Skip to main content
Graduate
April 16, 2024
Question

Erase Flash Memory with FreeRTOS

  • April 16, 2024
  • 3 replies
  • 1739 views

Hi everyone,
I've been having a problem for several days now. The erasing of Flash memory by sector (or Bank). I'm working on an STM32F439VIT6 and when I use my function in initialisation, before using queues or other things, my function works as I want it to, but when I'm in routine, in my while(1) task for example, it returns errors: HAL_FLASH_ERROR_PGP and HAL_FLASH_ERROR_PGS. Here is an extract from my function:

 

void Erase_Memory(uint32_t nb_sectors, uint32_t sector, uint32_t* pointer_to_zero) {
 // Disable all interrupts to protect flash operation
 __disable_irq();

 // Suspend task switching to ensure flash access is not interrupted
 vTaskSuspendAll();

 vTaskPrioritySet(plc_g3_handle, 9);

 // Check and wait until no flash memory operation is ongoing
 while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET) {
 osDelay(1); // Add delay to allow other hardware operations to complete
 }

 // Unlock the flash for erasing
 HAL_StatusTypeDef flashStatus = HAL_FLASH_Unlock();
 while (flashStatus != HAL_OK) {
 osDelay(1); // Delay then retry
 flashStatus = HAL_FLASH_Unlock();
 }

 // Setup flash erase parameters
 FLASH_EraseInitTypeDef EraseInitStruct = {
 .TypeErase = FLASH_TYPEERASE_SECTORS,
 .Sector = sector,
 .NbSectors = nb_sectors,
 .VoltageRange = FLASH_VOLTAGE_RANGE_3
 };

 uint32_t SectorError = 0;

 // Attempt to erase the flash and check the result
 if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
 uint32_t errorCode = HAL_FLASH_GetError();
 // Handle specific flash errors or log them
 // Consider retry logic or error handling notification
 }

 // Lock the flash after operation
 HAL_FLASH_Lock();

 // Ensure no flash operation is ongoing
 while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET) {
 osDelay(1);
 }

 // Resume task switching
 xTaskResumeAll();

 // Re-enable interrupts
 __enable_irq();

 // Clear the provided memory pointer
 *pointer_to_zero = 0;

 vTaskPrioritySet(plc_g3_handle, 7);
}

I've tried a lot of variants, originally my function was much simpler and much less secure (I checked almost nothing) and after switching to FreeRTOS I "robustified" it to give this.

However, there is still an error that I don't understand.
At first I thought it was the multitasking environment, so I added the task suspension, then I thought about the fact that interrupts could interfere. That's not the case either.


I should also point out that this is the only function I use (of my functions) that accesses memory.
And the error occurs exactly on the HAL_FlashEx_Erase and it is in the HAL_WaitForLastOperation that I have the return of these 2 flags.
I apologise in advance if there is a lack of information or if I could have found out more before coming but now I'm really stuck and I don't really see how to move forward.

Thank you in advance to the ST community.

 

Vincent T.

    This topic has been closed for replies.

    3 replies

    Super User
    April 16, 2024

    After you called vTaskSuspendAll (line 6) you call osDelay (lines 12, 18...)  Are you sure how this is going to work?

    Graduate
    April 16, 2024

    It's simply a time limit to restart the operation if the flash is occupied, so I don't see any problem with that, but perhaps I'm taking the wrong approach?

    Super User
    April 16, 2024

    @Vince18092001 Do you have code running in RAM, or the interrupt table in RAM?

    Graduate II
    April 17, 2024

    Consider __disable_irq() and a subsequent call to osDelay() - osDelay() relies on a timer interrupt, yes?