我目前正在尝试找到将包含char *的struct转换为char数组以传输串行数据帧的最简单方法。
struct存储帧头,校验和,msg大小等以及要传输的数据。例如
struct {
unsigned char header;
unsigned char msgSizeL;
unsigned char msgSizeH;
unsigned char *data;
unsigned char checksum;
....
....
....
....
unsinged char endFrame;
} Frame;
数据是指针,因为每帧传输的数据量可以在1到16个字节的范围内变化。
我试图找到将结构转换为无符号字符数组的最简单方法,而不将结构中的每个条目复制到数组中,但似乎无法找到方法。
或者我不必使用结构,因为我生成的框架内容从头开始排除数据内容,我只是想避免一个案例 -
unsigned char frame[1000];
frame[0] = 0x01; // header
frame[1] = msgSizeL; // msg size low byte
frame[2] = msgSizeH; // msg size high byte
frame[3] = data[0]; // data contents 0 Over simplification
frame[4] = data[1]; // data contents 1 for data copying -
frame[5] = data[2]; // data contents 2 data length is variable.
frame[6] = data[3]; // data contents 3
frame[7] = data[4]; // data contents 4
frame[8] = data[5]; // data contents 5
frame[9] = data[6]; // data contents 6
frame[10] = data[7]; // data contents 7
frame[3 + msgSize]; = getChecksum(data);
....
....
....
....
frame [3 + msgSize + 20] = 0xFF; // end frame
我将数据写入读取为随机数组索引的内容,而不是像frame.checksum = getChecksum(data);
那样有意义的内容。
对于提出一般性问题而非具体问题,可以提出建议和一点点火焰: - )
答案 0 :(得分:0)
我试图找到将结构转换为无符号字符数组的最简单方法,而不将结构中的每个条目复制到数组中,但似乎无法找到方法。
如果data
最多包含16个字节,我只需将其声明为16-char数组,如下所示:
#define MAX_DATA_LEN 16
struct {
unsigned char header;
unsigned char msgSizeL;
unsigned char msgSizeH;
unsigned char data[MAX_DATA_LEN]; // 16-char array instead of pointer
unsigned char checksum;
....
....
....
....
unsinged char endFrame;
} Frame;
如果这样做,那么这个结构中的所有数据都有一个预定义的大小(即unsigned char * sizeof(unsigned char)
的数量,依此类推其他数据类型......)你可以使用简单的{{1将结构复制到数组:
memcpy
答案 1 :(得分:0)
您有两种选择:
<强> 1。动态帧长
struct {
unsigned char header;
unsigned char msgSizeL; // this will be dynamic from 0x06 (empty) to 0x16 (full)
unsigned char msgSizeH; // this will be always 0x00
unsigned char dataSize; // specify the data size here
unsigned char data[16]; // use a static memory area for the package
unsigned char checksum;
unsigned char endFrame;
} Frame;
然后你可以这样做:
Frame xFrame;
unsigned char ucaData[17] = {0}; // your data
unsigned int uiDataLength = 6; // for example
memset(&xFrame, 0, sizeof(Frame)); // just to be sure
xFrame.header = 0x01;
xFrame.msgSizeL = uiDataLength;
xFrame.msgSizeH = 0;
xFrame.dataSize = uiDataLength;
memcpy(xFrame.data, ucaData, uiDataLength);
xFrame.checksum = CRC8(&xFrame, uiDataLength + 4); // crc for filled area
xFrame.endFrame = 0xFF;
然后在构建包时:
unsigned char xDataFrame[1000];
memcpy(xDataFrame, xFrame, 4 + uiDataLength);
memcpy(xDataFrame + 4 + uiDataLength, &xFrame + 20, 2);
transmit(xDataFrame, 6 + uiDataLength);
这样,您将丢弃发送和计算校验和的空字节。
<强> 2。静态帧长
然后你可以使用这样的结构:
struct {
unsigned char header;
unsigned char msgSizeL; // this will be always 0x16 (22)
unsigned char msgSizeH; // this will be always 0x00
unsigned char dataSize; // specify the data size here
unsigned char data[16]; // use a static memory area for the package
unsigned char checksum;
unsigned char endFrame;
} Frame;
通过这种方式,您可以计算此结构的前20个字节的校验和,但请注意,此结构可能包含填充区域,这些填充区域可能会在定义的和填充的内存区域周围移动数据。 sizeof(Frame)
可以手动计算为22个字节,但编译器可以决定它应该使用与pack
设置相关的32个字节或24个字节的内存。你可以使用
#pragma pack(1) // disable padding
[structure code]
#pragma pack() // back to the original setting
有关包装的更多信息: