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

Linux下USB对接GSM模块写入正常 中断读取数据不稳定排查

Linux下USB转GSM模块串口读取异常排查

你的代码存在语法错误、串口配置错误、异步IO逻辑错误三类核心问题,是读取时好时坏的根本原因,逐点说明:

一、编译级语法错误

  • open调用存在语法拼接错误:原代码fd=open("/dev/ttyUSB1",O_RDWR|O_NDELAY|O_NOCTTY|O_APPEND,S_IRWXU|S_IRWXG|S_IRWXO);|O_NOCTTY|O_SYNC|O_NDELAY); 多了半截无效flag和括号,打开已存在的tty设备不需要传入文件权限位,多余参数会导致open行为异常。
  • 信号处理函数内static int gsm_count缺少行尾分号,且该变量从未做增量更新、边界校验,定义后无实际作用,还会引发内存越界风险。
  • main函数内int init_ttyusb0(B9600,0)为函数调用,多余前缀int且缺少行尾分号,会直接引发编译失败。
  • 信号处理函数内fcntl(fd,F_SETFL,!(O_ASYNC));逻辑完全错误:O_ASYNC为非零宏,!O_ASYNC固定返回0,该行执行后会清空所有文件状态标志,直接导致后续异步通知失效。

二、串口termios配置错误

  • 配置位归属写错:ICANON、ISIG、ECHO*属于本地模式标志c_lflag,IXON/IXOFF/IXANY属于输入模式标志c_iflag,代码中误将这些位写到c_cflag、重复写到c_lflag,导致规范模式关闭、流控关闭的配置完全不生效,串口会按默认规则按换行切分数据,和GSM模块返回格式不匹配时就会读不到数据。
  • VMIN/VTIME配置和异步IO冲突:当前设置VMIN=0, VTIME=10代表读操作最长等待1秒就返回,哪怕没有数据也会返回空值,极易出现数据未到达就触发空读,后续数据到达时无信号触发的问题。
  • 初始化时未清空termios结构体、未清空串口缓冲区:结构体残留的随机配置、设备打开时残留的历史数据,都会随机干扰正常读写。
  • 多余标志干扰:打开设备时传入的O_APPEND标志对字符设备无意义,会随机影响读写偏移。

三、异步IO(中断式读取)逻辑错误

  • sigaction配置不完整:未初始化信号掩码sa_mask、未设置SA_RESTART标志,会导致信号触发时随机打断scanf、usleep等系统调用,程序流程错乱;未屏蔽信号嵌套会引发重入问题。
  • O_ASYNC开关逻辑完全错误:代码每次写完AT指令、固定sleep一段时间后才开启O_ASYNC,但GSM模块返回响应的时间不固定,若模块在开启O_ASYNC前就返回数据,不会触发SIGIO信号,直接读不到数据;信号处理函数中错误关闭O_ASYNC后,若模块返回数据分多段传输,后续数据段不会触发信号,直接丢失。
  • 信号处理函数逻辑违规:printf、memset、fcntl都不是异步信号安全函数,不能在信号处理函数中调用;read调用未判断返回值,直接按字符串打印会因为缺少结束符引发乱码、内存越界;读完立即清空缓冲区,主逻辑无法获取有效返回数据。

四、业务逻辑错误

  • 写AT指令后靠固定usleep等响应不可靠:不同AT指令响应时间差异极大,比如AT+CFUN=1需要数秒才能完成模块初始化,固定延时要么太短漏数据,要么太长阻塞流程。
  • case 2分支逻辑矛盾:代码中strcpy写入的是AT+CCID\r,实际write发送的是AT+CPIN?\r,指令和预期不匹配。

修复要点

  • 修正open调用:fd = open("/dev/ttyUSB1", O_RDWR | O_NOCTTY | O_NDELAY);,去掉多余标志和无效参数。
  • 修正termios配置:初始化时先清空结构体,将所有配置位写到对应flag字段,配置完成后调用tcflush(fd, TCIOFLUSH)清空收发缓冲区;设置VMIN=1, VTIME=0,让读操作至少读到1字节再返回。
  • 修正异步IO逻辑:串口初始化完成后就开启O_ASYNC,不要每次发指令后重复开启,也不要在信号处理函数中关闭O_ASYNC;配置sigaction时先清空sa_mask,加上SA_RESTART标志避免系统调用被打断。
  • 信号处理函数仅做最小操作:只执行read将数据追加到全局环形缓冲区,设置数据就绪标志,所有打印、解析、逻辑处理放到主循环中完成,不要在信号处理函数中调用非异步安全函数。
  • 去掉所有固定延时等响应的逻辑,完全靠信号触发的读操作接收模块返回数据,所有系统调用都要校验返回值,处理EINTR、EAGAIN等临时错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 23:21:41