linux串口接收数据不完整拆包情况解决方案

在Linux环境下进行串口通信时,遇到大于8字节数据接收被自动拆包的问题。通过分析,发现当检测到串口有数据时立即读取,可能导致数据不完整。解决方案是在select()调用后加入微秒级别延时,确保数据完整接收。这种方法有效防止了因快速响应数据信号而引发的数据拆包现象。

转自:
https://www.it610.com/article/1297660084041621504.htm

去年在使用linux串口的时候,出现大于8个字节数据接收时自动拆成每个包8个字节的情况,当时处理方案是判断串口的首位字符判断接收完成。后来在使用qt做串口时收到启发,如果刚接收到串口有数据的信号量时,立即触发槽函数,就会出现数据不完整情况,原因是程序一检测到缓存区有数据便触发信号量,此时立刻读缓存区,数据还没有接收完,就会出现拆包情况。
解决方案很简单,在select()后面加上一点延时即可。

void uart_recv(int fd)
{
    char data[1024];
    int len=0, ret = 0;
    fd_set fs_read;
    struct timeval tv_timeout;

    FD_ZERO(&fs_read);
    FD_SET(fd, &fs_read);
    tv_timeout.tv_sec  = 6000;//(10*20/115200+2);
    tv_timeout.tv_usec = 0;

    while (1)
    {
        ret = select(fd+1, &fs_read, NULL, NULL, &tv_timeout);
        usleep(10000);
        printf("ret = %d\n", ret);
        if (FD_ISSET(fd, &fs_read)) {
            memset(data,0,sizeof(data));
            len = read(fd, data, sizeof(data));
            printf("len: %d(bytes) recv: %s\n", len, data);
        } else {
            perror("select");
        }
    }
}

转自:
https://www.it610.com/article/1297660084041621504.htm

### 树莓派无法接收串口数据的原因分析 对于树莓派3及其后续版本,存在两个串口:硬件串口(PL011 UART)和迷你串口(mini-UART)。在树莓派3的设计中,硬件串口被分配给了蓝牙模块,而迷你串口则用于GPIO接口上的UART通信。由于迷你串口依赖于内核提供的时钟源,这可能导致波特率稳定,从而影响到正常的串口通信功能[^2]。 ### 解决方案概述 为了使树莓派能够稳定地通过GPIO引脚进行串口通信,建议采取以下措施: #### 关闭蓝牙服务并切换串口配置 可以通过修改`/boot/config.txt`文件来禁用蓝牙对硬件串口的占用,并将该资源释放给GPIO端子使用。具体操作如下所示: 编辑配置文件: ```bash sudo nano /boot/config.txt ``` 添加或确保已存在下列行以启用经典UART模式而连接至蓝牙: ```ini enable_uart=1 dtoverlay=pi3-disable-bt ``` 重启设备让更改生效: ```bash sudo reboot ``` #### 配置串口号映射关系 完成上述设置之后,还需要确认Linux系统的TTY设备名称是否指向正确的物理串口路径。通常情况下,默认会自动识别为`/dev/ttyS0`(针对miniuart) 或者 `/dev/ttyAMA0`(对应pl011 uart)。 如果发现仍然存在问题,则可能是因为应用程序层面未正确指定目标串口节点所致;此时应当检查程序代码里关于打开串口部分所使用的参数设定。 #### 调整应用层逻辑处理机制 当遇到接收的数据完整或是出现拆包现象的时候,可能是由于读取缓冲区大小合适造成的。对此可以在编写软件时增加超时判断以及循环读取直至接收到预期长度的消息为止。另外一种方式是在发送方加入特殊的帧头尾标记以便接收方可据此解析完整的报文内容[^3]。 ```python import serial ser = serial.Serial('/dev/ttyS0', baudrate=9600, timeout=1) while True: data = ser.readline().decode('utf-8').strip() if data != '': print(f'Received message: {data}') ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值