问题
在使用串口调试过程中,需要手动输入执行命令,交互性输入,以及等待执行结果。基本所有的信息都在 tty 中串行的进行显示。痛点有下面几个
- 重复命令手动输入执行
- 交互性输入
- 等待执行信息,不能自动保存到文件
- 串口调试环境本身edit 便利性
基于以上的问题,需要存在需求:
- 可以将执行命令存放脚本中,而且可以去调用执行
- 可处理交互性输入
- 对于执行命令输出可以保存到 log 文件
基本方案
-
基于 SecureCRT
SecureCRT 脚本,使用 python 语言
优点:
- GUI 界面,操作直观
- python syntax 语法特性支持强大
缺点:
- SecureCRT 过重,本身安装麻烦
- 仍然需要基本交互,SecureCRT 内调用脚本
- 与 jenkins 的集成
-
基于 Terminal 环境
首先要解决的是串口环境,这里使用 picocom 命令行工具,类似的有 minicom 等。
其次,针对需要交互行输入,使用 Expect 处理,Expect 基于 TCL (Tool control language)
最后,得到的 .expect 脚本可以通过 Jenkins pipeline 进行调用。
优点:
- 轻量化,可通过命令行安装
- 所有过程都在 Terminal 操作
- 集成到 Jenkins,完全支持自动化流程
缺点:
##实际解决
针对上面两种方案,如果是非重复性调试,使用前者上手更快。
如果有需要多次重复性,或者自动化测试需求,选择后者。
下面给出使用 Expect 的一个 demo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
set timeout 30 log_file test-expect.log
set baudrate "115200" set device "/dev/ttyUSB0" set prompt "=>"
set interval 5 set iter_cnt 10
proc start_xvr_debug { prompt } { send "xvr_client_dbus\r" expect $prompt }
proc test_switch_channel_display { iter_cnt interval prompt } {
for { set i 1 } { $i < $iter_cnt } { incr i 1 } { send "switch_channel_display -cam 0 -ch 0 -onoff 1\r" expect $prompt exec sleep $interval
send "switch_channel_display -cam 0 -ch 0 -onoff 0\r" expect $prompt exec sleep $interval
send "switch_channel_display -cam 0 -ch 1 -onoff 1\r" expect $prompt exec sleep $interval
send "switch_channel_display -cam 0 -ch 1 -onoff 0\r" expect $prompt exec sleep $interval } }
proc test_start_stop_pipeline { iter_cnt interval prompt } { for { set i 1 } { $i < $iter_cnt } { incr i 1 } { send "stop_pipeline /dev/xvr_pipeline-0\r" expect $prompt exec sleep $interval
send "stop_pipeline /dev/xvr_pipeline-1\r" expect $prompt exec sleep $interval
send "start_pipeline /dev/xvr_pipeline-0\r" expect $prompt exec sleep $interval
send "start_pipeline /dev/xvr_pipeline-1\r" expect $prompt exec sleep $interval } }
spawn picocom -b $baudrate $device expect "Terminal ready\r" send "\r"
start_xvr_debug $prompt test_switch_channel_display $iter_cnt $interval $prompt
expect eof
wait
|
在具体使用中遇到的有几个小坑:
- 集成到 jenkins 时,jenkins 用户无法获得
/dev/ttyUSB0
权限。
sudo
执行 Expect 脚本进程 kill
详情见尾注意小节。
参考
注意
-
关于 jenkins 用户无法获取 /dev/ttyUSB0
权限
在这里最好不要直接使用 sudo
,使用 root 权限执行的坏处在于,当你想要中断 expect 脚本时,也必须使用 root 权限。并且在集成到 Jenkins 时,jenkins 用户起了 root 权限的进程,在中断 job 的时候。expect 任然在 jenkins node 上继续执行。
解决的方案是将 jenkins 用户加入拥有 dev 设备权限的用户组。
1
| sudo usermod aG dialout jenkins
|
-
sudo 执行的 expect 进程kill
sudo killall -u USER expect