How can I reliably initialize EEE or partition the DFLASH on MK64FX?

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

How can I reliably initialize EEE or partition the DFLASH on MK64FX?

Jump to solution
2,248 Views
atilla
Contributor II

I have a bizarre problem that sometimes flash operations halt the microcontroller with a bus fault. The chip is MK64FX512VLL12.

I write my images using the command

pyocd flash -t k64f main.bin

My initialization code is below. What happens is, sometimes after verifying that the EEE functionality works, I will reflash the same firmware, and EEPROM total size would read zero.Then attempting to erase the flash and re-partition it causes a bus fault. However if I catch the fault with a debugger and reset the cpu, everything works fine from now on. If I don't do this capture/reset cycle from the debugger, the µC keeps resetting itself indefinitely.

Here is the gdb backtrace:

Program received signal SIGSEGV, Segmentation fault.
0xfffffffe in ?? ()
(gdb) bt
#0  0xfffffffe in ?? ()
#1  <signal handler called>
#2  0x20015f1a in s_flashRunCommand ()
#3  0x000029ee in flash_command_sequence (config=config@entry=0x20000870 <flash_config>) at ../../../sdk/devices/MK64F12/drivers/fsl_fla
   sh.c:2707
#4  0x00002a4c in FLASH_ProgramPartition (config=config@entry=0x20000870 <flash_config>, option=option@entry
    =kFLASH_PartitionFlexramLoadOptionLoadedWithValidEepromData, eepromDataSizeCode=eepromData
    SizeCode@entry=5, flexnvmPartitionCode=flexnvmPartit
    ionCode@entry=8) at ../../../sdk/devices/MK64F12/drivers/fsl_flash.c:2301
#5  0x00008304 in eee_partition () at ../../src/flash.c:432
#6  0x0000d48a in flash_init () at ../../src/flash.c:324
#7  0x0000fa6a in main () at ../../src/main.c:346

Now if I run the firmware in the debugger, and run through my flash_init function one line at a time, it works perfectly fine. And any subsequent power cycles etc. run OK. But if I flash something else, and reflash this firmware, it starts crashing again, until I run the initialization code in the debugger once more. Any idea how I can do this better?

static volatile flash_config_t  flash_config = { 0 };
void flash_init(void)
{
 status_t s;


s = FLASH_Init(&flash_config);
 kprintf("Initialization status :%ld\r\n", s);

 dflash_wait();
 s = FLASH_SetFlexramFunction(&flash_config, 
 kFLASH_FlexramFunctionOptionAvailableForEeprom);


if(512 != flash_config.EEpromTotalSize) // we need to partition
 {
 kprintf("Need to partition the data flash\r\n");
 s = eee_partition();
 kprintf("Partition status :%d\r\n", s);
 }
}

inline static void dflash_wait(void)
{
 while ((FTFE-> FSTAT & FTFE_FSTAT_CCIF_MASK) == 0){};
}

#define EEE_SPLIT_8 (0 << 4) //for 1+7 split
#define EEE_512 0b0101

#define EEE_SIZE EEE_512
#define EEE_SPLIT EEE_SPLIT_8 

#define EEE_CODE (EEE_SIZE | EEE_SPLIT)

#define DEPART_128 0x8 //code for 128KB for EEEPROM backing (maximum)
#define DEPART_CODE DEPART_128
#define DFLASH_BASE 0x10000000
//#define DFLASH_SIZE (128*1024)
#define DFLASH_SIZE 0x00020000

status_t eee_partition(void)
{
    status_t s;

    dflash_wait();
    FLASH_Erase(&flash_config,
    DFLASH_BASE,
    DFLASH_SIZE,
    kFLASH_ApiEraseKey);
 
    dflash_wait();
    s = FLASH_ProgramPartition(&flash_config,
            //load FlexRAM with EEPROM data at boot time
            kFLASH_PartitionFlexramLoadOptionLoadedWithValidEepromData,
            EEE_CODE,
            DEPART_CODE);
    return s;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Labels (1)
0 Kudos
Reply
1 Solution
2,009 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Atilla Filiz,

  Sorry, K64 120M chip doesn't have the HSRUN mode, please ignore that point.

 Do you enable the interrupt before you do the flash operation?

  The flash operation can't be interrupted, so you need to disable the global interrupt before you do the flash operation.

  Please try to disable the global interrupt, and test it again.

  Any updated information, please kindly let me know.


Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

View solution in original post

0 Kudos
Reply
11 Replies
2,009 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Atilla Filiz,

  When you do the flash operation, please note these points:

1. Before you do the flash commander operation, please disable the global interrupt, after you finish it, you can enable the interrupt again.

 2. Please copy the launch flash commander to the RAM.

Please check it at first.

BTW, please tell me what's the data about

flash_config.EEpromTotalSize?
Where you get this data?

Any updated information, please kindly let me know.
Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
2,009 Views
atilla
Contributor II

The driver I am using is here: FSL_Flash drivers ($1863113) · Snippets · GitLab 

The data comes from reading the DFLASH IFR. The call is line 3124 in fsl_flash.c in the above snippet.

0 Kudos
Reply
2,009 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Atilla Filiz,

   Do you try the official SDK code which can be downloaded from this link:

https://mcuxpresso.nxp.com/en/select 

  Can you reproduce the problem on the official SDK code?

  You can find the flash project in:

SDK_2.5.0_FRDM-K64F\boards\frdmk64f\driver_examples\flash

But, please note, if you are using MK64FX512VLL12, you need to change the project according file to K64FX, when you download the SDK code, please choose the processor as MK64FX512VLL12, you can find the according chip code in folder:SDK_2.5.0_FRDM-K64F\devices

If you can reproduce it in the official code, then I will help you to check the details.


Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
2,009 Views
atilla
Contributor II

Hi Kerry

I am using the official SDK, but an older version (2.3.0 instead of 2.5). Upgrading to a newer SDK is not possible at the moment. I had a look at 2.5 and saw the flash drivers have been refactored.

0 Kudos
Reply
2,009 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Atilla Filiz,

   It doesn't matter, you can run the SDK2.5 on your side, just check whether that code also have problems on your side or not.

  Any updated information, just let me know.


Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
2,009 Views
atilla
Contributor II

Hi

I did run the SDK example successfully for both 2.3.0 and 2.5.0 versions. However, the SDK example is for PFLASH only. My issue happens with DFLASH, specifically running in EEE mode. This is the key difference between the sample and our use case.

Otherwise I checked the initialization steps, both in the example and my code, the steps are

- memset the flash config structure to 0
- call flash_init

- call flash_erase

Is there some cache that maybe I need to clean? Check for or clear some error bits in some registers?

In addition, I realized when the CPU gets reset,  FSTAT[RDCOLERR] bit is set. And although the according to the pyocd debugger, there is a Hard Fault, but the code does not jump to our HardFault handler, instead jumps to the address 0xfffffffe which is also strange. Under what condition does the CPU jump to that address?

0 Kudos
Reply
2,009 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Atilla Filiz,

  Do you enable the project optimization? You can set the optimization to the lowest level.

 When you get the reset, any rules? which API will cause it enter the reset? Flash erase and eeprom partition?

 Could you tell me what the clock mode you are using? RUN mode or HSRUN? You can't operate the flash in HSRUN mode.


Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
2,009 Views
atilla
Contributor II

Hi. I compile with -Og and -Os level optimizations. I am not sure what RUN and HSRUN are, but I never use any power saving mode. The flash is clocked at 24MHz.

I see my attempts to use Read Once and Read Resource commands always return 0xffffffff 0xffffffff. Here is how I read resources (in this case, flash partition map)

static void flash_exec(void) __attribute__((section (".data")));
static void flash_exec(void)
{
    FTFE->FSTAT = 0x80;
    while (0 == (FTFE->FSTAT & 0x80));
}

static void flash_read_resource(uint32_t addr)
{
    uint32_t code = addr & 0x00ffffff; //address is 24-bits
    code |= (0x03 << 24);
    kFCCOBx[0] = code;
    FTFE->FCCOB4 = 0x0; //resourse seletor for IFR
    flash_exec();
    //copy registers to our cache for convenience
    ifr_cache[0] = kFCCOBx[1];
    ifr_cache[1] = kFCCOBx[2];
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

static void eee_partition(void)
{
    FTFE->FCCOB0 = 0x80; //PGMPART
    FTFE->FCCOB1 = 0xFF;
    FTFE->FCCOB2 = 0xFF;
    FTFE->FCCOB3 = 0xFF;
    FTFE->FCCOB4 = EEE_CODE; //0x05
    FTFE->FCCOB5 = DEPART_CODE; //0x08

    flash_exec();
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

In this case, flash_exec function is in the SRAM, kFCCOBx is an array for 32-bit access on FCCOB registers.

When I try to partition, I receive the hardfault, and here are my registers when the fault happens:

r0             0x1a                26
r1             0x25                37
r2             0x80                128
r3             0x40020000          1073872896
r4             0x200004d8          536872152
r5             0x200194ec          536974572
r6             0x1fff024c          536805964
r7             0x600               1536
r8             0x0                 0
r9             0x0                 0
r10            0x20010000          536936448
r11            0x0                 0
r12            0x2001ff7b          537001851
sp             0x2001ffb8          0x2001ffb8
lr             0xfffffff9          -7
pc             0xfffffff9          0xfffffff9
xpsr           0x41000003          1090519043
fpscr          0x0                 0
msp            0x2001ffb8          0x2001ffb8
psp            0x0                 0x0 <__isr_vector>
primask        0x0                 0
control        0x0                 0
basepri        0x0                 0
faultmask      0x0                 0

The PC is in a weird state.

Here is how I reset:

1. Connect with pyocd.
2. halt

3. set vc h   (this sets VC functionality to auto-halt on hard faults)

4. go

5. The microcontroller will try to run eee_partition  because the IFR seems erased

wait for the hard fault to happen

5. reset

From now on, the Read Resource command reads the Data Flash IFR correctly, and EEEPROM works also correctly.

0 Kudos
Reply
2,010 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Atilla Filiz,

  Sorry, K64 120M chip doesn't have the HSRUN mode, please ignore that point.

 Do you enable the interrupt before you do the flash operation?

  The flash operation can't be interrupted, so you need to disable the global interrupt before you do the flash operation.

  Please try to disable the global interrupt, and test it again.

  Any updated information, please kindly let me know.


Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply
2,009 Views
atilla
Contributor II

Hi kerryzhou

Disabling the interrupts solved the problem. Indeed the SysTick was the problem. And the HardFault handler was not being called because that handler is on the flash as well. Thank you for the support.

I used __disable_irq() and __enable_irq() to guard the flash operations.

0 Kudos
Reply
2,009 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Atilla Filiz,

    That's very good it works on your side now.

    If you have the new technical questions in the future, welcome to create the new question post.


Have a great day,
Kerry

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
Reply