如何使用expect脚本根据硬件返回值执行条件判断逻辑
Expect脚本问题修正
你的原脚本存在语法、逻辑、命令拼写三类错误,无法按预期执行,核心问题如下:
- 语法规则错误:Expect的
expect多分支匹配块内不能直接嵌套while/if/elseif控制流语法,该块内仅支持匹配规则 {对应执行动作}的格式,原写法把控制流关键字当匹配模式,解释器会直接报错 - 命令拼写错误:Expect输出命令为
puts,原代码写为put;回车转义符为\r,原代码写为/r - 逻辑漏洞:FPGA忙状态轮询逻辑位置错误,会导致匹配失效;串口打开后未配置波特率、数据位等参数,大概率出现乱码;未设置超时兜底,设备无响应时脚本会永久挂起;i2c_read命令中的
0xh0为无效十六进制参数,属于笔误;串口设备名ttys1小写s不符合Linux系统命名规则,正确应为ttyS1 - 匹配逻辑漏洞:原代码未在读取i2c返回值时匹配barebox提示符,无法准确截取有效返回字段
修正后可直接运行的脚本如下(请根据实际硬件参数调整波特率、I2C命令参数):
#! /bin/expect set timeout 5 # 打开并配置串口 set serial_port [open /dev/ttyS1 w+] # 按实际串口参数修改波特率,默认配置为115200波特率、8数据位、无校验、1停止位、无流控 fconfigure $serial_port -mode 115200,n,8,1 -blocking 0 -buffering none spawn -open $serial_port puts "Spawning serial connection" send -- "\r" expect "barebox: /" send -- "?\r" expect "barebox: /" # 发起I2C测试模式指令 send "i2c_write -b 1 -a 0x50 -r 0x105 -w 0x02 0xf0\r" expect "barebox: /" send "i2c_write -b 1 -a 0x50 -r 0x105 -w 0x01 0xf0\r" expect "barebox: /" # 轮询读取I2C返回值,增加最大重试次数避免死循环 set max_retry 10 set retry_count 0 set test_result "unknown" while {$retry_count < $max_retry} { # 原代码此处0xh0为笔误已删除,如有需要请替换为正确参数 send "i2c_read -b 1 -a 0x50 -r 0x108 -w 0x03\r" expect { "0x04 0x00" { puts "FPGA still busy, retrying..." incr retry_count sleep 1 continue } "0x00 0x00" { set test_result "success" puts "Test Pattern test successful\r" break } "0x08 0x00" { set test_result "failed" puts "Test Pattern test failed\r" break } timeout { set test_result "timeout" puts "Read I2C response timeout\r" break } "barebox: /" { puts "No valid status in response, retrying..." incr retry_count sleep 1 continue } } } if {$retry_count >= $max_retry} { puts "Error: FPGA keeps busy after $max_retry retries\r" } puts "End of Test Pattern test, result: $test_result\r"
使用注意事项:
- 请根据barebox实际串口配置修改
fconfigure行的波特率参数,否则会出现乱码无法匹配提示符 - 如果你的i2c_read命令确实需要最后一个传参,请把删除的
0xh0替换为正确的十六进制值 - 可根据FPGA实际响应速度调整
max_retry和单次重试间隔的sleep时长
内容的提问来源于stack exchange,提问作者Tellrell White
相关产品推荐
相关产品推荐

