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

Ubuntu下stty配置串口输出的正确方式及数据偏移问题排查

Ubuntu下向Silicon Labs BMG220p发送二进制串口数据的问题解决

问题背景

  • 设备:Silicon Labs BMG220p微控制器,USB连接Ubuntu后识别为/dev/ttyACM0
  • 需求:通过bash脚本发送固定32字节的二进制数据
  • 异常:首次运行脚本时设备能收到正确的32字节数据,后续每次执行都会出现数据偏移3字节的情况,推测是串口驱动对二进制数据添加了控制字符处理
  • 当前使用的脚本:
#! /usr/bin/bash

while getopts p: flag
do
        echo -n "$flag: "
        case ${flag} in
                p) ttyPort=${OPTARG}
                   echo "Use tty $ttyPort";;;
        esac
done

printf "%b" "\x02\x11\x22\x33\x44\x0Akaefer\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x07\x03\x04" > $ttyPort
  • 当前stty -F /dev/ttyACM0输出:
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>;
start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel
-iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho
-extproc

解决方案

一、修正串口配置(stty)

问题根源在于当前串口处于规范模式(icanon)并启用了软件流控(ixon),驱动会对二进制数据做特殊字符解析和缓存处理。需要将串口切换为原始模式,禁用所有不必要的处理逻辑:

在脚本发送数据前添加以下配置命令:

stty -F $ttyPort raw -echo -ixoff -ixon -icanon isig min 0 time 0

各参数作用:

  • raw:禁用所有输入输出的转义、翻译处理,直接传递原始二进制数据
  • -echo:禁止回显发送的数据,避免干扰设备接收
  • -ixoff -ixon:禁用XON/XOFF软件流控,防止驱动将\x11、\x13这类二进制字符当成流控命令
  • -icanon:关闭规范模式,禁用行缓存和特殊字符(如回车、EOF)的解析
  • min 0 time 0:设置无最小字符数要求和超时,确保数据立即发送

修改后的完整脚本:

#! /usr/bin/bash

while getopts p: flag
do
        echo -n "$flag: "
        case ${flag} in
                p) ttyPort=${OPTARG}
                   echo "Use tty $ttyPort";;;
        esac
done

# 配置串口为原始模式,禁用所有不必要的处理
stty -F $ttyPort raw -echo -ixoff -ixon -icanon isig min 0 time 0

# 发送二进制数据
printf "%b" "\x02\x11\x22\x33\x44\x0Akaefer\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x07\x03\x04" > $ttyPort

二、使用screen发送二进制数据的方法

如果需要用screen工具在脚本中发送二进制数据,可按以下步骤操作:

  1. 提前生成包含目标二进制数据的文件:
printf "%b" "\x02\x11\x22\x33\x44\x0Akaefer\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x07\x03\x04" > binary_data.bin
  1. 在脚本中通过screen后台发送数据:
# 后台启动screen串口会话,配置为原始模式
screen -S serial_send -d -m $ttyPort 9600,raw,-echo,-ixoff,-ixon
sleep 0.5  # 等待会话连接稳定
# 向会话发送命令,发送二进制文件内容
screen -S serial_send -X exec !! cat binary_data.bin
sleep 0.1  # 等待数据发送完成
# 关闭screen会话
screen -S serial_send -X quit

内容的提问来源于stack exchange,提问作者T.Krastev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 11:46:07