You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下UART阻塞read()异常:读取自发送数据或垃圾字符求助

搞定串口阻塞读取异常与垃圾字符问题

兄弟,你的串口代码有几个关键问题导致了现在的异常,咱们一步步拆解修复:

核心问题分析

  1. tcflush清空了关键数据:你在uart_read里调用tcflush(fd, TCIOFLUSH),这会直接清空所有未读取的输入数据和待发的输出数据——相当于你发完握手信息后,还没等接收就把数据全清了,自然读不到正确内容,甚至读超时后拿到垃圾值。
  2. VTIME配置让阻塞变成了"限时等待":你设置了port_settings.c_cc[VTIME] = 10,这个参数的单位是0.1秒,也就是read会等1秒,哪怕没收到足够数据也会返回,这不是你要的完全阻塞。
  3. 无视read返回的实际字节数:你不管read到底读了多少字节,直接用buffer_size构造字符串,这会把buf里没被覆盖的垃圾内存也塞进字符串里,导致乱码。
  4. main函数调用参数缺失:你的uart_read需要传buffer_size,但main里只传了指针,这会导致buffer_size是随机垃圾值,轻则读错长度,重则内存越界。

一步步修复代码

1. 调整串口配置,实现真正的阻塞读取

在configure_port函数里,把c_cc的VMIN和VTIME改成完全阻塞模式:

// 完全阻塞:直到收到至少1个字节才返回(适合不定长数据)
port_settings.c_cc[VMIN] = 1;  // 最小读取1字节
port_settings.c_cc[VTIME] = 0; // 无超时,一直等数据

如果你的场景是要读固定长度的数据(比如必须读满N字节才返回),可以把VMIN设为对应长度,VTIME保持0即可。

2. 重构uart_read函数,去掉多余操作并正确处理读取结果

删掉没用的usleep和tcflush,并且用read返回的实际字节数构造字符串:

int UART::uart_read(string *data, int buffer_size) {
    char * buf = new char[buffer_size + 1]; // 多留一位存结束符
    
    // 真正的阻塞读取
    int n = read(fd, buf, buffer_size);
    
    // 错误处理
    if (n < 0) {
        cout << "Error reading: " << strerror(errno) << endl;
        delete[] buf;
        return 0;
    }
    
    // 给字符串加结束符,用实际读取的字节数构造有效字符串
    buf[n] = '\0';
    string data_received(buf, n);
    *data = data_received;
    
    delete[] buf;
    cout << "data_received: " << *data << endl;
    
    return n > 0 ? 1 : 0;
}

3. 修正main函数的调用参数

调用uart_read时必须传入合理的buffer_size,比如32字节:

int main() {
    UART uart_connection;
    string handshake = "handshake!";
    uart_connection.uart_write(handshake);
    
    string data;
    // 传入缓冲区大小,根据你的需求调整
    uart_connection.uart_read(&data, 32);
    
    cout << "Final received data: " << data << endl;
}

4. 优化open_port的参数(可选但更清晰)

你现在open时用了O_NDELAY然后又用fcntl去掉,不如直接去掉O_NDELAY,代码更直观:

fd = open("/dev/ttyS4", O_RDWR | O_NOCTTY);

额外硬件&场景提示

  • 如果RX没接设备还读到垃圾字符,大概率是RX引脚悬空导致的电平噪声,硬件上可以给RX加个上拉电阻,或者软件里开启奇偶校验来过滤噪声。
  • 发送大段数据时,建议做循环读取(比如每次读一部分,直到收完预期长度或遇到协议结束符),避免单次read截断数据。

内容的提问来源于stack exchange,提问作者Luis Cruz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:09:46