OSが起動する以前のスタートアップルーチン:H8で学ぶマイコン開発入門(4)(2/4 ページ)
OSが搭載されていない組み込みシステムの場合、プログラマはOSが実行してくれる処理のすべてを自分で実装する必要がある。
スタートアップルーチン
WindowsやLinuxなどのOSが搭載されたシステムでは、main関数の前後や周辺デバイスの制御は、OSが処理してくれます。これに対してOSが搭載されていない組み込みシステムの場合、OSが実行してくれる処理のすべてをプログラマが実装する必要があります。これらの処理を行うプログラムのことを、一般的にスタートアップルーチンと呼びます。スタートアップルーチンでは、最低限、以下の処理をプログラミングします。
- スタックの設定
- 割り込みベクタの設定
- ROM領域からRAM領域へ初期値データの転送
- 初期値を持たないデータのクリア(初期化)
- ハードウェアおよびCPU内蔵レジスタの初期化、割り込み許可
- アプリケーションプログラムの呼び出し
1.スタックの設定
Cプログラムの自動変数(局所変数)は、変数が宣言された関数内部での計算やデータの保存、条件判定のためのフラグとして一時的に使われます。関数の仮引数や浮動小数点演算を行うためのテンポラリ領域なども一時的に使われ、さらにプログラムの書き方によりサイズや数が異なります。また、関数の戻り番地も常に値を保持している必要はありません。これら、一時的に使われる変数や作業領域などはコンパイラにより、スタックと呼ばれるRAM領域に割り付けられます(図1)。
プログラマは、アプリケーションプログラムで必要なスタック領域の大きさと、スタック領域の先頭アドレスをスタックポインタレジスタに適切に設定する必要があります。スタックを消費するものをまとめると、以下のようになります。
スタックを消費するもの
スタック領域はコンパイラにより、読み書き可能なRAM内に配置されます。このため、スタートアップルーチンで細心の注意を払ってスタック領域を設定しないと、プログラムが暴走する原因になります。
図2は、スタック領域の確保が十分ではなく、データ領域を破壊している例です。スタートアップルーチンで設定したスタックポインタが正常にスタック領域を指している間は問題ありません。しかし、スタックポインタがスタック領域の外側、この例ではデータ領域にまで侵入してくると、元データは破壊され、プログラムは動作異常を起こします。
また図3は、プログラム中で使っているポインタに問題があり、プログラムがスタックを破壊している例です。スタック領域に、関数の戻り番地が保存されているとします。この例ではプログラムポインタの使い方に問題があり、ポインタがスタック領域を指してしまいました。ポインタを使ってメモリからデータを取り出すだけなら、取り出したデータがおかしい値となるだけで、暴走する直接の原因にはならないかもしれません。しかし、ポインタでデータを書き込んでいる場合は、この例では本来あるべき関数の戻り番地が破壊されるため、プログラムは確実に暴走します。
このようにスタックの設定は、組み込みプログラムにとって非常に重要な要素です。
2.割り込みベクタの設定
プログラム実行中に割り込みが発生すると、現在実行中のプログラムは中断され、プログラムカウンタは割り込み要因に対応するベクタを指します。割り込みベクタの記述方法や割り込み発生後の処理方法はマイコンにより異なります。本連載で使用するH8マイコンの場合、表1のベクタテーブルが割り当てられています。
H8マイコンの場合、割り込みが発生すると、以下の処理がマイコンにより実行されます。
- プログラムカウンタとコンディションコードレジスタ(CCR)をスタックに退避
- CCRの割り込みマスクビットを1にセット
- 割り込み要因に対応する割り込みハンドラのスタートアドレスを割り込みベクタテーブルから取り出して、割り込みハンドラに分岐
プログラマの仕事は、割り込みハンドラのスタートアドレスを、ベクタテーブルに記述することです。H8/3048マイコンでは、割り込み例外処理を開始させる要因として、7種類の外部割り込み(NMI、IRQ0〜IRQ5)と内蔵周辺モジュールからの要求による30種類の割り込み内部要因があります。プログラマは、それぞれのベクタテーブルをプログラミングする必要があります。なお、割り込みハンドラ自体を記述することも、プログラマ側の責任であることはいうまでもありません。
Copyright © ITmedia, Inc. All Rights Reserved.