ターミナルへの表示
ここまでは,C言語でプログラムを書く前に知っておくべき予備知識を学んできた.ここからはプログラムを作り,実際にミームスを動かしていく.
まず,PC上の TeraTerm 上への表示と,キーボードからの読み込みを行うプログラムを作成する.
この仕組みを用いることにより,今後のプログラム開発中に「変数の値を知りたい」などの要求にこたえることができるようになる.
プログラムの仕組み
「マイコンの開発環境の構築」の回で説明したように,モニタプログラムには printf( )と scanf( ) 関数が組み込まれている.ハードウェアごとに異なる標準入出力に対して,標準ライブラリでは対応できないので,MEMEsのモニタプログラムに組み込まれている関数の実体を使用するのである.
ユーザプログラムの中で printf( ) や scanf( ) を使用したときに,標準ライブラリを呼び出すのではなく,図1のようにモニタプログラム中の printf( ) や scanf( ) を呼び出すようにするというのが今回の重要なポイントとなる.
図1:printf と scanf の実体
printf( ) のテスト
まず printf( ) 関数の簡単な動作確認を行う.
すでに説明したように,ユーザープログラムがモニタプログラム内の printf( ) を呼び出すと,表示される情報はSH7085 の SCI モジュールからシリアル通信データとして出力され,シリアルーUSB変換 IC により USB に変換され,PCへと送信され,TeraTerm 上に表示されるのである.
ワークスペースを開く
まず,下記のワークスペースをダウンロードする.ダウンロード先は Windows の「ダウンロード」フォルダで良い.
次に,ダウンロードしたファイルを,Windows から見た Linux ファイルシステムである
¥¥Linux¥Ubuntu¥home¥[User]¥micon にコピーする.
図2:tar ファイルのコピー
次に Linux 環境上で tar ファイルからファイル抽出する.
WSL2 を起動し,
$ cd micon
などとし,カレントディレクトリを変更する.
ls コマンドで,先ほどコピーした tar ファイルが確認できるはずである.
続いて次のコマンドで,ファイルを抽出する.
$ tar -xvf terminal.tar
(tar コマンドのオプション -xvf は,ハイフンなしの xvf としても動作する)
コマンド入力途中に[TAB]キーを押すと,残りの文字列を補完する機能があるので,使ってみるとよい.
図3:ファイル抽出
次に
$ cd terminal/
でディレクトリを移動する.
$ ls
でプロジェクトを構成しているファイル群を確認できる.
本来ならば,ここで C ソースファイルを編集するのであるが,初めてのプロジェクトは編集無しで,メイク・実行できるようになっている.
(C ソースファイルの編集は,Windows 環境からテキストエディタを使い行う.又は Linux 環境上で vi エディタなどで行う)
次のコマンドでメイクを行う.
$ make terminal1
C ソースファイルをコンパイル,ライブラリなどとリンクし,目的の mot ファイルを自動生成する.もしエラーが発生した場合は,行番号などの情報が表示されるので,修正を行い再度 make する.
次に MEMEs ボードと Windows PC とを USB ケーブルで接続し,Windows で TeraTerm を起動する.
[新しい接続]ダイアログでは,「シリアル」を選択する.
[設定] – [シリアルポート] メニューを選び通信条件を設定する.
図5:TeraTerm設定1
ここでスピードを [38400] とし,[現在の接続を再設定] で確定する.
図6:スピード設定
MEMEs ボードにダウンロードする準備ができたので,実際にダウンロード・実行してみる.
MEMEs と USB 接続していることを確認し,MEMEs の電源を投入する.TeraTerm にはモニタプログラムの起動メッセージが表示される.
図7:起動メッセージ
表示されない場合は,次を確認する.
- USB ケーブルは正しく接続されているか
- COM ポート番号は正しいか
- スピード設定は正しいか(スピード設定が間違っていると,文字化けする)
ダウンロードするには,モニタプログラムで L コマンド(Load)を発行する.L [Enter] を入力すると,ファイル待ちの状態に入る.
なおコマンドは大文字・小文字どちらでも構わない.
図8:L コマンド発行
転送するファイルは,先ほど make コマンドで生成された terminal1.mot である.
転送を開始するには2つの方法がある.どちらでも結果は同じである.
- [ファイル] – [ファイル送信] メニューで転送するファイルを指定する
- 転送するファイルを TeraTerm 画面にドラッグする
ここでは TeraTerm 画面にドラッグする時の画面を用意した.
図9:ダウンロードするファイル
ダウロードが終了したら,G コマンド(GO)を発行する.
G [Enter]
TeraTerm には次のようなメッセージが表示される.
図10:実行結果
プロジェクトはいくつかのCソースコードやヘッダファイルなどで構成されているが,プログラミングの対象は主に terminal1.c である.
terminal1.c のリスト
/* * terminal1.c : printf()関数のテストプログラム */ #define printf ((int (*)(const char *,...))0x00007c7c) #define scanf ((int (*)(const char *,...))0x00007cb8) void main(void) { printf("Hello World\n"); }
このプログラムの要点は,4行目と5行目である.printfを0x00007c7c番地へのポインタと定義している.同様にscanfを0x00007cb8番地へのポインタとしている.これにより,ソースコード中のprintfは0x00007c7c番地を呼び出すようになる.
printf( ) の引数である文字列を変更することにより任意の文字列を表示可能なので,ソースコード修正→メイク→ダウンロード→実行,を繰り返し,各自試してみること.
printf( ) を実行し終わると,main( ) は終了する.main( ) 自体も関数であるので,終了すると呼び出し元へ戻るはずである.
組込みプログラムの場合は,通常main( ) は無限に続くように作るか(電源が入っている限り,機器を制御し続ける),安全な状態を作ってスリープまたはHaltするようにしておく.
今回のプログラムは,main()の呼び出し元である libmemes.c の before_main() を確認すると,main()が終了するとwhile(1);文で無限ループするようになっていることがわかる.
PCのプログラムであれば,ウィンドウを閉じて終了,となるのだが,組込みプログラムの場合は,main()が終了しても装置が不安定な状態にならないように考慮が必要なのである.
演習問題
演習1:printf( ) 関数を使用して,TeraTerm 上に1, 2, …, 100 の数字を出力するプログラムを作成せよ.
演習2:terminal2.c のmain ( ) 関数に TeraTerm から入力された文字列をそのまま出力するプログラムを,下記の実行例を参考にして作成せよ.
次のような手順で作業する.
- terminal2.c を編集する
- make terminal2 でメイクする
- terminal2.mot を TeraTerm にダウンロード(L コマンド)
- 実行(G コマンド)
図9:実行例