2017-06-26 12:21 PM
Hi all,
I am working with the STM32L486 series and having a flash question. I need to save some NVM parameters to a 2K page in flash but the flash utils can only write double word at a time (64 bits). My NVM structure size will ebb and flow and would probably not align to a 64-bit boundary. How do I handle saving the structure gracefully in the code? I am thinking of padding some dummy bytes to meet the 64-bit boundary but it is a bit cumbersome. I used to do this feature in bytes easily when working with other processors capable of byte write, but this is a bit different. Any ideas?
Thanks,
ED
2017-06-26 12:39 PM
Can you just not use a struct, where you memcpy from FLASH to RAM, or read in-place, and then have a writing routine that commits the whole thing, rounded to an 8-byte boundary, from a RAM based buffer? Or malloc() the RAM buffer rounded up to the next 8-byte size, and access via a pointer.
I don't see a fault occurring unless the structure is pushed to the very top of RAM so not padding exists, but the stack is most likely there.
2017-06-26 03:21 PM
Thanks Clive for the quick response, as always. I'd like to use a master RAM based NVM struct, which consists of a few sub structs, to do one shot memcpy as you mentioned. This contributes to the code clarity and efficiency, which are important to me.
Been thinking maybe I need to align all the sub structs to a 64-bit boundary. The unused bytes will be designated as spares to be replaced with actual parameters when a particular sub struct needs to expand. For example:
typedef struct NVM_STRUCT_ID
{ uint16_t Param1;uint16_t
Param2
;
uint16_t
Param3
;
uint16_t
Param4
;
uint16_t
Param5
;
uint16_t
spare1
;
uint16_t
spare2
;
uint16_t
spare3
;
} NVM_STRUCT_ID;Of course the spares will be managed at a minimum to minimize foot print.
Will experiment a few methods as I go along.
2017-06-27 12:26 AM
I usually prefer to pass the memory alignment to compiler by using unions. For example:
typedef struct MY_STRUCT
{
uint16_t Param1;
uint16_t Param2;
uint16_t Param3;
} MY_STRUCT;
union{
uint64_t u64;
MY_STRUCT id;
}testunion;
uint64_t test64;
testunion.id.Param1 = 1;
testunion.id.Param2 = 2;
testunion.id.Param3 = 3;
test64 = testunion.u64; // converted NVM_STRUCT_ID to 64-bit variable�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
Bests,
Misagh
2017-06-27 12:30 PM
Not sure how this is better since it looks like you need to allocate both 'testunion' (missing here?) and 'test64' to accomplish the same goal. Thanks anyway!
2017-06-28 12:40 AM
Actually you do not need to test64. It just used to clarify that you can use the u64 variable as the converted struct.