Flash ECC error

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 
3,872件の閲覧回数
hajianik
Senior Contributor I

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

タグ(1)
0 件の賞賛
返信
1 解決策
3,715件の閲覧回数
danielmartynek
NXP TechSupport
NXP TechSupport

Hi @hajianik,

Yes, I can reproduce it.

This is the code that reads the PFlash at 0x70000

danielmartynek_0-1651503497877.png

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

 

 

 

元の投稿で解決策を見る

タグ(1)
8 返答(返信)
2,875件の閲覧回数
RachelGomez123
Contributor I

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

0 件の賞賛
返信
3,855件の閲覧回数
danielmartynek
NXP TechSupport
NXP TechSupport

Hi Koorosh Hajiani,

Let me check with the owner of the AN12522 application note.

Regarding the LR, this is a valid EXC_RETURN code.

danielmartynek_0-1649932201409.png

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

 

 

0 件の賞賛
返信
3,764件の閲覧回数
danielmartynek
NXP TechSupport
NXP TechSupport

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

0 件の賞賛
返信
3,791件の閲覧回数
hajianik
Senior Contributor I

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.

 

hajianik_0-1650577702952.png

Sorry for dragging this too,too long time.

Thanks as always,

Koorosh Hajiani

タグ(1)
0 件の賞賛
返信
3,750件の閲覧回数
danielmartynek
NXP TechSupport
NXP TechSupport

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

 

3,741件の閲覧回数
hajianik
Senior Contributor I

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:

 

hajianik_0-1651176949818.png

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

タグ(1)
0 件の賞賛
返信
3,716件の閲覧回数
danielmartynek
NXP TechSupport
NXP TechSupport

Hi @hajianik,

Yes, I can reproduce it.

This is the code that reads the PFlash at 0x70000

danielmartynek_0-1651503497877.png

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

 

 

 

タグ(1)
3,710件の閲覧回数
hajianik
Senior Contributor I

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

タグ(1)
0 件の賞賛
返信