2025-05-09 3:22 AM - last edited on 2025-05-14 1:10 AM by Andrew Neil
I'm using STM32 with HAL and LL drivers (H7 and G4 families, in particular, but I think this can be a general question) and I trying to avoid being forced in recursive faults when reading a flash location with broken ECC.
In my application it may happen to try to read a broken flash location.
In TrapHandler I'm able to intercept the error, report it to flash driver, clear error flags, and avoid any reset.
However, when returning from TrapHandler, I'll fall back on the same flash instruction which generated the fault, which will try to read the same location again, and so another fault will be generated in loop.
Is there a way to continue with the execution in a portable way after encountering this fault?
For a deeper understanding, this is one of the specific use case in which I would need the above behavior:
When in bootloader, before jumping to application, I calculate the CRC of application flash, compare it with the one stored to another flash location, and jump to application only if they match.
However it may happen that a flash location is broken (e.g. due to an error in the application, or to a sudden power loss while writing/erasing) generating an ECC error.
When encountering this error, I report the faults to the flash driver which results in a failed CRC calculation, and I would like to proceed with my algorithm.
However, even if I'm correctly detecting the error, clearing flags and returning from fault handler, the flash driver will try to read the broken location again with another fault immediatly generated, and I get stuck on the same memcpy instruction forever, without being able to proceed.
This is a simplified code for the flash read, with the Fls_SetEccError called inside TrapHandler to report errors to the flash driver. However, if an ECC error is encountered, I'll get stuck forever in the memcpy operation.
To break the flash ECC, I can perform two writes with different values on the same flash location and then try to read it.
bool_t Fls_bEccError = FALSE;
bool_t Fls_Read( uint32_t u32StartAddress, uint32_t u32Length, uint8_t *pu8Buffer ) {
memcpy( pu8Buffer, ( uint32_t * )u32StartAddress, u32Length );
return !(Fls_bNoEccError);
}
void Fls_SetEccError( void ) {
Fls_bEccError = TRUE;
}
Thank you in advance for your help
2025-05-18 8:06 AM
IIRC this depends on the phase of execution of the instruction. Some instructions are marked as "done" and IP forwards to the next instruction. In some other cases the IP stays on the offending instruction, so return from exception then will repeat the instruction. I never could remember the rules. Jumping to explicit address instead of simply resuming from the stacked IP avoids the guesswork.