1
\$\begingroup\$

I am trying to write to flash memory from the firmware itself.

It looks like the Erase process hangs for 2 seconds or so but works, but the writing process seems to totally freeze the MCU cause a HARD FAULT. Below is the code I am using. Any idea why?

FLASH_EraseInitTypeDef flashErase;
flashErase.TypeErase = TYPEERASE_SECTORS;
flashErase.VoltageRange = FLASH_VOLTAGE_RANGE_3;
flashErase.Sector = FLASH_SECTOR_7;
flashErase.NbSectors = 1;

HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | 
              FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);

uint32_t sectorError;
if (HAL_FLASHEx_Erase(&flashErase, &sectorError) != HAL_OK) {
  error = true;
}
if (HAL_FLASH_Program(TYPEPROGRAM_WORD, 0x08060000, 123) != HAL_OK) {
  error = true;
}
HAL_FLASH_Lock();

EDIT: The microcontroller actually triggers a HARD FAULT

I tried locating some user data to 0x08020000 (sector 5) using linker script and initializing it as follows:

__attribute__((__section__(".user_data"))) char userConfig[4] = {1, 2, 3, 4};

I can check that it is properly located and initialized (&userConfig[0] is 0x08020000 and the values are 1 2 3 4), and properly erased (back to 255 255 255 255 if I just do an erase of sector 5), but trying to write to 0x08020000 always makes an HARD FAULT happen.

EDIT2: I tried to execute the code in the RAM (using direct registers access instead of calling HAL methods) and it doesn't make any difference

\$\endgroup\$
5
  • \$\begingroup\$ I think you're running up against: Reference Manual, page 69, section 3.5 -> "Any attempt to read the Flash memory on STM32F4xx while it is being written or erased, causes the bus to stall" ... "code or data fetches cannot be performed while a write/erase operation is ongoing". It's likely that for the erase to work it just happened that the relevant bit of code was in the instruction cache and a read from flash wasn't necessary, but that didn't work out for the write. \$\endgroup\$
    – brhans
    Nov 9, 2020 at 0:48
  • \$\begingroup\$ So do you mean that this code should be loaded in RAM? \$\endgroup\$
    – Gregwar
    Nov 9, 2020 at 0:58
  • \$\begingroup\$ Yes. It's pretty typical that for writing flash you need to run at least some code out of RAM. Make a function that's as small as possible that does the write and then polls the status of the flash until the write is done. This also means that -- unless you put a lot of stuff into RAM -- your processor will appear to go dead while the write is happening. So you need to design your download process to accommodate this. \$\endgroup\$
    – TimWescott
    Nov 9, 2020 at 1:31
  • \$\begingroup\$ In that case how in the world the methods "HAL_FLASHEx_Erase" or "HAL_FLASH_Program" that themselves call other methods and doesn't seem to be in the RAM could be of any use? \$\endgroup\$
    – Gregwar
    Nov 9, 2020 at 1:37
  • \$\begingroup\$ Actually an HARD FAULT is triggered, the controller doesn't hang \$\endgroup\$
    – Gregwar
    Nov 9, 2020 at 10:22

1 Answer 1

1
\$\begingroup\$

I will answer to my own question. I am using MBED as environment and I missed this page that basically explains two of my problems.

The MPU is pre-configured by the framework to disable both writing in ROM and executing of RAM. You need to declare explicitly if you want it to be possible using ScopedRomWriteLock or ScopedRamExecutionLock

https://os.mbed.com/docs/mbed-os/v6.4/apis/mpu-management.html

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.