All,
I am using the K64 FRDM board for some proof concept regarding the flex nvm setup for flash EEPROM and DFLASH. I couldn't find any demos or application notes on how to leverage this library code, but essentially started playing with it to get a working solution. I was finally able to get it to work, however have noticed some intermittent behavior for settings this up using the partition command. If i let the code run on its own, the flash EEPROM does not get properly setup, and stays at the default of no E-flash and only D-flash is used. However if I manually step through the FLASH_ProgramPartition() function, specifically into the flash_command_sequence(), and the callFlashRunCommand() function it E-flash and D-flash or properly partitioned and works as expected. Not sure what is going on here. I have intentionally turned off all interrupts during this just to make sure nothing will pull the rug from underneath the fsl_flash.c functions. Any help or even and app note that specifically details how to actually use this fsl_flash.c library with E-FLASH and D-FLASH.
It should be important to note, that I am using mbed cli to create the project and export to IAR.
Below is the code that shows what I've done:
#include "mbed.h"
#include "intrinsics.h"
#include "fsl_flash.h"
#include <stdio.h>
#include <errno.h>
#define MAX_STRING_SIZE 20
#define TEST_VALUE 0xB00B3 //721075
#define CALC_ADDR_END( start, var ) (start + sizeof( var ))
#define EEPROM_START FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS
typedef struct
{
uint32_t test_var1;
uint16_t test_var2;
bool test_var3;
uint8_t test_var4;
uint16_t test_var5;
}
TestStruct1_t;
typedef struct
{
uint8_t test_var1;
char test_string1[MAX_STRING_SIZE];
uint8_t test_var3;
}
TestStruct2_t; // Create global variable that is tied to flex_nvm memory space
__no_init uint32_t eeprom1_uint32 @ EEPROM_START;
#define E_UINT32_2 CALC_ADDR_END(EEPROM_START, eeprom1_uint32)
__no_init uint32_t eeprom2_uint32 @ E_UINT32_2;
#define E_TEST_STRUCT_1 CALC_ADDR_END(E_UINT32_2, eeprom2_uint32)
__no_init TestStruct1_t e_test_struct1 @ E_TEST_STRUCT_1;
#define E_TEST_STRUCT_2 CALC_ADDR_END(E_TEST_STRUCT_1, e_test_struct1)
__no_init TestStruct2_t e_test_struct2 @ E_TEST_STRUCT_2;
#pragma location="__flash"
const uint32_t test_var = 0;
flash_config_t flash_config;
template <class T, class U>
static status_t Copy_Mem_To_EEPROM(T *start, U *src, uint32_t num_bytes)
{
return FLASH_EepromWrite(&flash_config, (uint32_t)start, (uint8_t*)src, num_bytes);
}
template <class T, class U>
static status_t Copy_Value_To_EEPROM(uint32_t *start, T src, uint32_t num_bytes)
{
return FLASH_EepromWrite(&flash_config, (uint32_t)start, (uint8_t*)&src, num_bytes);
}
void flex_mem_demo(void)
{
__disable_interrupt();
TestStruct1_t p1;
TestStruct2_t p2;
// manually break and set the eeprom1_uint32 = 0 using the debugger
// this allows the one time program partition to be run. Every other restart
// instance from this point forward will only initialize and increment the
// eeprom1_uint32 , but not repartition the Flex NVM. Enjoy
if(eeprom1_uint32 == 0xFFFFFFFF)
{
FLASH_Init(&flash_config);
FLASH_ProgramPartition(&flash_config, kFLASH_PartitionFlexramLoadOptionLoadedWithValidEepromData, 0x32, 0x0B);
FLASH_Init(&flash_config);
Copy_Value_To_EEPROM(&eeprom1_uint32, TEST_VALUE, sizeof(eeprom1_uint32));
p1.test_var1 = 1; //modify local parameter //now store in eeprom Copy_Mem_To_EEPROM(&e_test_struct1.test_var1, &p1.test_var1, sizeof(e_test_struct1.test_var1));
}
else
{
FLASH_Init(&flash_config); p1.test_var1 = e_test_struct1.test_var1 + 1; Copy_Mem_To_EEPROM(&e_test_struct1.test_var1, &p1.test_var1, sizeof(e_test_struct1.test_var1));
Copy_Value_To_EEPROM(&eeprom1_uint32, (eeprom1_uint32 + 1), sizeof(eeprom1_uint32));
}
__enable_interrupt();
}
int main(void)
{
device.baud(115200);
flex_mem_demo();
dflash_mem_demo();
while(1);
}