7

我有一个配置结构,我想保存在 ARM cortex M3 的内部闪存上。根据规范,保存在内部flash中的数据,必须对齐32bit。因为我的结构中有很多布尔值和字符,我不想使用 32 位来存储 8 位......我决定使用__packed预处理器编译指示打包结构,然后当我将它保存为一个整体结构时,我只需确保结构大小可被 4 整除(4 字节 = 32 位),如果需要,我通过添加填充字节来做到这一点。目前,在开发过程中,我对结构进行了很多更改,为了使其与 32 位对齐,我需要一直更改填充字节。目前,结构看起来像这样

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;

有没有更好的方法来实现我正在做的事情?我是嵌入式编程的新手,我想确保我没有犯错。

编辑:请注意。数据保留在内部闪存的末尾,因此省略填充将不起作用...

4

4 回答 4

4

也许这是一个想法:

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;
于 2011-12-15T08:19:01.153 回答
4

解决方案 1:您可以将其放在包含结构和字符数组的联合中:

union
{
  CONFIG config;
  uint8_t total_size[32];
} my_union;
于 2011-12-15T08:28:39.490 回答
4

首先,通常要避免打包对齐,如果您最终得到的数据未与其自然边界对齐,则某些 CPU 在您尝试访问它们时会发出陷阱。

首先,按顺序存储成员,这样编译器就不会为对齐添加间隙(或者如果有,它会在最后添加它)。如果可以的话,让 1. 成员具有您想要的对齐要求 - 因为这会迫使编译器至少为结构提供那么多对齐。

这需要一些关于您的平台和编译器的对齐要求的知识,例如摆脱填充数组并更改

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

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

然后告诉编译器这个结构需要 4 字节对齐(在这种情况下,它可能已经需要,因为第一个成员有 4 字节或更多的对齐要求)。例如与 gcc 一起使用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.

于 2011-12-15T08:54:26.607 回答
1

解决方案 2:您可以使用 IAR 特定功能#pragma location将配置数据放置在特定位置,例如闪存末尾的 32 处。这样你就不需要以任何方式填充结构:

/* Fictitious end of flash location. */ 
#pragma location=0x1234FFE0
struct [... your struct goes here ...]
于 2011-12-15T08:30:50.300 回答