【发布时间】:2018-04-06 23:59:29
【问题描述】:
我目前正在处理一个基于 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 数据可能应该被解释为布尔值,但它被编码为位域半字节以节省空间。我唯一不知道的是我是否应该考虑 start 是最不重要的位还是最重要的位。 F.e:
0x 00 8 ...
这里的 8 代表 Start-Move-Stop-Vibr 数据,其中最高有效位最高。但这是否意味着消息是 Start 类型或 Vibr?
【问题讨论】:
-
C 标准由实现决定如何将位域打包到包含对象中。因此,将位域放入消息定义中是不好的做法。相反,您应该有一个
byte Flags,并使用按位运算来提取位。 -
参考设备制造商可能比猜测更可靠。或者,如果绝望地查看多条消息,则振动设备并查看它发送的内容。或者使用水晶球。
-
如何知道构成 Temp 值的两个字节是小端还是大端?关键是你不能确定只给定这个结构定义,位域中位的顺序也是如此。
-
你可以直接问 SigFox 的人——见build.sigfox.com/steps/technical-quickstart#get-started-links
-
跨编译域使用结构是一个非常非常糟糕的主意。一般来说,使用位域同样糟糕,如果在编译域中使用结构的一部分,情况会更糟。您正在为自己创造工作和维护以及令人头疼的问题。这是您应该不惜一切代价避免使用的语言的一个酥油高手功能。
标签: c embedded iot bit-fields