スパイス  組み込み制御装置の受注製作

モニタプログラムを移植する
平成26年4月 10日

xprintf関数
 モニタプログラムによってデバッグの度にEPROMにプログラムを書き込みICを抜き差しする手間を省くことができるようになります。しかしデバッグ作業の中心は特定の動作状態まで進んだときに変数の値がどうなっているかを確認する作業が主体です。一般的には特定のプログラムの位置にブレークポイントを設定して、ブレーク後に必要な変数の値を確認します。最近の統合開発環境ではこの方法が中心的です。

 しかし、この方法はコンパイラから多くの情報を引き出す必要があります。プログラマはC言語のソースコードを意識していますので、C言語のソースコードに対応するアセンブラ言語での命令のアドレスを管理する必要があります。現在は多くのCコンパイラが対応していますが、古い時代のものではアセンブラベースのアドレスに対してブレークポイントを設定することしかできません。

 もう一つの方法は先のブレークポイントを設定したい位置にprintf関数を置いて、その時点での変数の値を表示させるというものです。この方法も組み込み装置で使用するには幾つかの問題点があります。最初の課題はC言語標準のprintf関数では標準入出力に対して操作が行われるのに対して、組み込み装置には標準入出力が無いのです。標準入出力はFILE構造体を介した実装です。内部的にはかなり複雑な構造になっています。これを実装するためにはsbrk(), malloc()などのヒープメモリ関連の関数を実装する必要があります。ここ10年位のCコンパイラでは組み込み用のCコンパイラにもヒープメモリが使用できるようになってきましたが、それ以前まではヒープメモリを使える組み込みCコンパイラは(私が知っている範囲では)無かった。メモリの制約が厳しいので実装すること自体のメリットが少なかったためでしょう。

 これを補うためかLSIC-86にはxprintf()という関数が用意されていました。基本的な機能はprintf()関数と同じですが、引数の一つとして一文字出力を行う関数を渡します。結果の出力はこの一文字出力関数を介して行うため、どこにでも出力できる優れものです。私がこのような仕様のprintf関数を知ったのはLSIC-86が最初ですが、それ以前からあったのかもしれません。
 このxprintf関数を使用すればシリアルポートに直接、変数の値を出力できます。次の問題はLSIC-86以外のCコンパイラではxprintf関数を使えない(コンパイラに含まれていないので自分で実装するしかない)のですが、同じような希望はあちこちにあったのでしょう。xprintf関数の自作ソースが公開されています。例えばChan氏のHPです。大抵は実数を扱うことは出来ないのですが、組み込みではあまり問題にはなりません。私は他から入手したソースを参考にして自分で実装しなおしました。
 xprintf()によるデバッグではC言語のソースコードレベルでデバッグできるので、コンパイラがC言語でのソースコードデバッグをサポートしていない場合には、こちらの方法が有利です。

 比較的古い時代のCコンパイラを使用するなら、xprintf()関数は必須の機能となります。

 タイトル先頭へ 前へ 次へ タイトル末尾へ