cancel
Showing results for 
Search instead for 
Did you mean: 

STM32: avoid deadloops when intercepting (expected) ECC errors while reading flash memory

MrJorge
Associate

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

 

 

 

 

 

3 REPLIES 3

Not sure there's an easy answer. You can check the stack frame to recover the context and advance the instruction pointer based on the opcode. Or recognize it is in this particular loop.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
TDK
Guru

Consider resetting instead and using a magic value in memory which indicates an error was encountered during a read to flash location X.

If you feel a post has answered your question, please click "Accept as Solution".

Not sure there's an SEH (Structured Exception Handler) in the try/catch sense.

The stated issue is that the return simply retries the operation, hoping the handler has fixed the issue, say pulling in virtual memory, or it digs into the context to fix or emulate the opcode that faulted, and advance. Making a general handler would be quite a task, making something relatively selective/specific, perhaps not so.

In that loop you could have it jump to a different location upon return, say breaking from the loop, by modifying the PC in the stacked context.

You have to return, rather than have the handler jump directly, as the machine has to unstack the context and MCU/NVIC internal states.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..