有点令人困惑的标题,我知道。
我创建了一个包含“raw”-array和2个结构的联合。这两个结构包含一个struct header_t,一个结构联合和一个uint8_t。我只附加了inMsg_t,因为两个结构都以相同的方式构成。
typedef struct sAfRegisterSRSP{
uint8_t Status;
} tAfRegisterSRSP;
typedef union InOutMsg_u{
uint8_t raw[ZIGBEE_PAYLOAD_MAX];
outMsg_t outMsg;
inMsg_t inMsg;
}msg_t;
typedef struct header_s{
uint8_t len; ///< packet len
uint8_t cmd0; ///< type (Bit: 7-5) and subsystem (Bit 4-0))
uint8_t cmd1; ///< command identifier
}header_t;
typedef struct inMsg_s{
header_t header;
union payload_u{
tAfRegisterSRSP afRegisterSRSP;
tAfDataRequestSRSP afDataRequestSRSP;
tAfIncomingMsgAREQ afIncomingMsgAREQ;
tAfDataConfirmAREQ afDataConfirmAREQ;
tZbStartRequestSRSP zbStartRequestSRSP;
tZbPermitJoiningRequestSRSP zbPermitJoiningRequestSRSP;
} payload;
uint8_t checksum; //just a placeholder; cannot be used practically
}inMsg_t;
现在,当我运行代码时,头字节的内存映射很好。 raw数组的byte [0]映射到header-struct中的len-field。 cmd0和cmd1也是如此。但是,afRegisterSRSP-struct的“status”不是指向状态字节,而是指向CRC-Byte,它位于状态字节之后。查看内存地址时也很清楚。
标题字段位于地址:0x15F6,0x15F7和0x15F8。
然后第一个有效载荷字节位于0x15FA并且省略了0x15F9。
我已经附加了调试器中显示的screenshot内存。
我无法弄清楚为什么跳过一个字节以及如何解决它。
答案 0 :(得分:1)
payload
联合与四字节边界对齐,header
只有三个字节长。这意味着在结构的C定义中有一个填充字节,但是你的内存映射可能是打包的,省略了所有填充。您需要使用编译器特定的标志,pragma或属性来指定各种联合/结构被打包(到一个字节对齐)以确保不创建填充字节。例如,gcc
packing和Visual Studio packing。
此外,根据您的磁盘数据格式,您可能需要小心执行字节交换以从机器本机字节序(通常是小端,例如在x86上)切换到网络字节序(通常是大端字节,除了少数例外) Windows特定协议)。