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;
}
Solved! Go to Solution.
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.
-------------------------------------------------------------------------------
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.
-------------------------------------------------------------------------------
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.
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.
-------------------------------------------------------------------------------
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.
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.
-------------------------------------------------------------------------------
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?
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.
-------------------------------------------------------------------------------
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.
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.
-------------------------------------------------------------------------------
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.
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.
-------------------------------------------------------------------------------