意外と深い、マイコン版「Hello World!!」を侮るなかれ−ザ・組み込み−ソフトウェアのハードウェア化(4)(3/4 ページ)

» 2008年10月29日 00時00分 公開
[鳥海佳孝 設計アナリスト,@IT MONOist]

エラーを調査し、コンパイルを実施せよ!

 しかし、本当に「stdio.h」のヘッダーファイルがないのでしょうか? そして、そもそもこれらのインクルードファイルは一体どこを見に行くのでしょうか? H8の開発環境ですので、基本的に「-I」オプションでコンパイル時に指定したディレクトリの下辺りにありそうなものですが……。

 というわけで、こういうときは「find」コマンドでファイルを検索するのが一番です。


# find /usr/local/src/uClinux-dist/include -name stdio.h -print
/usr/local/src/uClinux-dist/include/stdio.h
/usr/local/src/uClinux-dist/include/STLport/stdio.h 

 フムフム。どうやら「stdio.h」そのものはあるようですね。となると、ヘッダーファイルそのものは存在するものの、ライブラリ自体がうまく関係付けられていないことが考えられます。

 次に、「lib」を疑ってみましょう。以下のように「lib」ディレクトリに移動し、「ls」コマンドを以下のように実行して下さい(lsコマンドのオプション「-alF」に関しては「man ls」でご確認ください)。

# cd ../lib
# ls -alF 

 すると、画面1のようにリンク先が見つからないファイルがたくさん発見されます。

「lib」ディレクトリ以下を、「ls -alF」コマンドで表示した様子(1) 画面1 「lib」ディレクトリ以下を、「ls -alF」コマンドで表示した様子(1)

 これらを調べていくと、どうやらこのディレクトリにある「uClibc」のリンク先に原因があるようです。このリンク先が「...../uClinux-dist/uClibc」を指しているので、これを「lib」の1つ上の階層にある「uClibc」に変更してみます。なお、こういう変更を行う際は、念のためオリジナルのファイルを別名で保存しておくクセを付けておきましょう。というわけで、以下のようにコマンドを実行してください。

# mv uClibc uClibc.org ←オリジナルを別名で保存しておく
# ln -s ../uClibc uClibc 

 それでは、以下のコマンドできちんとリンクできているかを再度確認してみましょう。

# ls -alF 

 すると、画面2のように、先ほど(画面1)リンク先がエラーになっていた個所がすべて正しいリンク先になりました。

「lib」ディレクトリ以下を、「ls -alF」コマンドで表示した様子(2) 画面2 「lib」ディレクトリ以下を、「ls -alF」コマンドで表示した様子(2)

 では、気を取り直してもう一度「make」コマンドを実行してください。

# cd /root/3069F
# make
h8300-linux-elf-gcc -mh -mint32 -Os -fno-builtin -nostartfiles -nostdinc -I/usr/local/src/uClinux-dist/include -I/usr/local/src/uClinux-dist/include/include hello.c -c hello.c
h8300-linux-elf-gcc -mh -mint32 -Os -fno-builtin -nostartfiles -nostdinc -I/usr/local/src/uClinux-dist/include -I/usr/local/src/uClinux-dist/include/include -Wl,-elf2flt /usr/local/src/uClinux-dist/lib/crt0.o  -L/usr/local/src/uClinux-dist/lib -lc  hello.o -o hello-h8 

 いかがでしょうか? 見事にコンパイルできましたね!

 いよいよ、このファイル(hello-h8)をH8マイコンのターゲットボードで実行させるわけですが、ここでNFSマウントが活躍します。「/opt/aki3069f」というディレクトリが、ターゲットボードのルートファイルシステムになっていますので、実行可能なファイル(hello-h8)を「/opt/aki3069f/bin」の下に、以下のコマンドでコピーし、念のため実行権を与えておきます。

# cp hello-h8 /opt/aki3069f/bin
# chmod 755 /opt/aki3069f/bin/hello-h8 ←念のため実行権を与える 

 ここまでの準備ができたら、シリアル通信ソフトでつながっているH8マイコンのコンソールから、hello-h8を実行するだけです。しかし、前回までの解説で作成した「romfs」のファイルには、「echo」コマンドが入っていません。つまり、これではコマンドを実行した後のmain関数の戻り値を調べることができませんので、ここではカーネルのソースの中にあるBusyBoxの「echo」コマンドを有効にします。なお、今回デフォルトのBusyBoxの設定に「echo」コマンドのみを追加したファイル(busybox)を用意しましたので、以下のリンクからダウンロードして、次のように設定してください(自力で生成できた方は、以下の操作は必要ありません)。ちなみに、ダウンロードしたファイルは「/root/3069F」以下にあるものとします。

# mv /opt/aki3069f/bin/busybox /opt/aki3069f/bin/busybox.org
# cp busybox /opt/aki3069f/bin/
# chmod 755 /opt/aki3069f/bin/busybox ←念のため実行権を与える
# cd /opt/aki3069f/bin
# ln -s busybox echo 

 BusyBoxの設定が完了したら、hello-h8を実行してみましょう。シリアル通信ソフトでつながっているH8マイコンのコンソールで、以下のコマンドを入力してください。

/> hello-h8
Hello World!!
pid 26: failed 31488 

 上記のように「Hello World!!」と出力されればOKです。このような小さなマイコン上でOSが動作して、しかもその上でユーザー・アプリケーションが動作するなんて……、大型計算機を知る時代を過ごした筆者にとっては考えられません。すごいことだと思います。

 ところで、先ほどの「Hello World!!」の表示結果をよく見てみるとプロセス番号(今回の例では「26」)を出力して、何やらfailedとして整数値を出力しています。

 どうやらこの値は、

“255(戻り値の1バイト分で表される最大値)×123(戻り値で指定した値)+123(戻り値で指定した値)”

すなわち、123(戻り値で指定した値)×256で返してくるようです。ちなみに、「hello-h8」コマンドの直後に「echo」コマンドを使ってみると、

/> echo $?
123 

のように戻り値「123」が出力されます。

Copyright © ITmedia, Inc. All Rights Reserved.