You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Expect TCL发送高值数据自动转为Unicode的问题求助

Expect v5.45 (macOS) 发送二进制数据自动转码问题的解决方法

问题背景

在macOS上使用Expect v5.45操作串口时,所有值大于0x7F的字节会被自动转为UTF-8编码发送(例如0xDB被转为0xC3 0x9B),额外的字节导致接收端异常。即使对串口通道设置了-encoding binary -translation binary,问题依然存在;但改用TCL原生的puts -nonewline命令发送则完全正常。

问题复现代码

set portID [open $serial_dev r+]
fconfigure $portID -mode "9600,n,8,1"
fconfigure $portID -handshake "rtscts"
fconfigure $portID -encoding binary -translation binary

spawn -open $portID
set send_slow {1 .5}

send -s -raw -- [binary format H* DB20DC20DD20100A]

调试信息确认

Expect调试输出显示send命令将二进制数据解析为Unicode字符后发送:

send: sending "\u00db \u00dc \u00dd \u0010\n" to { exp7 }

回环测试收到的转码后数据:

00000000: c3 9b 20 c3 9c 20 c3 9d  .. .. ..
00000008: 20 10 0a 0a 0a            ....

临时解决方案(使用puts)

直接用TCL的puts命令发送二进制数据可以绕过Expect的转码逻辑:

puts -nonewline $portID [binary format H* DB20DC20DD20100A]

该方式能发送正确的原始字节:

00000000: db 20 dc 20 dd 20 10 0a  . . . ..

针对send命令的核心解决方法

问题根源在于spawn -open创建的Expect通道并未继承原串口通道的二进制配置,需要在spawn后重新配置该通道:

set portID [open $serial_dev r+]
fconfigure $portID -mode "9600,n,8,1"
fconfigure $portID -handshake "rtscts"
fconfigure $portID -encoding binary -translation binary

spawn -open $portID
# 关键:配置spawn生成的Expect通道为二进制模式
fconfigure $spawn_id -encoding binary -translation binary

set send_slow {1 .5}
send -s -raw -- [binary format H* DB20DC20DD20100A]

原理说明

  • spawn -open会基于原通道创建一个新的Expect内部通道,默认可能使用系统编码(UTF-8)处理数据
  • 显式对$spawn_id设置-encoding binary-translation binary,强制Expect将数据作为原始字节流发送,避免自动转码
  • 配合send -raw参数,确保数据不被Expect进行任何额外处理

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

火山引擎 最新活动