Skip to main content
Associate II
Apr 16, 2024 8:51 AM UTC
Question

Erase Flash Memory with FreeRTOS

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.

4 replies

Pavel A.
Apr 16, 2024 10:47 AM UTC

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

Associate II
Apr 16, 2024 11:05 AM UTC

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?

Pavel A.
Apr 16, 2024 12:05 PM UTC

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

David Littell
Senior II
Apr 17, 2024 12:43 AM UTC

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