我在访问这个联合时遇到问题:
typedef union{
struct{
uint8_t SA : 8; //! Source Address
union { //! Protocol Data Unit
struct {
uint8_t SPECIFIC : 8;
uint8_t FORMAT : 8;
} ;
uint16_t PDU2 ;
};
uint8_t DP : 1; //! Data Page
uint8_t Reserved : 1; //! Reserved = 0
uint8_t PRIORITY : 3; //! Priority
uint8_t Reserved1 : 3; //! Reserved = 0
};
uint32_t word; //single 32-bit word
} J1939_ID
在ESP32 中执行下一个
J1939_ID J1939_RxId;
J1939_RxId.word = 0x11223344;
Serial.println(J1939_RxId.word, HEX);
Serial.println(J1939_RxId.SA, HEX);
Serial.println(J1939_RxId.PDU2, HEX);
Serial.println(J1939_RxId.FORMAT, HEX);
Serial.println(J1939_RxId.SPECIFIC, HEX);
PDU2是0x1122,而不是我想要的0x2233,FORMAT(0x22(和SPECIFIC(0x33(相同
我看不出哪里出了问题,有人能帮帮我吗?
编辑:溶液加入">属性((压缩((";工会
typedef union{
struct{
uint8_t SA : 8; //! Source Address
union { //! Protocol Data Unit
struct {
uint8_t SPECIFIC : 8;
uint8_t FORMAT : 8;
} ;
uint16_t PDU2 ;
}__attribute__((packed));
uint8_t DP : 1; //! Data Page
uint8_t Reserved : 1; //! Reserved = 0
uint8_t PRIORITY : 3; //! Priority
uint8_t Reserved1 : 3; //! Reserved = 0
};
uint32_t word; //single 32-bit word
} __attribute__((packed)) J1939_ID
您有一个小型的endian机器。因此,RxId.word
看起来像
+----+----+----+----+
| 44 | 33 | 22 | 11 |
+----+----+----+----+
您的编译器使用";正常填充约定";,因此,您的结构更接近以下内容(省略了一些不相关的细节(:
struct {
uint8_t SA; // Aligned to an offset divisible by 1.
uint8_t __padding1;
uint16_t PDU2; // Aligned to an offset divisible by 2.
uint8_t flags; // Aligned to an offset divisible by 1.
uint8_t __padding2;
} // Size must be divisible by 2 (largest of above).
把两者放在一起,我们得到
struct {
uint8_t SA; // 0x44
uint8_t __padding; // 0x33
uint16_t PDU2; // 0x1122
uint8_t flags; // 0x00 or uninitialized, not sure.
}
如果要继续使用并集,则需要将单词从本端序转换为大端序(例如使用htonl
(,或者更改结构中字段的顺序。您还需要告诉编译器创建一个";包装的";struct(即省略填充(。