組込プログラムではリセットスタートで起動し、自分自身で必要なハードウェアの初期化をするプログラムが基本となります。
そのようなプログラムの例としてROMモニタをとりあげます。
ここではROMモニタをソースから構築してCPUボードに書込むまでの手順を説明します。
ターゲットボードとしてH8S2212-P52を使います。
H8S2212UはUSB経由のブート書込が可能なCPUで、CPUボードはUSBバスパワーで動作しますので専用のケーブル・電源なしでプログラムの開発ができる便利なボードです。

ブート書込みの準備

青枠で囲んだ3本のジャンパをすべて差し込んでからUSBケーブルに接続します。
これでブート書込みの準備が出来ました。
※ブート書込を失敗したりやり直す場合は一度USBケーブルを抜いて接続し直して下さい。
プロジェクトはJDEのインストールで /usr/src/jed/work/mon_H8S2212-P52/mon_H8S2212-P52.jpr
にインストールされます。
ソースが存在しない場合はこちらからダウンロードして /usr/src に保存しCygwinウィンドウで tar コマンドを使って展開して下さい。
メニューからプロジェクト mon_H8S2212-P52.jpr を開き
(再構築)をクリックします。
コンパイルメッセージ欄に「コンパイルとリンクが終わりました」と表示されたら構築完了です。
エラーが発生した時は下図と較べて設定を確認して下さい。

どのようなメモリ配置でプログラムが作成されたかを確認するにはメッセージ欄の文字 mon_H8S2212-P52.map をダブルクリックします。
表示されたエディタウィンドウでまず .text という文字列を検索してみます。
.textはプログラムのセクションでプログラムが0x00001000から0x6880のサイズで展開されていることを示しています。
同様に .vectors .bss .heap .stack について検索するとメモリ配置がCPUの内蔵ROM、RAMの範囲を超えていないことを確認できます。
リンカスクリプトで定義されたROM、RAMの範囲を超えるとリンカエラーになりますからこのマップファイルを確認しなければならないことはほとんどありませんが、
組込プログラムで解決できないトラブルが発生したときには念のためにマップファイルを確認することを覚えておくと役立ちます。

次にmon_H8S2212-P52.motをダブルクリックして生成された転送用のSフォーマットファイルを見てみます。
これは下図のようにプログラムのバイナリデータをアスキー文字でフォーマット化したものです。
先頭5-8文字がアドレスで続いて16進表記のデータが続き最後の2文字がチェックサムになっています。
通常はこのファイルを意識する必要はありませんがどのような形式のファイルが生成・転送されるかを知るために一度は確認しておくと何かの時に役立ちます。

次に ブート書込ツールを使って構築したモニタプログラムをターゲットボードに書き込みます。
H8S2212-P52のブート書込に沿ってブート書込をおこなってください。
書き込んだモニタを起動してみます。
USBケーブルを外し、青枠で囲んだジャンパを外してからケーブルを再接続します。
LEDが点滅を開始したらモニタが正常に動作しています。

通信プログラムを起動してENTERキーをたたくとモニタプロンプトが表示され、’?’を入力するとモニタコマンド一覧が表示されます。

シンプルなprintfプロジェクトを作成して構築、書込・実行します。

ソースは下図に表示している7行が全てです。
組込プログラムではmain()から抜けないのが原則なので、printf()を実行した後にforループで停止します。
puts関数やprintf関数を利用する場合は、syscalls_newlib.S を、プロジェクトに追加 して下さい。

正常に構築が終了したらプログラムの転送・書込みに進みます。
エラーが発生したときはエラーの書込と修正を参考にして構築完了するまで修正をおこないます。
CPUボードにUSBケーブルを接続しモニタが起動してLEDが点滅していることを確認します。

ROM化ボタンをクリックしてプログラムの書き込みを開始します。
通信プログラムが起動しターゲットボードにプログラムを転送して実行します。

通信画面で最後に表示されている"Hello world."が実行されたプログラムの出力です。
それ以外はモニタが出力した表示出力です。
プログラム開始アドレスが0x00008100、サイズが0x0000A97D=43,389byteとなっています。
1行だけのプログラムなのにサイズがかなり大きくなっているのはprintfを使うと多くのライブラリ関数を必要とするためです。
使っているライブラリ関数の一覧は printf.map で確認することができます。
ROM化されたプログラムがある場合はモニタを起動してRUNコマンドでプログラムを実行することができます。
下図が実行画面です、モニタからRUNコマンドで実行した場合にはプログラムステータスが表示されます。

ジャンパを取り外すとパワーオンリセットでプログラムを実行することができます。

下図が実行画面です、パワーオンリセットで実行する場合はプログラムの出力だけが表示されます。

printfを使うとソースはシンプルでも生成されたプログラムはかなり大きくなります。
ここではプログラムサイズが小さくて済む文字列入出力を説明します。
メニューからプロジェクト /usr/src/jde/tutorial/puts/puts.jpr を開き
(再構築)をクリックします。
コンパイルメッセージ欄に「コンパイルとリンクが終わりました」と表示されたら構築完了です。
エラーが発生した時は下図と較べて設定を確認して下さい。 ソースは下図に表示している12行が全てです。
conio.c に、puts() に関する記述がしてありますので、プロジェクトに必要となります。
ROM化ボタンをクリックしてプログラムの書き込みを開始します。
通信プログラムが起動しターゲットボードにプログラムを転送して実行します。

プログラムサイズが 0x00000804=2052byte とprintfを使った場合に較べてたいへんコンパクトになっています。
サンプルプログラムではforループ中で文字入力待ちをしていますのでキーボードをたたく毎に文字列が出力されます。
簡単なコンソール入出力関数のサンプルプログラムです。
printf()は多量のヒープメモリが必要で少ない内部RAMしか持っていないCPUでは
ワークエリアを食いつぶしてしまいます。puts関数はその代替用です。
メニューのプロジェクトを開くから、 /usr/src/jde/work/H8S2212-P52/GNUH8V0802/sample_conio/conio.jpr を開き
(再構築)をクリックします。
コンパイルメッセージ欄に「コンパイルとリンクが終わりました」と表示されたら構築完了です。
エラーが発生した時は下図と較べて設定を確認して下さい。
ROM化ボタンをクリックしてプログラムの書き込みを開始します。
通信プログラムが起動しターゲットボードにプログラムを転送して実行します。

サンプルプログラムではforループ中で文字入力待ちをしていますのでキーボードをたたく毎に文字列が出力されます。
xputs()で文字列、conout()で文字、putint()で10進数としてコンソールに出力しています。
puts関数は、以下のようなコンソール入出力や文字列出力関数が使えます。詳しい使い方は、[conio.c][conio.h]を参照して下さい。
| ■■■■■■■ −コンソール入出力 − | ||
| int consts(void) char conin(void) void conout(char c) void errout(char c) int readline(char *buf,int maxlen,int echo) |
文字列入力 文字入力 文字出力 エラー出力 ライン入力バッファへ改行までの文字列を読み込む |
|
| ■■■■■■■ −文字列出力関数 − | ||
| void putback(void) void putcrlf(void) void xputs(char *s) void puthex(unsigned char n) void puthxb(unsigned char n) void puthxw(unsigned short n) void puthxl(unsigned long n) void putint(unsigned long n) |
バックスペース処理 CRLFの出力 文字列出力 データを16進数として出力 バイトデータを2桁の16進数にして出力 ワードデータを4桁の16進数にして出力 ワードデータを8桁の16進数にして出力 バイトデータを10進数にして出力 |
|
基板に実装してあるLEDを点滅させるサンプルプログラムです。

メニューのプロジェクトを開くから、 /usr/src/jde/work/H8S2212-P52/GNUH8V0802/sample_led/led.jpr を開き
(再構築)をクリックします。
コンパイルメッセージ欄に「コンパイルとリンクが終わりました」と表示されたら構築完了です。
エラーが発生した時は下図と較べて設定を確認して下さい。
ROM化ボタンをクリックしてプログラムの書き込みを開始します。
通信プログラムが起動しターゲットボードにプログラムを転送して実行します。

サンプルプログラムでは、P1の8ポートをすべて出力設定にして、割り込み禁止をかけ、forループ中でP1ポートへの出力(LEDの点滅)をしています。
delay()は時間待ちの関数で、jで点滅時間を調整しています。 ポートとLEDの配置は、図( main.c 後半の注釈文)の通りです。

タイマー割り込みのサンプルプログラムです。
メニューのプロジェクトを開くから、 /usr/src/jde/work/H8S2212-P52/GNUH8V0802/sample_timer/timer.jpr を開き
(再構築)をクリックします。
コンパイルメッセージ欄に「コンパイルとリンクが終わりました」と表示されたら構築完了です。
エラーが発生した時は下図と較べて設定を確認して下さい。
ROM化ボタンをクリックしてプログラムの書き込みを開始します。
通信プログラムが起動しターゲットボードにプログラムを転送して実行します。

サンプルプログラムでは、タイマの初期化、割り込み許可をして、forループ中で1秒間隔で、文字列を出力しています。
inti(),InitTimer() で初期化、int_Timer0() が割り込み関数本体で、1mS 毎の割り込み:timer1mS から、1S
毎の割込:timer1S を作っています。
H8S内蔵A/D変換機能のサンプルプログラムです。
このCPUは、逐次比較方式の10bitのA/D変換器を内蔵しており、最大6チャネルのアナログ入力を選択することができます。
ここでは、5[kΩ]のボリュームをJ1ソケットの 1pin(3.3V OUT),15pin(GND),43pin(AN0)に配線しています。

メニューのプロジェクトを開くから、 /usr/src/jde/work/H8S2212-P52/GNUH8V0802/sample_ad/read_ad.jpr を開き
(再構築)をクリックします。
コンパイルメッセージ欄に「コンパイルとリンクが終わりました」と表示されたら構築完了です。
エラーが発生した時は下図と較べて設定を確認して下さい。
ROM化ボタンをクリックしてプログラムの書き込みを開始します。
通信プログラムが起動しターゲットボードにプログラムを転送して実行します。

サンプルプログラムでは、read_ad() からの変換データ デジタル値をモニタに表示しています。
forループ中で、0,1,2 の値を read_ad() へ順に渡し、各アナログ入力チャネルからの変換結果を、mein() へ返し、分解能:10bit
から、電圧の最大値(3.3V)を1024分割したいくつかを、puts()を用いて、画面表示しています。
下記は、アナログ入力チャネルとADDR(AD変換データレジスタ) の対応です。
詳しくは、H8S_2212グループハードウェアマニュアル を参照して下さい。
