2

我目前正在重写一个程序来处理使用RDM 协议通过串行连接接收到的数据,每个数据包都由 UART 接收,并且具有特定的结构,但长度可能会有所不同,下面是一个数据包结构示例,假设数据包中的字节数为n(这可能会根据数据包的内容而改变)

我想要做的是在我的 C 代码中定义一个结构,该结构定义了各种参数,但能够从 UART 读取和写入结构的字节,就好像结构只是 uint8_t 的数组一样。我的问题是我已经读过结构可能并不总是存储在连续的内存部分中,因此&RDMPacket1通过结构获取和递增可能最终导致数据不在正确的位置。

我的另一个问题是,如果我有一个数组来存储结构内最大可能长度(220 字节)的数据包数据,那么数据包末尾的校验和将被写入错误的位置。可以使用哪些方法来接收数据并将其放入结构中?

示例数据包定义(从标准缩短)

Byte     | Description
0        | START Code - Constant, can be ignored
1        | Sub-Start Code - Contains command for device to process
2        | Message Length - Points to byte number of Checksum High (up to 255)
3-8      | Destination UID - Unique ID of packet Destination
9-14     | Source UID - Unique ID of packet Source
15       | Transaction Number - ID of transaction between controller and responder
16-(n-2) | Data (up to 220 bytes long)
n-1      | Checksum High
n        | Checksum Low

这是一个保存最大可能长度的数据包的结构示例:

struct RDMPacket
{
    uint8_t     subStartCode;
    uint8_t     messageLength;
    uint32_t    destinationUID;
    uint32_t    sourceUID;
    uint8_t     transactionNumber;
    uint8_t     portID;
    uint8_t     messageCount;
    uint8_t     subDevice;
    uint8_t     commandClass
    uint8_t     parameterID;
    uint8_t     parameterDataLength;
    uint8_t     parameterData[220];
    uint16_t    checksum
} RDMPacket1;
4

1 回答 1

4

当您处理非字节对齐的内存结构时,可能会出现您所描述的问题。在这种情况下,每个结构字段都将具有特定的对齐方式。即,如果对齐是 4 个字节,则每个字段将从可被 4 整除的地址开始。为避免这种情况,您可以使用 GCC 的packed结构属性,它指示编译器将结构打包到最小内存。在其他编译器中,有#pragma pack或一些其他相应的编译器指令用于此目的。为确保您的结构已打包,您可以检查它的大小sizeof并将其与预期大小进行比较。

于 2015-01-21T15:18:53.280 回答