C/C++;——比特域是布尔值吗?

C/C++;——比特域是布尔值吗?,c,embedded,iot,bit-fields,C,Embedded,Iot,Bit Fields,我目前正在处理一个基于SigFox的物联网设备,它可以发送负载高达12字节的消息。这意味着芯片制造商通常必须有创造性。我目前正在处理的一条消息如下: typedef struct { byte MsgId; // Message Identification Value = 0x01 unsigned int Start :1; // Start Message unsigned int Move :1; // Object Moving unsigned int

我目前正在处理一个基于SigFox的物联网设备,它可以发送负载高达12字节的消息。这意味着芯片制造商通常必须有创造性。我目前正在处理的一条消息如下:

typedef struct {
    byte MsgId; // Message Identification Value = 0x01
    unsigned int Start :1; // Start Message
    unsigned int Move :1; // Object Moving
    unsigned int Stop :1; // Object Stopped
    unsigned int Vibr :1; // Vibration Detected
    int16 Temp; // Temperature in 0,01 degC
    byte GPSFixAge; // bit 0..7 = Age of last GPS Fix in Minutes,
    byte SatCnt_HiLL; // bit 0..4 = SatInFix, bit5 Latitude 25 bit 6,7 = Longitude 25,26
    byte Lat[3]; // bit 0..23 = latitude bit 0..23
    byte Lon[3]; // bit 0..23 = longitude bit 0..23
}
我假设Start-Move-Stop-Vibr数据可能被解释为一个布尔值,但它被编码为一个位字段半字节以节省空间。我唯一不知道的是我是否应该考虑开始是最不重要还是最重要的一点。F.e.:

0x 00 8…

此处的8表示开始-移动-停止振动数据,其中最高有效位为最高。但这是否意味着该消息属于启动类型,或者更确切地说是Vibr

我假设Start-Move-Stop-Vibr数据可能被解释为一个布尔值,但它被编码为一个位字段半字节以节省空间

相反,他们试图用一个位字段对某个二进制表示进行建模。这是高度特定于编译器的,因此类似这样的代码只能在特定的编译器上工作

我唯一不知道的是我是否应该考虑开始是最不重要还是最重要的一点< /P> 您无法知道,标准中没有指定最重要的位。此外,CPU(可能还有网络协议)的持久性可能在这里发挥作用

了解这一点的唯一方法是阅读特定的编译器文档


这就是为什么一般的结构,特别是位字段不适合映射原始二进制数据的原因。编写此代码的唯一可移植方法是使用原始
uint8\t
数组缓冲区,然后可以将其反序列化为各种变量。

C标准让实现决定如何将位字段打包到包含对象中。因此,将位字段放入消息定义中是不好的做法。相反,您应该使用
字节标志
,并使用逐位操作来提取位。参考设备制造商可能比猜测更可靠。或者,如果你看了不止一条信息,然后震动设备,看看它发送了什么。或者使用水晶球。您如何知道构成临时值的两个字节的顺序是小端还是大端?关键是,如果只给出这个结构定义,你就无法确定,比特域中的比特顺序也是如此。你可以直接问SigFox的人——看,跨编译域使用结构是一个非常糟糕的主意。一般来说,使用位字段同样糟糕,如果在编译域中使用结构的一部分,情况会更糟。你正在为自己创造工作、维护和麻烦。这是语言中一个你应该不惜一切代价避免的奇才特征。