gpt4 book ai didi

c - Overeager struct packing warnings with `__attribute__((packed))` ?

转载 作者:太空狗 更新时间:2023-10-29 16:05:52 27 4
gpt4 key购买 nike

我正在 32 位 ARM mcu(Atmel SAM4SD32C,Cortex-M4/ARMv7E-M 部件)上实现二进制日志记录系统,并且正在设计我的数据结构。我的目标是将日志格式描述为一个压缩结构,并将该结构与一个字符数组 union 起来,以便写入日志设备(在本例中为通过 FatFS 的 SD 卡)。

基本上,我有一个非常简单的结构:

typedef struct adc_samples_t
{
int32_t adc_samples[6];

uint64_t acq_time;

int8_t overrun;
uint8_t padding_1;
uint8_t padding_2;
uint8_t padding_3;

} __attribute__((packed, aligned(4))) adc_sample_set;

现在,我的架构是 32 位的,据我所知,访问任何成员/other/然后 overrun 成员应该是 32 位对齐的,因此没有额外的开销.此外,aligned(4) 属性应强制该结构的任何实例都位于 32 位对齐边界上。

但是,编译上面的结构定义会产生一堆警告:

        In file included from ../src/main.c:13:0:
<snip>\src\fs\fs-logger.h(10,10): warning: packed attribute causes inefficient alignment for 'adc_samples' [-Wattributes]
int32_t adc_samples[6];
^
<snip>\src\fs\fs-logger.h(12,11): warning: packed attribute causes inefficient alignment for 'acq_time' [-Wattributes]
uint64_t acq_time;

据我所知(我现在意识到这是一个很大的假设),我假设 32 位对齐是在 32 位 arm 上实现最佳组件定位所需的全部。 奇怪的是,唯一/不/产生警告的成员是 overrunpadding_X 成员,我不明白其原因。 (好吧,ARM docs字节访问总是对齐的。)

这里到底发生了什么?我假设(可能不正确)结构实例化将在 4 字节边界上。编译器是否需要更广泛的对齐方式(在 8 字节边界上)?


编辑:好的,深入研究 ARM 文档(这里的魔法词是“Cortex-M4 对齐”:

3.3.5. Address alignment

An aligned access is an operation where a word-aligned address is used for a word, dual word, or multiple word access, or where a halfword-aligned address is used for a halfword access. Byte accesses are always aligned.

The Cortex-M4 processor supports unaligned access only for the following instructions:

LDR, LDRT
LDRH, LDRHT
LDRSH, LDRSHT
STR, STRT
STRH, STRHT

All other load and store instructions generate a UsageFault exception if they perform an unaligned access, and therefore their accesses must be address aligned. For more information about UsageFaults see Fault handling.

Unaligned accesses are usually slower than aligned accesses. In addition, some memory regions might not support unaligned accesses. Therefore, ARM recommends that programmers ensure that accesses are aligned. To trap accidental generation of unaligned accesses, use the UNALIGN_TRP bit in the Configuration and Control Register, see Configuration and Control Register.

为什么我的 32 位对齐值不是字对齐的?用户指南将“对齐”定义如下:

Aligned
A data item stored at an address that is divisible by the number of bytes that defines the data size is said to be aligned. Aligned words and halfwords have addresses that are divisible by four and two respectively. The terms word-aligned and halfword-aligned therefore stipulate addresses that are divisible by four and two respectively.

最佳答案

I assumed that 32-bit alignment was all that was needed for optimal component positioning on 32-bit ARM

是的。

但是你在这里没有 32 位对齐[在最初提出的问题] because :

Specifying the packed attribute for struct and union types is equivalent to specifying the packed attribute on each of the structure or union members.

given that :

The packed attribute specifies that a variable or structure field should have the smallest possible alignment—one byte for a variable, and one bit for a field, unless you specify a larger value with the aligned attribute.

换句话说,如果您仍然希望压缩结构在强制所有成员对齐后仍然具有一些最小对齐,因此类型本身为空,您需要指定 - 事实上可能实际上不会让 -Wpacked 闭嘴是另一回事 - GCC 可能会在它实际考虑任何进一步的对齐修饰符之前反射性地吐出它。

请注意,在序列化方面,您不一定需要打包它。成员恰好适合 9 个字,因此唯一的编译器填充是在最后一个额外的字,以将总大小四舍五入到 40 个字节,因为 acq_time 强制结构自然对齐 8。除非你想一次对这些东西的整个数组进行操作,否则你可以简单地忽略它并仍然将成员视为一个 36 字节的 block 。

关于c - Overeager struct packing warnings with `__attribute__((packed))` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40640948/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com