# MBED + STM32F446RE triggers HARD FAULT when trying to write to flash

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

• 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. Nov 9, 2020 at 0:48
• So do you mean that this code should be loaded in RAM? Nov 9, 2020 at 0:58
• 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. Nov 9, 2020 at 1:31
• 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? Nov 9, 2020 at 1:37
• Actually an HARD FAULT is triggered, the controller doesn't hang Nov 9, 2020 at 10:22

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