std*_*all 6 c cortex-m3 memory-alignment iar
我有一个配置结构我想保存在ARM cortex M3的内部闪存上.根据规格,数据保存在内部闪存中,必须与32bit对齐.因为我有很多boolean和chars在我的结构中,我不想使用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;
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来实现我正在做的事情?我是嵌入式编程的新手,我想确保我没有犯错误.
编辑:请注意.数据在内部闪存结束时保留,因此省略填充将无法正常工作......
首先,通常要避免压缩对齐,如果最终得到的数据未与其自然边界对齐,则当您尝试访问它们时,某些 CPU 只会发出陷阱。
首先,按顺序存储成员,以便编译器不会添加对齐间隙(或者如果添加,则会将其添加到末尾)。如果可以的话,让 1. 成员具有您想要的对齐要求 - 因为这会迫使编译器至少给予结构足够的对齐。
这需要一些关于平台和编译器的对齐要求的知识,例如摆脱填充数组,并更改
typedef struct
{
uint8_t status;
uint16_t delay;
uint32_t blabla;
uint8_t foo[5];
uint8_t padding[...];
} CONFIG;
Run Code Online (Sandbox Code Playgroud)
到
typedef struct
{
uint32_t blabla;
uint16_t delay;
uint8_t status;
uint8_t foo[5];
} CONFIG;
Run Code Online (Sandbox Code Playgroud)
然后告诉编译器该结构需要 4 字节对齐(在这种情况下,它可能已经需要,因为第一个成员具有 4 字节或更多对齐要求)。例如与 gcc 一起使用attribute((__aligned__(4))
然后编写一个小型测试程序来验证您的对齐要求(这只是一个在结构上使用 sizeof() 和alignof() 的小程序),这甚至会告诉您是否需要为结构添加指令保持一致。作为构建/打包的一部分运行该程序。
也许这是一个想法:
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;
Run Code Online (Sandbox Code Playgroud)