Hello, I have a following problem. I want to save my own struct using the flash_demo example from SDK.
I am using FlashProgram function for that purpose.
What have I tried:
Here is my code (the rest of SDK flash_demo remains unchanged):
typedef struct
{
int x, y;
char name[40];
} myStruct;
int main(void)
{
/*rest of example code*/
myStruct first = { .x = 1, .y = 123, .name = "George" };
/*rest of example code*/
/********************************************************************
* For devices without SWAP, program some data for demo purposes
*********************************************************************/
destination = flashSSDConfig.PFlashBase + (flashSSDConfig.PFlashSize - 6*FTFx_PSECTOR_SIZE);
end = flashSSDConfig.PFlashBase + (flashSSDConfig.PFlashSize - 4*FTFx_PSECTOR_SIZE);
/*for (i = 0; i < BUFFER_SIZE_BYTE; i++)
{
Set source buffer
program_buffer[i] = i + 100;
}*/
size = sizeof (myStruct);//BUFFER_SIZE_BYTE;
/* message for user */
PRINTF("\n\n\r---->Running FlashProgram() and FlashProgramCheck()...");
while ((destination + (size)) < end)
{
ret = FlashProgram(&flashSSDConfig, destination, size, \
first, g_FlashLaunchCommand);
if (FTFx_OK != ret)
{
ErrorTrap(ret);
}
/*rest of example code*/
Unfortunately this gives an error:
D:/Freescale/SDK/examples/frdmkl43z/demo_apps/flash_demo/main.c:354:9: error: incompatible type for argument 4 of 'FlashProgram'
1. Does it mean I am not able to save struct in flash memory? (somewhat contrary to what Mike Butcher said here -> Reading flash - why not by normal memory access? )
2. Is there any way to transform any structure to uint8_t* which is required by FlashProgram?
I will be very grateful for any suggestions!
Hello Piotr Cerba:
Bob Paddock is correct, the FlashProgram() function of the driver expects a pointer to a raw array of bytes, not a structure. You can cast the parameter to match the uint8_t* expected by the driver, like this:
FlashProgram(&flashSSDConfig, destAdrss, sizeof(first), (uint8_t*)&first, g_FlashLaunchCommand);
This is what I get in KDS with GCC using your code (except that I used address 0x80000) and considering that the ARM Cortex-M core in Kinetis uses little endianness:
Since the structure is stored in Flash in the same order as the variable in RAM, then you can retrieve the data from flash by using a simple pointer to the same kind of structure, something like this:
typedef struct
{
int x, y;
char name[40];
} myStruct, *myStructPtr;
//...
myStruct first = { .custom = "ON", .x = 1, .y = 123, .name = "George" };
myStructPtr firstPtr = (myStructPtr)0x80000;
//...
destAdrss = 0x80000;
FlashProgram(&flashSSDConfig, destAdrss, sizeof(first), (uint8_t*)&first, g_FlashLaunchCommand);
//Erasing "first"
first.x = 0;
first.y = 0;
//Recovering "first"
first.x = firstPtr -> x;
first.y = firstPtr -> y;
:smileyalert: Note that the core processor is 32-bit (4 bytes), but the smallest programming size for the flash memory controller in K64 (FTFE) is 8-bytes (phrase). Therefore the flash driver expects that the size parameter is a multiple of 8 and the dest address parameter is aligned to an 8-bytes boundary. The size of your structure is 40 + 4 + 4 = 48 bytes, which is good, but if you add more members and the size is not a multiple of 8, then you may need to add padding bytes, considering that the compiler may add its own padding bytes to a member which is not 4-bytes long, as mentioned by Bob.
I hope this information is helpful.
Regards!,
Jorge Gonzalez
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
I don't know what FlashProgram wants. Would it want &first?
However using structures in this way is not recommended due to how the compiler might pack the structures.
A structure may have hidden bytes to maintain alignment. ARM natively normally aligns to four byte boundaries.
offsetof() in <stddef.h> can be helpful in (de)serializing structures for storage and transmission.