2022-02-04 06:09 AM
I have an application running on an STM32F4 which uses the STM32 HAL framework + FreeRTOS. I occasionally need to store some settings in flash during runtime and have written the following function to erase the data at my target address of 0x08060000UL (I believe this is SECTOR_6 of this particular MCU).
HAL_StatusTypeDef Flash::erase(uint32_t address)
{
HAL_StatusTypeDef status;
HAL_FLASH_Unlock(); // unlock the flash API
__disable_irq(); // disable all interrupts
vTaskSuspendAll(); // suspend all FreeRTOS tasks
FLASH_EraseInitTypeDef eraseConfig = {0};
uint32_t sectorError;
uint32_t flashError = 0;
eraseConfig.TypeErase = FLASH_TYPEERASE_SECTORS;
eraseConfig.Sector = this->getSector(address);
eraseConfig.NbSectors = 1;
eraseConfig.VoltageRange = FLASH_VOLTAGE_RANGE_3;
status = HAL_FLASHEx_Erase(&eraseConfig, §orError); // <---- FAILS HERE
if (status != HAL_OK)
{
flashError = HAL_FLASH_GetError();
}
status = HAL_FLASH_Lock();
xTaskResumeAll(); // resume all FreeRTOS tasks
__enable_irq(); // re-enable interrupts
return status;
}
The flashError variable ends up getting set to 6, which means the following two errors occurred during the call to HAL_FLASHEx_Erase()
#define HAL_FLASH_ERROR_PGS 0x00000002U /*!< Programming Sequence error */
#define HAL_FLASH_ERROR_PGP 0x00000004U /*!< Programming Parallelism error */
I can't be 100% sure, but I think this code worked fine prior to implementing FreeRTOS. Regardless, what kind of behavior might cause such an error? I thought disabling all ISRs as well as suspending all tasks (even though there is only one running during this operation) would cover me, but no combination of these attempts alleviates the error 🤷�?♂�?.
Solved! Go to Solution.
2022-02-04 02:15 PM
OK there was an error in my above code for clearing these flags prior to using the API. I was using the wrong flag defines
These fixed my problem:
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGAERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGPERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGSERR);
2022-02-04 06:30 AM
Checks flags in FLASH_SR prior to calling HAL_FLASHEx_Erase. Sometimes they are already set. If they are, clear them before calling.
Verify Sector is a valid value.
2022-02-04 07:04 AM
I have this block of code right before the HAL_FLASHEx_Erase and still have no success. Are there any other macro functions I should use to clear the flags?
HAL_FLASH_Unlock();
// clear all flash error flags prior to using the API
__HAL_FLASH_CLEAR_FLAG(HAL_FLASH_ERROR_NONE);
__HAL_FLASH_CLEAR_FLAG(HAL_FLASH_ERROR_RD);
__HAL_FLASH_CLEAR_FLAG(HAL_FLASH_ERROR_PGS);
__HAL_FLASH_CLEAR_FLAG(HAL_FLASH_ERROR_PGP);
__HAL_FLASH_CLEAR_FLAG(HAL_FLASH_ERROR_PGA);
__HAL_FLASH_CLEAR_FLAG(HAL_FLASH_ERROR_WRP);
__HAL_FLASH_CLEAR_FLAG(HAL_FLASH_ERROR_OPERATION);
2022-02-04 02:15 PM
OK there was an error in my above code for clearing these flags prior to using the API. I was using the wrong flag defines
These fixed my problem:
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGAERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGPERR);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGSERR);