Linuxのシリアルコンソールを使ってテストシステムを構築してみます。テストと言ってもコマンドを打って返ってきたテキストを拾ってpass/failを判定する簡易的なものです。基本的な部分を押さえておけば、テスト項目を増やしたり規模を大きくしたりするのはそれほど難しくないと思います。
minicom の導入
ここでは minicom を使用してシリアルコンソールに接続します。インストールされていなければインストールします。
sudo apt install minicom
dmesg などでシリアルデバイスを探しておきます。ここでは USBシリアルケーブルでターゲットボードと接続しているとして、/dev/ttyUSB0 とします。
シリアル接続の設定を設定ファイルに記載しておきます。minicom コマンドオプションで指定することもできますが、".minirc.<configname>" で home ディレクトリに保存しておけば、"minicom <configname>" だけで設定を反映して起動することができます。
pu port /dev/ttyUSB0 pu baudrate 115200 pu rtscts No
configname を "hoge" とすると、これを ${HOME}/.minirc.hoge に保存しておきます。
runscript でコマンド列を記述
シリアルコンソールに送り込む指示は runscript マクロ言語で記述します。コマンドには以下のものがあります。
expect send goto gosub return !< ! exit print set inc dec if timeout verbose sleep break call log
頻繁に使うのは send, expect, print, exit くらいです。
- send は文字列をシリアルに送り込みます。
- expect は文字列が来るまで待機します。{...} で複数書いた場合はそれぞれの文字列に対して処理を実行し、break で脱出します。
- print は文字列を出力ログにのみ出力し、シリアルには出力しません。
- exit はスクリプトを終了します。
その他の機能についてはマニュアル minicom(1) を参照してください。
print "### TEST ###" send "\n" expect { "Hit any key to stop autoboot:" send "\n" "=>" break } send "fatload mmc 0:1 fitImage 0x80000000" send "bootm 0x80000000" expect "login:" send "root" exit
この例では U-Boot が起動するところから始めています。これを startup.script として保存しておきます。
minicom を起動する際に、先ほど保存した設定とこのスクリプトを指定します。
今回の設定は ${HOME}/.minirc.hoge に保存したので、"minicom hoge" とすれば読み込まれます。実行スクリプトは "-S startup.script" で指定します。
$ minicom default -S startup.script
これでスクリプトがに合わせてシリアルコンソールの入出力が制御されます。
minicom と shell の往来
最初の起動スクリプトは実行できたので、テスト項目ごとにスクリプトを作成しています。
しかしこの時点での minicom はスクリプトが終わっただけで本体は終わっていません。メニューからスクリプトを実行することはできますが、自動化したいのでこの方法は使いません。
起動スクリプトに続いてテスト項目ごとに実行するコマンドを同じスクリプトに書いていけば実行することはできますが、結果は1つのテキストに出力するためテスト項目ごとに評価するのが難しくなります。またスクリプトがすべて終わるまで評価できないので、テストシステムとしてはあまり望ましくありません。
スクリプト1つ終わるごとにコンソールで終了キーの "Ctrl-A x [RET]" を押すのも使い勝手が悪すぎます。minicom を自動で終わらせる方法がないかを調べていたら、ある投稿を見つけました。
stackoverflow: How to exit minicom via scripting
"Ctrl-A x [RET]" をテキストファイルに用意しておいて、リダイレクトで読み込ませれば終われるということです。emacs や vi で "Ctrl-A x [RET]" (^Ax^M)を作って escape.txt に保存しておきます。
$ minicom default -S startup.script < escape.txt
これでスクリプトが終了すると同時に minicom も終了します。
スクリプト連続実行と評価
テスト項目ごとにスクリプトを作成して、実行と評価を繰り返していけばテストシステムは出来上がりです。
テスト項目を 1-1, 1-2, 1-3,..., 2-1, 2-2, 2-3,... とナンバリングして、項目ごとのファイル名に番号を入れておけば shell script でどんどん実行することができます。番号に適合したスクリプトがなければ飛ばします。
まずテスト全体を実行するメインスクリプトを作成します。main.sh としておきます。
#!/bin/sh minicom hoge -S startup.script < escape.txt for c in $(seq 1 9); do for n in $(seq 1 9); do SCR=test-${c}-${n}.script LOG=test-${c}-${n}.log TST=test-${c}-${n}.sh [ -f ${SCR} -a -f ${TST} ] || continue minicom hoge -S ${SCR} -C ${LOG} < escape.txt ${TST} ${LOG} if [ $? = 0 ]; then echo "### ${c}-${n} pass" else echo "### ${c}-${n} fail" fi done done
この例では test-<c>-<n>.sh に minicom で出力した結果を評価して、終了コードに反映しています。テスト成功なら 0、テスト失敗なら 1 を返します。
test-1-1.script の例として、CPU 温度を計測して出力します。
send "\n" expect "# " send "cat /sys/class/thermal/thermal_zone0/temp expect "# " exit
test-1-1.sh の例として、温度値を出力ファイルから探し出して、50℃を超えていなければ1を返します。
#!/bin/sh TEMP=`awk '/^[0-9]+$/ {print}' $1` [ $TEMP -lt 50000 ] && exit 1 exit 0
このようなスクリプトをテスト項目の分だけ用意して、メインスクリプトを実行すればテストが自動で実行され、結果が出力されます。
まとめ
今回の簡易テストシステムでは以下のファイルを用意しました。
- main.sh
- .minirc.hoge
- startup.script
- escape.txt
- test-1-1.script
- test-1-1.sh
結果の文字列に特定ヘッダ ("###" など) を付けるなどしておけば、さらに上位のシステムと接続して結果を収集するのに役立ちます。
コメント