Unable to erase sector of internal flash using HAL
Problem:
HAL_FLASHEx_Erase returns error 0x20000, and HAL_FLASH_Program does return HAL_OK but does not actually write any data to the flash.
Goal: Erase and install new firmware on flash on its own inside the bootloader.
I am developing a bootloader for the STM32H533RET6. I have TrustZone enabled, and configured the secure and non-secure regions. I am trying to erase and write to the non-secure part of the flash, from the bootloader which is secure (and separate from the actual application). I have disabled any write protection that I am aware of inside the option bytes. I also use the Memory Management Tool inside CubeMX to configure the secure and non-secure regions. For the non-secure region of the flash I have set "Access Permissions" to "RW by any privilege level". I do have a Flash watermark set on bank 1 but this does not cover any of the non-secure flash regions. No watermark is set on bank 2.
Below is the code I use to erase and write to a sector on the flash:
uint32_t Erase_And_Write_Data(uint32_t start_address, uint32_t* data, uint32_t words_size)
{
FLASH_EraseInitTypeDef erase_init;
uint32_t sector_error;
HAL_FLASH_Unlock();
// Determine sectors and bank based on start_address
uint32_t first_sector = (start_address - 0x08000000) / INTERNAL_FLASH_SECTOR_SIZE;
uint32_t last_sector = ((start_address - 0x08000000) + (words_size*4)) / INTERNAL_FLASH_SECTOR_SIZE;
uint32_t sector_count = last_sector - first_sector + 1;
uint32_t bank = start_address < 0x08040000? FLASH_BANK_1 : FLASH_BANK_2;
// Erase sector
erase_init.TypeErase = FLASH_TYPEERASE_SECTORS;
erase_init.Sector = first_sector;
erase_init.NbSectors = sector_count;
erase_init.Banks = bank;
if(HAL_FLASHEx_Erase(&erase_init, §or_error) != HAL_OK) {
HAL_FLASH_Lock();
return HAL_FLASH_GetError();
}
// Write to sector
uint32_t written = 0;
while(written < words_size) {
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, start_address + (written * 4), (uint32_t)&data[written]) != HAL_OK) {
HAL_FLASH_Lock();
return HAL_FLASH_GetError();
}
written += 4;
}
HAL_FLASH_Lock();
return 0;
}
The STM32H533 flash consists of 2 banks each being 256Kbytes in size. This then is divided into sectors of 8KB making up 64 total sectors, where 0-31 is bank1 and 32-63 is bank2. I have validated that putting in a start_address results in the correct sectors, sector count and bank. I have also just tried hardcoding a sector and a bank, but this all results in the same 0x20000 error.
To test the HAL_FLASH_Program I disabled the HAL_FLASHEx_Erase. I then called the HAL_FLASH_Program on an address of a sector that I knew was empty, as I erased it using the STM32CubeProgrammer. After executing the HAL_FLASH_Program, it did infact return a HAL_OK, but after checking the data on the address I wrote to, nothing was written and everything was still 0xFFFFFFFF.
Any help or advice is appreciated.
