0

我必须为以下数据包头编写 C++ 代码:

原始图片链接,上述JPEG的PNG版本。

这是我为上述数据包格式编写的结构代码。我想知道 uint8_t 或 uint16_t 位字段是否正确

    struct TelemetryTransferFramePrimaryHeader
    {
        //-- 6 Ocets Long --//

        //-- Master Channel ID (2 octets)--//
        uint16_t TransferFrameVersionNumber : 2;
        uint16_t SpacecraftID : 10;
        uint16_t VirtualChannelID : 3;
        uint16_t OCFFlag : 1;

        //-----------------//

        uint8_t MasterChannelFrameCount;
        uint8_t VirtualChannelFrameCount;

        //-- Transfer Frame Data Field Status (2 octets) --//

        uint16_t TransferFrameSecondaryHeaderFlag : 1;
        uint16_t SyncFlag : 1;
        uint16_t PacketOrderFlag : 1;
        uint16_t SegmentLengthID : 2;
        uint16_t FirstHeaderPointer : 11;

        //-----------------//

    };

如何确保 LSB -> MSB 保留在 struct 中?

我一直感到困惑,我已经尝试阅读,但它最终让我更加困惑。

PS:我使用的是 32 位处理器。

4

3 回答 3

5

使用位字段时位的确切映射方式是特定于实现的。所以很难确定你是否做对了,我们需要知道确切的 CPU 和编译器(当然还有编译器版本)。

简而言之; 不要这样做。位域对于这样的事情不是很有用。

通过根据需要声明单词并设置其中的位来手动执行此操作。

于 2014-07-11T12:52:15.393 回答
2

恕我直言,任何试图以struct这种方式构建 a 的人都处于犯罪状态。

例如,C99 标准说:

实现可以分配任何大到足以容纳位域的可寻址存储单元。如果有足够的空间剩余,紧跟在结构中另一个位域之后的位域将被打包到同一单元的相邻位中。如果剩余空间不足,则将不适合的位域放入下一个单元还是与相邻单元重叠是实现定义的。单元内位域的分配顺序(高位到低位或低位到高位)是实现定义的。未指定可寻址存储单元的对齐方式。

即使您可以预测您的编译器将以(例如)uint32_t 为单位构造位字段,并且这些字段被安排在第一个字段 LS 位......您仍然需要处理字节序!

所以...正如 unwind 所说...手工操作!

于 2014-07-11T13:01:15.503 回答
1

我同意你不应该这样做。然而,意法半导体使用位域来访问其 Cortex-M3/M4 微控制器寄存器的位。因此,任何希望其用户能够使用 STMicroelectronics Cortex-M3/M4 库的编译器供应商都需要支持从最低有效位开始的位域分配。在我的编译器中,这是默认设置,但它也是可选的,因此如果我愿意,我可以将其反转。

于 2014-07-11T15:30:10.753 回答