cancel
Showing results for 
Search instead for 
Did you mean: 

Erase Flash Memory with FreeRTOS

Vince18092001
Associate III

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.

4 REPLIES 4
Pavel A.
Evangelist III

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

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.
Evangelist III

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

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