I am writing a new firmware received by UART. I use DMA with Interrupt and my new firmware is in .HEX format, I receive it in blocks of 1500 in 1500 bytes, and I have a case that performs the processing of extracting the addresses, crc, cheksum, and the real data and after that calls the businessRules_update_firmware function. I want to write the firmware using the application code itself. However, I have a problem writing after 0x08018000
. My microcontroller is category 5, with 192KB and dual-bank. And my application code is running on bank1 and I want to write the new firmware on bank2. I always record correctly from 0x08018000
to 0x080180F0
, but I can never record after 0x08018100
, what could this be?
The businessRules_updateFirmware
function is called within a loop after the data from the .HEX file has been processed.
uint32_t flashAddress = 0x08018000;
void businessRules_updateFirmware(void)
{
uint8_t buffer[FIRMWARE_PACKAGE_SIZE];
uint32_t pageError;
if (protocol_feedFirmwareBuffer(buffer))
{
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_BSY);
FLASH_EraseInitTypeDef eraseInitStruct;
eraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
eraseInitStruct.PageAddress = flashAddress;
eraseInitStruct.NbPages = 1;
if (HAL_FLASHEx_Erase(&eraseInitStruct, &pageError) != HAL_OK)
{
HAL_FLASH_Lock();
HAL_FLASH_OB_Lock();
return;
}
uint8_t binaryData[FIRMWARE_PACKAGE_SIZE / 2];
hexStringToBytes((const char*)buffer, binaryData, FIRMWARE_PACKAGE_SIZE);
for (uint32_t i = 0; i < FIRMWARE_PACKAGE_SIZE / 2; i += 4)
{
uint32_t data = *(uint32_t*)&binaryData[i];
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, flashAddress , data) != HAL_OK)
{
HAL_FLASH_Lock();
HAL_FLASH_OB_Lock();
return;
}
flashAddress += 4;
}
HAL_FLASH_Lock();
HAL_FLASH_OB_Lock();
}
}
uint8_t hexCharToValue(char hexChar)
{
if (isdigit(hexChar))
return hexChar - '0';
else
return tolower(hexChar) - 'a' + 10;
}
void hexStringToBytes(const char *hexString, uint8_t *byteArray, size_t byteArraySize)
{
for (size_t i = 0; i < byteArraySize / 2; ++i)
{
if (2 * i + 1 >= strlen(hexString))
{
byteArray[i] = 0x00;
break;
}
byteArray[i] = (hexCharToValue(hexString[2 * i]) << 4) | hexCharToValue(hexString[2 * i + 1]);
}
}
I tried some variations of this function, but without success so far.
void businessRules_updateFirmware(void)
{
uint32_t pageAddress;
uint32_t pageError;
uint8_t buffer[FIRMWARE_PACKAGE_SIZE];
bool dataIsReady = false;
dataIsReady = protocol_feedFirmwareBuffer(buffer);
if (dataIsReady)
{
uint8_t binaryData[FIRMWARE_PACKAGE_SIZE / 2];
hexStringToBytes((char *)buffer, binaryData, FIRMWARE_PACKAGE_SIZE / 2);
pageAddress = protocol_getAddressToFirmware();
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
FLASH_EraseInitTypeDef eraseInitStruct;
eraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
eraseInitStruct.PageAddress = pageAddress;
eraseInitStruct.NbPages = 1;
if(HAL_FLASHEx_Erase(&eraseInitStruct, &pageError) != HAL_OK){
HAL_FLASH_Lock();
HAL_FLASH_OB_Lock();
return;
}
for(uint32_t i = 0; i < FIRMWARE_PACKAGE_SIZE / 2; i += 4){
uint32_t data = (binaryData[i] << 0) | (binaryData[i + 1] << 8) | (binaryData[i + 2] << 16) | (binaryData[i + 3] << 24);
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, pageAddress + i , data) != HAL_OK){
HAL_FLASH_Lock();
HAL_FLASH_OB_Lock();
return;
}
}
pageAddress += FIRMWARE_PACKAGE_SIZE / 2;
protocol_setAddressToFirmware(pageAddress);
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
}
}
uint8_t hexCharToValue(char hexChar) {
if (isdigit(hexChar))
return hexChar - '0';
else
return tolower(hexChar) - 'a' + 10;
}
void hexStringToBytes(const char *hexString, uint8_t *byteArray, size_t byteArraySize) {
for (size_t i = 0; i < byteArraySize; ++i) {
byteArray[i] = (hexCharToValue(hexString[2 * i]) << 4) | hexCharToValue(hexString[2 * i + 1]);
}
}
I solved the problem, as I was using DMA, I was having a problem with my circular buffer that was filling up and was unable to process the rest of the data received. Then I adjusted the pointer and counter and also the HAL_UARTEx_RxEventCallback function