冗余 __packed__ 属性
该代码适用于 Microchip 的 PIC32MX 微处理器。他们的编译器本质上是 GCC 3.4。
我倾向于使用 GCC 的 __packed__
属性 将位域打包到一个联合中,然后将它们作为 unsigned char
(即类型双关)检索,以便通过 SPI 或 I2C 发送。这种行为都是由我的实现定义的,并且工作得很好。我更喜欢这个而不是一百行左右的屏蔽和转换:)
我的问题是:下面的代码中是否有多余的 __packed__ 属性?乍一看,我认为那些工会高层成员可以省去,但我不太确定。或者我可以省略嵌套结构中的那些吗?
// Remember that bitfields cannot straddle word boundaries!
typedef struct
{
/// Some flag #1
unsigned FlagOne : 1 __attribute__((packed));
/// Some flag #2
unsigned FlagTwo : 1 __attribute__((packed));
/// A chunk of data
unsigned SomeData : 5 __attribute__((packed));
// and so on, maybe up to 32 bits long depending on the destination
} BlobForSomeChip;
/// This kind of type-punning is implementation defined. Read Appendix A (A7, A12) of
/// the MPLAB C Compiler for PIC32 MCUs manual.
typedef union
{
/// Access the members of this union to set flags, etc
BlobForSomeChip blobdata __attribute__((packed));
/// As a byte for sending via SPI, I2C etc
unsigned char bytes[4] __attribute__((packed));
} BlobData;
This code is for Microchip's PIC32MX microprocessor. Their compiler is essentially GCC 3.4.
I tend use GCC's __packed__
attribute to pack bitfields into a union, and later retrieve them as an unsigned char
(ie. type-punning) for sending over SPI or I2C. This behaviour is all defined by my implementation, and works perfectly. I prefer this to a hundred or so lines of masking and shifting :)
My question is: are there __packed__
attributes in the code below that are redundant? At first glance, I would think that those on the top-level union members can be dispensed with, but I'm not so sure. Or can I leave out those in the nested struct?
// Remember that bitfields cannot straddle word boundaries!
typedef struct
{
/// Some flag #1
unsigned FlagOne : 1 __attribute__((packed));
/// Some flag #2
unsigned FlagTwo : 1 __attribute__((packed));
/// A chunk of data
unsigned SomeData : 5 __attribute__((packed));
// and so on, maybe up to 32 bits long depending on the destination
} BlobForSomeChip;
/// This kind of type-punning is implementation defined. Read Appendix A (A7, A12) of
/// the MPLAB C Compiler for PIC32 MCUs manual.
typedef union
{
/// Access the members of this union to set flags, etc
BlobForSomeChip blobdata __attribute__((packed));
/// As a byte for sending via SPI, I2C etc
unsigned char bytes[4] __attribute__((packed));
} BlobData;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,我建议使用
-Wall
进行编译。现在:
BlobForSomeChip
结构声明了 7 位。通常,由于对齐原因,它的长度为 4 个字节,但使用打包属性时,它的长度仅为 1 个字节。unsigned char[4]
无法打包。不管怎样,它总是 4 个字节长。简而言之:
struct BlobForSomeChip
= 1 字节unsigned char[4]
= 4 字节BlobData
= 4 字节(其最大成员的大小)。总之,BlobData 上的打包属性不是必需的。如果使用的话,GCC 将简单地忽略它们 - 使用
-Wall
查看输出。First of all, I recommend compiling with
-Wall
.Now:
BlobForSomeChip
struct has 7 bits declared. Normally, it would be 4 bytes long due to alignment, but with packed attributes it will be only 1 byte long.unsigned char[4]
can't be packed. It will always be 4 bytes long, no matter what.In short:
struct BlobForSomeChip
= 1 byteunsigned char[4]
= 4 bytesBlobData
= 4 bytes (its largest member's size).Concluding, the packed attributes on
BlobData
are not required. GCC will simply ignore them if used - see the output using-Wall
.