在 C 中解析和读取数据帧? [英] Parse and read data frame in C?

查看:14
本文介绍了在 C 中解析和读取数据帧?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个从 Linux 上的串口读取数据的程序.数据由其他设备发送,帧格式如下:

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|
----------------------------------------------------

Data 字段包含 127 个八位字节,如图所示,八位字节 1,2 包含一种类型的数据;八位字节 3,4 包含另一个数据.我需要获取这些数据

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

我知道如何在 Linux 中向串行端口写入和读取数据,但它只是写入和读取一个简单的字符串(如ABD")

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:

  • 在数据字段中获取 octet 1,2 中的数据
  • 在数据字段中获取 octet 3,4 中的数据
  • 获取 CRC 字段中的值以检查数据的一致性

这里是在 Linux 中从串行端口读取和写入简单字符串的示例片段代码:

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!
", 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
");
            return 0;
        } else {
            printf("SERIAL read error %d %s
", errno, strerror(errno));
            return 0;
        }
    }                    
    return 1;
}

请问有人有什么想法吗?

Does anyone please have some ideas?

推荐答案

result 是一个 char 数组,其宽度为 1 个八位字节.

result is an array of chars, which are 1 octet wide.

读取八位字节n使用:

char octet_n = result[n];

所以要做你想做的事:

// skip the start and command fields
char *data_field = result + 2; 

int octet_1_2 = data_field[1] | (data_field[2] << 8);
int octet_3_4 = data_field[3] | (data_field[4] << 8);

// crc is at byte 128 + 2 = 130
int crc = result[130];

编辑:对这一行的解释:

int octet_1_2 = data_field[1] | (data_field[2] << 8);

您想将两个连续的八位字节读入一个 16 位字:

You want to read two consecutive octets into one 16-bit word:

            1
       bits 5        8 7       0
            --------------------
octet_1_2 = | octet 2 | octet 1|
            --------------------

所以你想取八位字节 1 的 7:0 位并将它们放入 octet_1_2 的位 7:0 中:

So you want to take bits 7:0 of octet 1 and put them in bits 7:0 of octet_1_2:

octet_1_2 = data_field[1];

然后你想取出八位字节 2 的位 7:0 并将它们放入 octet_1_2 的位 15:8.为此,您可以将八位字节 2 向左移动 8 位,然后将结果 OR'ing 到 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, and OR'ing the result into octet_1_2:

octet_1_2 |= data_field[2] << 8;

这两行可以像我上面那样合并成一条.

These two lines can be merged into one as I did above.

这篇关于在 C 中解析和读取数据帧?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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