Hi, Daniel,
I'll try my best to make this my last post on the subject since the GM still is barking at me.
Please look at the following paragraph from AN12522 S32K1xx ECC Error Handling app note:
3.3 Flash error emulation
The Flash Memory Module (FTFC) allows the users to emulate the setting of the FERSTAT[DFDIF] flag to check the associated
interrupt routine. Setting the FERCNFG[FDFD] bit creates the error emulation.
CAUTION
Consider that the real flow is first jump into the BusFault (if enabled) before going into the Flash error handler.
Cumulative programming of bits (back-to-back program operations without an intervening erase) within a flash memory location is not allowed.
So your example code 1st goes into Flash error handler and then right away jumps into the BusFault where the link register is 0xfffffff9 and there is no recovery from that.
This run contrary to the fellow as describe in the note. it is stated that it goes to BusFault and then to Error Handler.
how is it possible to recover from a bus fault with a link register of 0xfffffff9? whichever the order may be.
Thanks,
Koorosh Hajiani
解決済! 解決策の投稿を見る。
Hi @hajianik,
Yes, I can reproduce it.
This is the code that reads the PFlash at 0x70000
0x7A2 moves 0x70000 into R3
0x7A6 is the ECC BUS fault instruction, it loads R3 with data at 0x70000
0x7A8 loads R2 with the address of variable "read".
0x7AA stores R3 at the address in R2.
This code addd 0x4 to the stacked PC (0x7A6 + 4 = 0x7AA).
__asm("mov r1, r13");
__asm("ldr r2, =0x1C");
__asm("add r3, r1, r2");
__asm("ldr r0, [r3]");
__asm("ldr r2, =0x4");
__asm("add r0, r0, r2");
__asm("str r0, [r3]");
If the return address is 0x7AA and R2 != address of the variable but a number that does not point to a valid SRAM memory, it will crash.
In this case, we could modify the stack like this:
__asm("mov r1, r13");
__asm("ldr r2, =0x1C");
__asm("add r3, r1, r2");
__asm("ldr r0, [r3]");
__asm("ldr r2, =0x2"); // add 2 only
__asm("add r0, r0, r2");
__asm("str r0, [r3]");
Regards,
Daniel
The only way for fixing single bit ECC fault on EEPROM/Flash is the read of a particular sector, erase them and write it back that ECC values are correctly restored. The difference between EEPROM and Flash is only in sector size in that case and that you use slightly different commands.
Regards,
Rachel Gomez
Hi Koorosh Hajiani,
Let me check with the owner of the AN12522 application note.
Regarding the LR, this is a valid EXC_RETURN code.
https://www.nxp.com/docs/en/application-note/AN12201.pdf
In Case 2: Record the address which trigger the fault of AN12201, you can find an example that allows returning to the instruction that follows the fault instruction.
Regards,
Daniel
Hi @hajianik,
It has been confirmed that the AN is not exactly correct.
There can be a delay between FTFC ECC detection and the CORE fault detection depending on circumstances. The FTFC module can detect the error first and thus the FTFC interrupt can be called before the core exception.
The AN will have to be modified.
Regards,
Daniel
Hi Daniel,
Thank you for all your help on this.
Sorry for the delay, I was doing other tasks.
I tried the code from the app note you send me to return to the instruction following the fault.
yes It does save the return address (PC) on the stack WITH AN OFFSET OF 0X18 from the stack top
However from the screen shot , we van see that it is going to jump to where the link register is(0xffffffff9)
This will not recover the code.
I believe the ARM processor use the LINK and not the PC register for their return destination, You'd know better than I and correct me.
Sorry for dragging this too,too long time.
Thanks as always,
Koorosh Hajiani
Hi @hajianik,
Please refer to B1.5.8 Exception return behavior
in ARM®v7-M Architecture Reference Manual
Normally, the execution returns to the PC address stacked (after asm("bx lr"), which is the address of the fault instruction.
The code from the AN modifies the stacked PC address by adding 0x4 offset to it.
I just tested it in the test project attached.
The SP is decremented further by 0x4 when the ASM code modifies the stacked PC address.
So, in order to return to the next instruction after the fault instruction, use this code instead:
void BusFault_Handler(void)
{
__asm("mov r1, r13");
__asm("ldr r2, =0x1C");
__asm("add r3, r1, r2");
__asm("ldr r0, [r3]");
__asm("ldr r2, =0x4");
__asm("add r0, r0, r2");
__asm("str r0, [r3]");
}
BR, Daniel
Hi Daniel,
Thank you so much for bearing with me.
You've been a great help and I learned a lot in the exchange.
So You're correct , With your modification ,It jumps to the instruction right after the fault which caused the error. In my case it is:
while(1) {
asm("nop");
}
This is the infinite loop in the main. I placed a breakpoint right in there and it hits it however if I run the code at least in my project or run the code without any break points and pause the debugger it'll hit the Hard_Fault handler and if run again ,I wind up in here:
So, I'm trying to understand what's going on.
I couldn't build your project for some reason so I just created a project like yours.
Any thought on that?
BR,
Koorosh
Hi @hajianik,
Yes, I can reproduce it.
This is the code that reads the PFlash at 0x70000
0x7A2 moves 0x70000 into R3
0x7A6 is the ECC BUS fault instruction, it loads R3 with data at 0x70000
0x7A8 loads R2 with the address of variable "read".
0x7AA stores R3 at the address in R2.
This code addd 0x4 to the stacked PC (0x7A6 + 4 = 0x7AA).
__asm("mov r1, r13");
__asm("ldr r2, =0x1C");
__asm("add r3, r1, r2");
__asm("ldr r0, [r3]");
__asm("ldr r2, =0x4");
__asm("add r0, r0, r2");
__asm("str r0, [r3]");
If the return address is 0x7AA and R2 != address of the variable but a number that does not point to a valid SRAM memory, it will crash.
In this case, we could modify the stack like this:
__asm("mov r1, r13");
__asm("ldr r2, =0x1C");
__asm("add r3, r1, r2");
__asm("ldr r0, [r3]");
__asm("ldr r2, =0x2"); // add 2 only
__asm("add r0, r0, r2");
__asm("str r0, [r3]");
Regards,
Daniel
Hi Daniel,
Thanks for helping me and staying with me through all this. It works!!!
I learned lots of things.
I'll be out of your hair for a while until the next issue, let hope it would be a long time , for your sake.
BR,
Koorosh Hajiani