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)
{
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)
#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
#define DEPART_CODE DEPART_128
#define DFLASH_BASE 0x10000000
#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,
kFLASH_PartitionFlexramLoadOptionLoadedWithValidEepromData,
EEE_CODE,
DEPART_CODE);
return s;
}