HI,.
The function below writes 8 bytes to a flash location 0X0D2660 (0XAA,0X55,,,) which is 64bit aligned and then it erases it and writes 0x14,0x13,0x12......to the same location
then I read the location 0x0d2660 and I observe FTFC_FERSTAT remains 0 ( does not report an error)after the read to the location.
This function flsh_ecc (please see below)run out of RAM from 0x1FFE0000 which is at top of the ram also the debugger shows me the 1st phrase is written and then erased and rewritten with a new phrase correctly.
then I read the location:
myvar = *((unsigned long long*)0xd2660);
the only thing which is notable is :the code triggers a BUS FAULT exception and won't run anymore.
void flsh_ecc(void)
{
//while((FTFC->FSTAT & FTFC_FSTAT_CCIF_MASK) != FTFC_FSTAT_CCIF_MASK); /* Wait until any ongoing flash operation is completed */
#pragma asm
;ldr r1, =0x40020000 (0x1fff027c <run_ocs_volt_once..C.3A.5CFramework_ZERV_v00.2E02.5CApplications.5CZERV_Framework.5CAppl.5Cobj.5CINF_CDD.>)
movw r1,0x0000
movt r1,0x4002
movs r0, #128 ; 0x80
strb r0, [r1, #0]
L1:
ldrb r0, [r1, #0]
lsls r0, r0, #24
bpl L1
#pragma endasm
//FTFC->FSTAT = FTFC_FSTAT_ACCERR_MASK | FTFC_FSTAT_FPVIOL_MASK;
FTFC->FCCOB[3] = 0x07;//a_cmd; //Program Phrase command (0x07)
FTFC->FCCOB[2] = 0x0d;//v_AddrVec[0]; //Flash address [23:16]
FTFC->FCCOB[1] =0x26; //v_AddrVec[1]; //Flash address [15:08]
FTFC->FCCOB[0] =0x60; //v_AddrVec[2]; //Flash address [7:0]
// if (a_pageBuffer != NULL) {
FTFC->FCCOB[7] =0x55; //a_pageBuffer[0]; //data
FTFC->FCCOB[6] = 0xaa;//a_pageBuffer[1];
FTFC->FCCOB[5] = 0x55;//a_pageBuffer[2];
FTFC->FCCOB[4] =0xaa; //a_pageBuffer[3];
FTFC->FCCOB[11] =0x55; //a_pageBuffer[4];
FTFC->FCCOB[10] =0xaa; //a_pageBuffer[5];
FTFC->FCCOB[9] =0x55; //a_pageBuffer[6];
FTFC->FCCOB[8] =0xaa; //a_pageBuffer[7];
// }
FTFC->FSTAT = FTFC_FSTAT_CCIF_MASK; //launch command
//while((FTFC->FSTAT & FTFC_FSTAT_CCIF_MASK) != FTFC_FSTAT_CCIF_MASK);
#pragma asm
;ldr r1, =0x40020000 (0x1fff027c <run_ocs_volt_once..C.3A.5CFramework_ZERV_v00.2E02.5CApplications.5CZERV_Framework.5CAppl.5Cobj.5CINF_CDD.>)
movw r1,0x0000
movt r1,0x4002
movs r0, #128 ; 0x80
strb r0, [r1, #0]
L2:
ldrb r0, [r1, #0]
lsls r0, r0, #24
bpl L2
#pragma endasm
FTFC->FCCOB[3] = 0x09;//a_cmd; //Program Phrase command (0x07)
FTFC->FCCOB[2] = 0x0d;//v_AddrVec[0]; //Flash address [23:16]
FTFC->FCCOB[1] =0x26; //v_AddrVec[1]; //Flash address [15:08]
FTFC->FCCOB[0] =0x60; //v_AddrVec[2]; //Flash address [7:0]
FTFC->FSTAT = FTFC_FSTAT_CCIF_MASK; //launch command
#pragma asm
;ldr r1, =0x40020000 (0x1fff027c <run_ocs_volt_once..C.3A.5CFramework_ZERV_v00.2E02.5CApplications.5CZERV_Framework.5CAppl.5Cobj.5CINF_CDD.>)
movw r1,0x0000
movt r1,0x4002
movs r0, #128 ; 0x80
strb r0, [r1, #0]
L3:
ldrb r0, [r1, #0]
lsls r0, r0, #24
bpl L3
#pragma endasm
FTFC->FCCOB[3] = 0x07;//a_cmd; //Program Phrase command (0x07)
FTFC->FCCOB[2] = 0x0d;//v_AddrVec[0]; //Flash address [23:16]
FTFC->FCCOB[1] =0x26; //v_AddrVec[1]; //Flash address [15:08]
FTFC->FCCOB[0] =0x60; //v_AddrVec[2]; //Flash address [7:0]
// if (a_pageBuffer != NULL) {
FTFC->FCCOB[7] =0x10; //a_pageBuffer[0]; //data
FTFC->FCCOB[6] = 0x12;//a_pageBuffer[1];
FTFC->FCCOB[5] = 0x13;//a_pageBuffer[2];
FTFC->FCCOB[4] =0x14; //a_pageBuffer[3];
FTFC->FCCOB[11] =0x15; //a_pageBuffer[4];
FTFC->FCCOB[10] =0x16; //a_pageBuffer[5];
FTFC->FCCOB[9] =0x17; //a_pageBuffer[6];
FTFC->FCCOB[8] =0x18; //a_pageBuffer[7];
//INT_SYS_EnableIRQGlobal();
FTFC->FSTAT = FTFC_FSTAT_CCIF_MASK; //launch command
#pragma asm
;ldr r1, =0x40020000 (0x1fff027c <run_ocs_volt_once..C.3A.5CFramework_ZERV_v00.2E02.5CApplications.5CZERV_Framework.5CAppl.5Cobj.5CINF_CDD.>)
movw r1,0x0000
movt r1,0x4002
movs r0, #128 ; 0x80
strb r0, [r1, #0]
L4:
ldrb r0, [r1, #0]
lsls r0, r0, #24
bpl L4
#pragma endasm
}
Just wondering beside the register FTFC-FEPRT, is it some else to check.
BR,
Koorosh Hajiani
Solved! Go to Solution.
Hi @hajianik,
Please correct me if I'm wrong, but you erase the sector between the Program Phrase commands.
So, why do you expect an ECC error there?
You would get an ECC error if the phrase was not erased.
Regards,
Daniel
Hi @hajianik,
Please correct me if I'm wrong, but you erase the sector between the Program Phrase commands.
So, why do you expect an ECC error there?
You would get an ECC error if the phrase was not erased.
Regards,
Daniel
Hi Daniel,
just to be precise, I wrote in my last post:
however the code hits an exception not like the BUS FAULT exception and seems never to recover.
The version when I set the double_bit on in ftfc_ferstat, I found out the exception it triggers is a HARD_FAULT.
WHEN I WAS DOING WRITE_ERASE_WRITE SEQUENCE, IT NEVER SET THE FAULT AND YET TRIGGERS BUS_FAULT EXCEPTION
WHEN DOING WRITE-WRITE SEQUENCE , IT SETS THE FLAG AND TRIGGERS HARD_FAULT.
The question is why do these exceptions are triggered and recoverable?
Thanks,
Koorosh
Hi Koorosh,
I would need to have more information about the "not like the BUS FAULT exception".
Can you please try to debug it following the steps here:
https://community.nxp.com/t5/S32K-Knowledge-Base/Fault-handling-on-S32K14x/ta-p/1114447
BR, Daniel
Hi Daniel,
I'll go to the link you posted.
I think my English is the issue.
when I mentioned "NO BUS FAULT " exception I'm referring to the code which, wrote a phrase then erase the phrase and finally writes a different phrase and you corrected me by saying you shouldn't erase in between phrases writes. This code hits the bus_fault exception and set no error in the FERSTAT register.
When I did the phrase write and write a different phrase (same location of course) code, this code sets the fault DFDIF in the FERSTAT register and then triggers a hard_fault exception and not a bus_fault exception.
Now why would I trigger a bus _fault exception in the first instance of the code?
and why I trigger a hard_fault exception in the second instance of the code(when it sets the error flg)?
and is it possible to recover from ecc error on flash?
I hope this would more clear.
BR,
Koorosh
Hi Koorosh,
This is still very confusing to me.
I understand that you have two handler in the project (HardFault and BusFault) and the BusFault is enabled. Then, any bus fault should be handled by the BusFault handler only with the exception of faults detected within the BusFault handler or exception vector featching.
Anyway, what bus fault is it? Imprecise or Precise? Is BFAR valid? If so, what is the address there.
If not, please disable the write buffer as suggested in the document I was referering to in my last response.
Best regards,
Daniel
Hi Daniel,
Sorry for dragging this too long and appreciate your patience.
Lets talk about the HARD_FAULT handler and just forget about the BUS_FAULT handler( I'll start a new thread about that)
My current code, injects an ECC flash error .It'd sets the DFDIF bit in the FERSTAT register and after a read to the location where the error was injected, would triggers a hard_fault exception .
My question is :
Is it typical that an ECC FLASH error to trigger HARD_FAULT exception, right after a read to the location responsible for the error ?
Is it possible to recover from a hard_fault exception or not?
I probably need to look at your link more carefully for the answer to 2nd question
BR, Koorosh
?
I need to look at the link you sent more carefully
Hi @hajianik,
I just tested it on S32K144 EVB.
It is a precise bus fault.
It feaches the BusFault_Hnadler provided it is enabled (in SHCSR).
Regarding a possible recovery solution, it would need to be reporgrammed or the application would need to overwrite the context on the stack.
There is an example in AN12522 on page 8.
Regards,
Daniel
Hi,
I took an S32K example project and modified the code to demonstrate the points made in my last post.
Please see the attachment.
The name of the project is misleading (ADC_s32k144) as this one has nothing todo with the ADC.
This code set the BUS_FAULT enabled , it sets the DFDIE (Interrupt enable bit) In FERCNFG register.
I run this on s32k148 eval board ,It will set DFDIF in FERSTAT register and When the location(where the fault was injected) is read , it keeps triggering HARD_FAULT exception handler and since LINK REGISTER is -7(0xfffffff9) it is stuck in the handler.
This is contrary to the statement in AN12522:
3.2 ECC for non-correctable errors
The S32K14x and S32K11x devices handle the non-correctable error in the same way. The Flash Memory Module ( FTFC ) can
generate an interrupt (if enabled) to notify a multiple -bit error event which can be enabled setting the FERCNFG[DFDIE] bit to 1.
• S32K1xx Error Handling: When the fault occurs, the FERSTAT[DFDIF] flag is set notifying that a double bit fault was
detected. The flash controller will generate a AHB error response resulting in a bus fault (if enabled). After serving the bus
fault, jump to the Flash Memory Module ( FTFC ) interrupt handler (if enabled). The software can handle the error depending
on whether the error occurred in Code Space or Data Space.
• If an uncorrectable error fault occurs during execution of a machine exception, a safe state shall be entered.
• The bus fault is disabled by default. Therefore, it will be getting escalated to hard fault.
So either I'm doing something wrong and( please correct me) or the AN12522 is wrong and that needs to be corrected too.
Thanks,
Koorosh
Hi @hajianik,
I'm sorry, I meant AN12201, p8
https://www.nxp.com/docs/en/application-note/AN12201.pdf
I have just brieflly gone through the example you posted.
You enable the FTFC fault interrupt in the FTFC controller and in NVIC but you did not implement the handler in the project.
void FTFC_Fault_IRQHandler(void){}
You have FTFE handler though.
void FTFE_Fault_IRQHandler(void){}
This would explain the HardFault there.
BR, Daniel
Hi Daniel,
sorry for a late response. I was on vacation.
you are correct, I had a typo, however when I changed it to void FTFC_Fault_IRQHandler(void) I still hit a hard_fault handler. This happens when I read the memory at fault.
BR,
Koorosh Hajiani
Hi @hajianik,
I don't have the board today.
Can you please debug this fault again:
https://community.nxp.com/t5/S32K-Knowledge-Base/Fault-handling-on-S32K14x/ta-p/1114447
What is the content of the CFSR / BFAR registers?
Can you find the instruction that triggers the fault?
Thanks,
BR, Daniel
Hi,
Below is a snapshot of the registers.
also the instruction that'll trigger Hardfault_handler
Thanks,
Koorosh
That's when I try to read the address at fault(0xD2680 that's what BFAR is showing.
Hi @hajianik,
There is an obvious error, the address that you are writing to is no implemented on S32K144.
But even with this being fixed, it does not workm and I can't find out why.
Anyway, the test project attached works as expected.
Regadrs,
Daniel
Hi,
So my target is S32K148. the address 0XD2680 is implemented on this version.
I can not find any error in my code as you looked at it AND COME TO THE SAME CONCLUSIN.
Will I be correct in response to the customer(GM) inquires to say:
NXP STATEMENT (REGARDING FLASH ECC ERROR)IN THEIR APPLICATION NOTE AND LITRITURE IS AT BEST MISLEADING.. IN FACT THIS ERROR TRIGGERS A HARD_FAULT EXCEPTION AND THERE IS NO RECOVERY FROM THAT.
Please correct me if I'm wrong.
Thanks
Hi @hajianik,
You posted an example ported on S32K144.
I tested that example on an S32K144 EVB.
The example that I posted works on that EVB, it goes to BusFault_Handler as expected.
Can you test it?
Thanks,
BR, Daniel
Hi,
Your example works fine on my s32k148 eval board. It triggers the FTFC_Fault_IRQHandler AND THEN TRIGGERS A BUS_FAULT handler.
I almost made my code identical to yours in spite of the fact I couldn't find any differences in the first place.
It is now identical to yours except the data for the Program Phrase command . same address like yours 0x00070000 and yet when I run my code it still hit the HARD_FAULT_HANDLER.
THIS IS A REAL MYSTRY TO ME EVEN the "err" in err=flsh_ecc(); is the same as yours which is 4.
Don't know what the deal is. it is exactly except for the program phrase data.
BR,
KOOROSH
Hi Daniel,
Sorry for posting again. I noticed in my code I did not enable the BUS_FAULT exception, used the wrong mask 0x2000 which ought've been 0x20000.when I corrected that, I keep hitting the bus fault and no FTFC_Fault_IRQHandler is triggered. it was hitting the HARD_FAULT handler since all the unable are escalated to the hard_fault.
Thanks,
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 Daniel,
Thanks so much for helping me on this.
I get identical reporting on the registers that you posted in your last reply.
However when I do the following I get HARD_ FAULT_ exception rather than a BUS_FAULT_ exception.
At this point I'm confused why the hard_fault exception triggers rather than the bus_fault when it is enabled?
I understand that all disabled exception will elevate to hard_fault which is enabled by default.
I read the application note you sent , there is no page 8 on that, it has only 5 pages. I believe you sent me a link on how to recover from an exception in an earlier post.
BR,
Koorosh