c++ - 解析来自串口的完整消息

标签 c++ gps serial-port uart

我正在尝试通过串行端口从我的 GPS 读取完整的消息。

我要查找的消息开头为:

0xB5 0x62 0x02 0x13

于是我就这样从串口读取

while (running !=0)
{

int n = read (fd, input_buffer, sizeof input_buffer); 


for (int i=0; i<BUFFER_SIZE; i++)
{   



if (input_buffer[i]==0xB5  && input_buffer[i+1]== 0x62 && input_buffer[i+2]== 0x02 && input_buffer[i+3]== 0x13    && i<(BUFFER_SIZE-1) )
     { 

            // process the message.
     }

}

我遇到的问题是我需要获得完整的消息。一条消息的一半可能在一次迭代中位于缓冲区中。另一半可能会在下一次迭代中出现。

有人建议从完整消息中释放缓冲区。然后我将缓冲区中的其余数据移动到缓冲区的开头。

我该怎么做或以其他方式确保我收到每条完整的选定消息?

编辑// enter image description here

我想要一个特定的类和 ID。但我也能读懂长度

最佳答案

为了最小化进行许多小字节计数的 read() 系统调用的开销,请在代码中使用中间缓冲区。
read() 应该处于阻塞模式以避免返回零字节代码。

#define BLEN    1024
unsigned char rbuf[BLEN];
unsigned char *rp = &rbuf[BLEN];
int bufcnt = 0;

static unsigned char getbyte(void)
{
    if ((rp - rbuf) >= bufcnt) {
        /* buffer needs refill */
        bufcnt = read(fd, rbuf, BLEN);
        if (bufcnt <= 0) {
            /* report error, then abort */
        }
        rp = rbuf;
    }
    return *rp++;
}

有关串行终端的正确 termios 初始化代码,请参阅 this answer .您应该将 VMIN 参数增加到更接近 BLEN 值的值。

现在您可以一次一个字节方便地访问接收到的数据,而性能损失最小。

#define MLEN    1024  /* choose appropriate value for message protocol */
unsigned char mesg[MLEN];

while (1) {
    while (getbyte() != 0xB5)
        /* hunt for 1st sync */ ;
retry_sync:
    if ((sync = getbyte()) != 0x62) {
        if (sync == 0xB5)
            goto retry_sync;
        else    
            continue;    /* restart sync hunt */
    }

    class = getbyte();
    id = getbyte();

    length = getbyte();
    length += getbyte() << 8;

    if (length > MLEN) {
        /* report error, then restart sync hunt */
        continue;
    }
    for (i = 0; i < length; i++) {
        mesg[i] = getbyte();
        /* accumulate checksum */
    }

    chka = getbyte();
    chkb = getbyte();
    if ( /* valid checksum */ ) 
        break;    /* verified message */

    /* report error, and restart sync hunt */
}

/* process the message */
switch (class) {
case 0x02:
    if (id == 0x13) {
        ... 
...

关于c++ - 解析来自串口的完整消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43280740/

相关文章:

c++ - 从输入文件中读取并存储在数组 C++ 中

安卓谷歌播放服务 : Best practices to make location request

c - Linux串口-wrtie()字节通过串口到目标设备

python - 从python控制rs232 windows终端程序

c++ - 神秘的内存泄漏

C++ 程序崩溃且没有错误

.net - .NET 紧凑框架的 GPS 库

c - 如何通过带有 c 的串行端口从带有 NMEA 协议(protocol)的 GPS 模块获取数据

matlab - Arduino Matlab串口通讯速度

c++ - 未知类型的可变参数构造函数参数列表