Вопрос

I have a configuration structure I would like to save on the internal flash of ARM cortex M3. According to the specifications, the data save in the internal flash, must be aligned to 32bit. Because I have lot's of boolean, and chars in my structure,I don't want to use 32bits to store 8 bits... I decided to pack the structure using the __packed preprocessor pragma, Then When I save it as a whole structure, I just have to make sure that the structure size is divisible by 4 (4 bytes = 32bits), I do it by adding padding bytes if needed. Currently, during development I alter the structure a lot, and to make it aligned with the 32 bits, I need to change the padding bytes all the time. Currently, the structure look slike this

typedef __packed struct
{
uint8_t status;
uint16_t delay;
uint32_t blabla;
uint8_t foo[5];
uint8_t padding[...] // this has to be changed every time I alter the structure.
} CONFIG;

Is there a better way to achieve what I'm doing ? I'm quite new in Embedded programming, and I want to make sure that I'm not doing mistakes.

Edit: Please note. The data is persisted in the end of the internal-flash, so omitting the padding will not work...

Это было полезно?

Решение

Perhaps this is an idea:

typedef __packed struct {
    uint8_t status;
    uint16_t delay;
    uint32_t blabla;
    uint8_t foo[5];
} CONFIG;

typedef __packed struct {
    CONFIG cfg;
    uint8_t padding[4 - (sizeof(CONFIG) % 4)]
} CONFIGWRAPPER;

Другие советы

Solution 1: You could put it inside a union containing your structure and an array of characters:

union
{
  CONFIG config;
  uint8_t total_size[32];
} my_union;

Firstly, packed alignment is usually to be avoided, if you end up with data not aligned to their natural boundaries, some CPUs will just issue a trap when you try to access them.

First, store the members in an order so the compiler doesn't add gaps for alignment (or if it does, it adds it at the end). If you can, have the 1. member have the alignment requirement you desire - as that forces the compiler to at least give the struct that much alignment.

This requires some knowledge on how the alignment requirements of your platform and compiler, e.g. get rid of the padding array, and change

typedef struct
{
uint8_t status;
uint16_t delay;
uint32_t blabla;
uint8_t foo[5];
uint8_t padding[...];
} CONFIG;

to

typedef struct
{
uint32_t blabla;
uint16_t delay;
uint8_t status;
uint8_t foo[5];
} CONFIG;

Then tell the compiler that this struct needs 4 byte aligment (in this case it likely already will as the first member has 4 byte or more alignment requirement). e.g. with gcc use attribute((__aligned__(4))

Then write a small test program that validates the alignment requirements you have (which is just a small program that uses sizeof() and alignof() on your struct), this'll even tell you if you need to add instruction for the struct to be aligned. Run that program as part of the build/packaging.

Solution 2: You could use the IAR-specific feature #pragma location to place the config data at a specific location, like 32 from the end of the flash. That way you would not need to pad the structure in any way:

/* Fictitious end of flash location. */ 
#pragma location=0x1234FFE0
struct [... your struct goes here ...]
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top