Kinetis K10FX512 read flash hard fault

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Kinetis K10FX512 read flash hard fault

Jump to solution
1,864 Views
darioantolovic
Contributor I

Hello friends,

 

we are working with MK10FX512VLQ12 on our custom developed board. We completed almost the firmware for the intended application, and had no problem until now.

 

The problem started while trying to implement the bootloader functionality. The bootloader FW writes some parameters in flash memory, that are used by both applications (bootloader and user). After the write is done, we check if the parameters are really in flash on the desired locations, but while accessing the flash location, the MCU goes to hard fault.

 

I will try to clarify all the steps that we make before the hard fault.

 

  • After reset we check a flag in memory (0x9000), that indicates if the bootloader application should be started, or should we jump to the user application. The read function looks like:

 

#define BL_RUN_FLAG_ADDRESS         0x9000   bootloader_run_flag = *((uint32_t*) BL_RUN_FLAG_ADDRESS);

 

The read function returns the correct value, and is set to enter the bootloader application if no user application is present.

  • In the bootloader application (after the PE_init) we first check if there are 5 parameters writen i memory (0x9004, 0x9008, 0x900C, 0x9010 and 0x9014), if not (and they are not at first start of the bootloader application) we write the parameters to this locations. To write this parameters we use the IntFLASH PE component from Configuration Data: Using the Internal FLASH instead of an external EEPROM | MCU on Eclipse. Below is the code to check if the data is written, and to write the data.

 

if(BL_CheckMsgIDinFlash()){      BL_WriteMsgIDtoFlash();       Cpu_SystemReset(); }  bool BL_CheckMsgIDinFlash(void) {   uint32_t rtrn = 0;   uint32_t i = 0;    for (i = 0; i < MSGID_NR; i++) {        if (Flash_MSGID[i] != *((uint32_t*) (BL_RUN_FLAG_ADDRESS + ((i + 1) * 4)))) {             rtrn++;        }   }   return (bool) rtrn; }  bool BL_WriteMsgIDtoFlash(void) {   uint32_t i = 0;   uint32_t err = 0;   uint32_t tmp32 = 0;   uint32_t addr = 0;    for (i = 0; i < MSGID_NR; i++) {        tmp32 = Flash_MSGID[i];        addr = BL_RUN_FLAG_ADDRESS + (i + 1) * 4;        err = IFsh1_SetBlockFlash((IFsh1_TDataAddress) &tmp32, addr, 4); // write data to specified location in flash    } return err; }

 

When I run this part of code in debugger, the memory locations are not written correctly, at least the debugger shows it incorrectly. While single stepping trough BL_WriteMsgIDtoFlash() i have this in my memory locations:

 

Step0x90000x90040x90080x900C0x90100x9014
1
0xFFFFFFFF
0x000004310xFFFFFFFF0xFFFFFFFF0xFFFFFFFF0xFFFFFFFF
20xFFFFFFFF0x000004310x000004320xFFFFFFFF0xFFFFFFFF0xFFFFFFFF
30xFFFFFFFF0xFFFFFFFF0xFFFFFFFF0xFFFFFFFF0xFFFFFFFF0xFFFFFFFF
40xFFFFFFFF0xFFFFFFFF0xFFFFFFFF0xFFFFFFFF0x000004340xFFFFFFFF
50xFFFFFFFF0xFFFFFFFF0xFFFFFFFF0xFFFFFFFF0x000004340x00000435

 

On the third step the first two locations are erased, and at the end the two last locations are correct.

 

  • After that I reset the CPU and do again the whole procedure. First I check the Bootloader flag on location 0x9000, and at this point the CPU goes in the hard fault handler.

 

bootloader_run_flag = *((uint32_t*) BL_RUN_FLAG_ADDRESS);

 

 

I read the flowing values in the system registers:

 

RegisterValueLocation
stacked_r00xffffffff0x1fff111c
stacked_r10x000000000x1fff1120
stacked_r20x000000000x1fff1124
stacked_r30x000090000x1fff1128
stacked_r120x000000000x1fff112c
stacked_lr0x0000371d0x1fff1130
stacked_pc0x000036fe0x1fff1134
stacked_psr0x210000000x1fff1138
_CFSR0x000082000x1fff113c
_HFSR0x400000000x1fff1140
_DFSR0x000000090x1fff1144
_AFSR0x000000000x1fff1148
_BFAR0x000090000x1fff1150
_MMAR0x000090000x1fff114c

 

The PC shows the last location where it broke, and this is the part of the code:

 

222         bootloader_run_flag = *((uint32_t*) BL_RUN_FLAG_ADDRESS); 000036fa:   mov r3,#0x9000 000036fe:   ldr r3,[r3,#0] 00003700:   str r3,[r7,#4]

 

The same problem happens when I try immediately read the memory locations after the write command, without resetting the CPU.

 

I attached also the InitFLASH source files for reference.

 

I'm very confused now, because we implemented this bootloader firmware on two other devices (MK10DX128 and MK40DN512) and it works without any problems.

 

Does anyone have a suggestion what could be the problem here?

 

Best regards,

Dario

Original Attachment has been moved to: Generated_Code.rar

Labels (1)
0 Kudos
1 Solution
986 Views
mjbcswitzerland
Specialist V

Dario

You are not respecting the phrase programming requirements fo the Flash in the K10FX512.

You are only allowed to write 8 byte blocks at at time (phrase) and any attempt to write to one of these phrases (8 byte blocks) that is not erased will corrupt the Flash and cause it to return a hard fault afterwards (it then requires an erase to recover).

You need to change your code to leave a long word space after the 5th long word that you have written:

eg:

0x10000004, 0x10000008, 0x1000000C, 0x10000010 and 0x10000014 + 0xffffffff

and then add futher data after that and it will work (or some other equivalent method).

The problem is that the Flash is being written as follows (assuming X is divisible by 4):

Phase Address X = 0x10000004, 0x10000008

Phase X + 1 = 0x1000000C, 0x10000010

Phase X + 2 = 0x10000014 + 0xffffffff

If you tried to write at long word offset 5 it was doing

Phase X + 2 = 0x10000014 + "changed value"

It is not allowed to write to a phrase twice (without a sector erase inbetween) and so your problem arisies.

Regards

Mark

Kinetis: http://www.utasker.com/kinetis.html

K60: http://www.utasker.com/kinetis/TWR-K60N512.html / http://www.utasker.com/kinetis/TWR-K60D100M.html / http://www.utasker.com/kinetis/TWR-K60F120M.html

For the complete "out-of-the-box" Kinetis experience and faster time to market

:smileyinfo: Out-of-the-box support for 46 Kinetis boards and 10 IDEs (460 combinations from a single code source with no porting required)

View solution in original post

3 Replies
986 Views
darioantolovic
Contributor I

Today we did some more debugging, and came to a weird behavior of the MCU while writing data to flash.

Attached you can find a CodeWarrior (10.6) project with an example application of the behavior.

To clarify the behavior, we try to write 5 data bytes to flash memory on locations 0x10000004, 0x10000008, 0x1000000C, 0x10000010 and 0x10000014. The data bytes are:

uint32_t Flash_MSGID[5] = { 0x430U, 0x431U, 0x431U, 0x431U, 0x431U};

We use the FLASH_LDD component from ProcessorExpert to write and read data. If we write the above mentioned array Flash_MSGID, there is no problem, and the data is written and read correctly. But if we change the value of second element in the array to 0x430U, then we get corrupted data on that locations, and the read command generates a hard fault condition.

uint32_t Flash_MSGID[5] = { 0x430U, 0x430U, 0x431U, 0x431U, 0x431U};

Hope someone can give us some help with this problem.

0 Kudos
987 Views
mjbcswitzerland
Specialist V

Dario

You are not respecting the phrase programming requirements fo the Flash in the K10FX512.

You are only allowed to write 8 byte blocks at at time (phrase) and any attempt to write to one of these phrases (8 byte blocks) that is not erased will corrupt the Flash and cause it to return a hard fault afterwards (it then requires an erase to recover).

You need to change your code to leave a long word space after the 5th long word that you have written:

eg:

0x10000004, 0x10000008, 0x1000000C, 0x10000010 and 0x10000014 + 0xffffffff

and then add futher data after that and it will work (or some other equivalent method).

The problem is that the Flash is being written as follows (assuming X is divisible by 4):

Phase Address X = 0x10000004, 0x10000008

Phase X + 1 = 0x1000000C, 0x10000010

Phase X + 2 = 0x10000014 + 0xffffffff

If you tried to write at long word offset 5 it was doing

Phase X + 2 = 0x10000014 + "changed value"

It is not allowed to write to a phrase twice (without a sector erase inbetween) and so your problem arisies.

Regards

Mark

Kinetis: http://www.utasker.com/kinetis.html

K60: http://www.utasker.com/kinetis/TWR-K60N512.html / http://www.utasker.com/kinetis/TWR-K60D100M.html / http://www.utasker.com/kinetis/TWR-K60F120M.html

For the complete "out-of-the-box" Kinetis experience and faster time to market

:smileyinfo: Out-of-the-box support for 46 Kinetis boards and 10 IDEs (460 combinations from a single code source with no porting required)

986 Views
darioantolovic
Contributor I

Mark,

thank You for the answer, it helped us a lot.

You are right, the problem was that we didn't respect the phrase requirements for this MCU.

We changed everything so that we write always 8 byte blocks at once, and now works everything OK.

Best regards,

Dario

0 Kudos