用C解析和读取数据帧?
我正在编写一个从Linux上的串口读取数据的程序。 数据由另一台设备发送,帧格式如下:
|start | Command | Data | CRC | End |
|0x02 | 0x41 | (0-127 octets) | | 0x03|
----------------------------------------------------
数据字段包含 127 个八位位组,如图所示,八位位组 1,2 包含一种类型的数据;八位位组 3,4 包含另一个数据。我需要获取这些数据
我知道如何在 Linux 中的串行端口写入和读取数据,但这只是写入和读取一个简单的字符串(如“ABD”)
我的问题是我不知道如何解析如上所述格式化的数据帧,以便我可以:
- 获取数据字段中八位字节 1,2 中的数据
- 获取数据字段中八位字节 3,4 中的数据
- 获取 CRC 字段中的值以检查数据的一致性
这里在 Linux 中从串行端口读取和写入简单字符串的示例片段代码:
int writeport(int fd, char *chars) {
int len = strlen(chars);
chars[len] = 0x0d; // stick a <CR> after the command
chars[len+1] = 0x00; // terminate the string properly
int n = write(fd, chars, strlen(chars));
if (n < 0) {
fputs("write failed!\n", stderr);
return 0;
}
return 1;
}
int readport(int fd, char *result) {
int iIn = read(fd, result, 254);
result[iIn-1] = 0x00;
if (iIn < 0) {
if (errno == EAGAIN) {
printf("SERIAL EAGAIN ERROR\n");
return 0;
} else {
printf("SERIAL read error %d %s\n", errno, strerror(errno));
return 0;
}
}
return 1;
}
有人有一些想法吗?
I am writing a program that reads the data from the serial port on Linux.
The data are sent by another device with the following frame format:
|start | Command | Data | CRC | End |
|0x02 | 0x41 | (0-127 octets) | | 0x03|
----------------------------------------------------
The Data field contains 127 octets as shown and octet 1,2 contains one type of data; octet 3,4 contains another data. I need to get these data
I know how to write and read data to and from a serial port in Linux, but it is just to write and read a simple string (like "ABD")
My issue is that I do not know how to parse the data frame formatted as above so that I can:
- get the data in octet 1,2 in the Data field
- get the data in octet 3,4 in the Data field
- get the value in CRC field to check the consistency of the data
Here the sample snip code that read and write a simple string from and to a serial port in Linux:
int writeport(int fd, char *chars) {
int len = strlen(chars);
chars[len] = 0x0d; // stick a <CR> after the command
chars[len+1] = 0x00; // terminate the string properly
int n = write(fd, chars, strlen(chars));
if (n < 0) {
fputs("write failed!\n", stderr);
return 0;
}
return 1;
}
int readport(int fd, char *result) {
int iIn = read(fd, result, 254);
result[iIn-1] = 0x00;
if (iIn < 0) {
if (errno == EAGAIN) {
printf("SERIAL EAGAIN ERROR\n");
return 0;
} else {
printf("SERIAL read error %d %s\n", errno, strerror(errno));
return 0;
}
}
return 1;
}
Does anyone please have some ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
result
是一个char
数组,宽度为 1 个八位字节。读取八位位组n使用:
所以要做你想做的事情你需要:
编辑:这一行的解释:
你想将两个连续的八位位组读入一个16位字:
因此您想要获取八位字节 1 的位 7:0 并将它们放入 octet_1_2 的位 7:0:
然后您想要获取八位字节 2 的位 7:0 并将它们放入位 15: 8 个
octet_1_2
。您可以通过将八位字节 2 的 8 位向左移动,然后将结果“或”运算到octet_1_2
中来完成此操作:这两行可以合并为一行,就像我上面所做的那样。
result
is an array ofchar
s, which are 1 octet wide.to read octet n use:
So to do what you want you need:
Edit: An explanation for this line:
You want to read two consecutive octets into one 16-bit word:
So you want to take bits 7:0 of octet 1 and put them in bits 7:0 of
octet_1_2
:Then you want to take bits 7:0 of octet 2 and put them in bits 15:8 of
octet_1_2
. You do this by shifting octet 2 8 bits to the left, andOR
'ing the result intooctet_1_2
:These two lines can be merged into one as I did above.
在 C 中读取格式化数据的最好方法是读取结构。
鉴于您拥有的帧格式,我将执行以下操作。
这样您就可以通过结构字段访问所需的数据。第一个结构和联合只是访问帧数据字段中所需字节的帮助器。
The best thing to read formatted data in C is to read a structure.
Given the frame format you have I would do the following.
This way you may access the data you need through the structure fields. The first structure and the union are just helpers to access the bytes you need in the data field of the frame.