cancel
Showing results for 
Search instead for 
Did you mean: 

MCU STM32L072 WRITE FIRMWARE FLASH - BANK2

Wave
Associate II

Hello everyone, 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]);
    }
}

 

3 REPLIES 3
Wave
Associate II

Hello everyone, 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]);
    }
}

 

Andrew Neil
Evangelist III
Andrew Neil
Evangelist III