内部FLASH存储器中C结构的对齐
我有一个配置结构,想保存在 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;
有没有更好的方法来实现我正在做的事情? 我是嵌入式编程的新手,我想确保我没有犯错误。
编辑:请注意。数据保留在内部闪存的末尾,因此省略填充将不起作用......
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...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
首先,通常要避免压缩对齐,如果最终得到的数据未与其自然边界对齐,则当您尝试访问它们时,某些 CPU 只会发出陷阱。
首先,按顺序存储成员,以便编译器不会添加对齐间隙(或者如果添加,则会将其添加到末尾)。如果可以的话,让 1. 成员具有您想要的对齐要求 - 因为这会迫使编译器至少给予结构足够的对齐。
这需要一些关于平台和编译器的对齐要求的知识,例如摆脱填充数组,并更改
为
然后告诉编译器该结构需要 4 字节对齐(在这种情况下,它可能已经需要,因为第一个成员已经4 字节或更多对齐要求)。例如,使用 gcc 使用
attribute((__aligned__(4))
然后编写一个小测试程序来验证您的对齐要求(这只是一个在您的struct),这甚至会告诉您是否需要添加要对齐的结构的指令作为构建/打包的一部分运行该程序。
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
to
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.
也许这是一个想法:
Perhaps this is an idea:
解决方案 1:您可以将其放入包含结构和字符数组的联合中:
Solution 1: You could put it inside a union containing your structure and an array of characters:
解决方案 2:您可以使用 IAR 特定的功能
#pragma location
将配置数据放置在特定位置,例如从闪存末尾开始的 32。这样你就不需要以任何方式填充结构: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: