访问结构作为字节数组 [英] Access struct as array of bytes

查看:77
本文介绍了访问结构作为字节数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在重新编写程序,以处理使用 RDM协议,每个数据包均由UART接收,并具有特定的结构,但是长度可能会有所不同,下面的数据包结构示例假定数据包中的字节数为n(这可能会根据数据包的内容而变化)

I'm currently in the process of re-writing a program to process data received over a serial connection using the RDM protocol, each packet is received by a UART and has a specific structure but may vary in length, a packet structure example is below, assuming the number of bytes in the packet to be n (this may change depending on the contents of the packet)

我想做的是在我的C代码中定义一个结构,该结构定义了各种参数,但是要能够从UART读写结构中的字节,就像该结构只是uint8_t的数组一样。我的问题是,我已阅读到结构可能并不总是存储在连续的内存部分中,因此采用& RDMPacket1 并遍历该结构可能最终会导致数据不在正确的位置。

What I want to do is define a struct in my C code that has the various parameters defined, but to be able to read and write bytes to/from the struct from the UART as though the struct is just an array of uint8_t. My issue with this is that I have read that structs may not always be stored in continuous sections of memory, so taking &RDMPacket1 and increment through the struct may end up with the data not being in the right place.

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

My other problem is that if I have an array to store a packet data of the maximum possible length (220 bytes) inside the struct, then the checksum at the end of the packet would be written into the wrong place. What methods could be used to receive the data and place it into the struct?

示例数据包定义(从标准简化)

Example packet definition (shortened from standard)

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

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

This is an example of a struct to hold the a packet of maximum possible length:

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个字节,则每个字段都将从一个可被4整除的地址开始。为避免这种情况,您可以对结构使用GCC的属性 packed ,指示编译器将结构压缩到最小内存。在其他编译器中,有 #pragma pack 或用于此目的的其他一些相应的编译器指令。为确保您的结构已打包,您可以使用 sizeof 检查结构的大小,并将其与期望的大小进行比较。

The problem that you are describing can arise when you are dealing with a non-byte aligned memory structure. In this case each struct field will have the specific alignment. I.e., if the alignment is 4 bytes, each field will start on an address that is divisible by 4. To avoid this, you can use GCC's attribute packed for the structure, that instructs the compiler to pack the structure to a minimal memory. In other compilers there is #pragma pack or some other corresponding compiler directives for this purpose. To make sure that your struct is packed, you can check it's size with sizeof and compare it to the expected size.

这篇关于访问结构作为字节数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆