2024-04-16 01:51 AM
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.
2024-04-16 03:47 AM
After you called vTaskSuspendAll (line 6) you call osDelay (lines 12, 18...) Are you sure how this is going to work?
2024-04-16 04:05 AM
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?
2024-04-16 05:05 AM
@Vince18092001 Do you have code running in RAM, or the interrupt table in RAM?
2024-04-16 05:43 PM
Consider __disable_irq() and a subsequent call to osDelay() - osDelay() relies on a timer interrupt, yes?