(A) ハードウェアの安定時間待ち
CPUに電源が投入されるということは、その基板に電源が投入されることを意味します。
基板に電源を投入すると、基板上にあるCPUを含めた各LSIに十分な電圧が供給されるまで、時間がかかります。
この十分な時間というのも、CPUやLSIによってバラツキがあります。
このため、CPUだけが先に起動して、プログラムが動作すると、十分な電圧が供給されていない不安定なLSIにプログラムがアクセスする可能性があり、正しく動作しない可能性があります。
以下に、電圧の供給とLSIの起動についてのイメージ図を記載します。
 |
| 図2. LSIの起動順序 |
私が10年以上前に開発したシステムで利用したLSIに「電源投入から100mS以上経過してからアクセスしてください」という仕様がありましたが、それを見逃してプログラムを作ってしまいました。
試作段階では、何も問題ありませんでしたが、量産に入ると製造した20%の基板が正しく起動しないという問題を出してしまいました。
調査した結果は、上記の仕様の見逃しであり、プログラムの起動時に100mSの安定待ち処理を入れることで対応したことがあります。
LSIによって、バラツキもあるため、開発時に問題が無くても、量産して見つかる場合があるため、非常に怖い問題です。
ハード的に基板上のLSIの中でCPUの起動が一番遅くなるように、遅延を入れる対策を取っている場合もありますが、ソフトを作る側でも十分に意識しなければなりません。適切な待ち時間は、LSIのマニュアルやハードウェア設計者に確認する必要があります。
(B) スタックポインタの初期化
必ず必要なCPU関連の初期化は、SP(Stack Pointer:スタックポインタ)の初期化です。
SPは、プログラムやCPUが一時的に利用するデータ領域(スタック領域)の、次にデータ書き込み可能なアドレスを管理しており、PUSH、POPなどのプログラム命令や、割り込みなどのCPU制御により増減します。
スタック領域の具体的な利用方法として、関数コール時や割り込み処理時の戻りアドレス退避や自動変数の領域確保に利用されます。
 |
| 図3. スタックポインタの動作 |
スタック領域は、データの読み書き出来るアドレスに配置する必要があり、具体的にはRAMが配置されているアドレスとなります。
RAMのアドレスは、システムのハードウェア構成によって変わります。
このため、SPを適切なRAMのアドレスに設定しなければ、関数コールや自動変数領域の確保が出来ないことになります。
C言語でプログラムを記述する場合は、スタック領域を意識することは少ないと思いますが、見えない部分で利用しているため、main関数が呼ばれる前にSPを初期化する必要があります。
(C) バスタイミングの初期化
CPUのアドレスバスやデータバスに接続されるLSI(例えば、ROMやRAM)には、高速なモノと低速なモノが存在します。
CPUの動作に比べて、低速なLSIにアクセスする場合は、CPUが応答を待つ必要があります。
この待ち時間(タイミング)を設定するのが、バスタイミングとなります。
CPU内部にある、メモリ(ROMやRAM)を利用する場合は、CPUの速度に合わせたメモリが入っているため、意識する必要はありませんが、CPUの外部に増設するメモリを利用する場合は、意識する必要があります。
バスタイミングが正しく設定されていなければ、メモリに正しくアクセス出来ません。
このため、例えばスタックポインタを外部RAMへ設定する場合などは、main関数を呼ぶ前に外部RAMへのバスタイミングを初期化しておくことで、プログラムが動作するために、必要な、ROM、RAMおよびスタックポインタが利用できる状態となります。
C言語で開発している場合に、C言語のプログラムを動かす準備や、アセンブラでなければ初期化できない部分については、main関数が呼ばれる前の準備処理で行う必要があります。
(A) 初期値付き変数の初期化
C言語でプログラムを記述した場合に、初期値付き変数という要素があり、プログラムが動き出した時点で、変数に初期値が設定されている必要があります。変数というのは、プログラムでは作業領域としてRAMに確保されます。
しかし、電源投入直後のRAMの内容は不定値となっています。
C言語で書かれたプログラムで初期値付き変数というのは、初期値が事前に設定されている前提でプログラムが作られているため、誰かが電源投入後の不定値が入っているRAMに初期値を書き込む必要があります。
初期値付き変数の初期化の仕組みとしては、コンパイラが初期値をROMデータとして、保存しているので、main関数が呼ばれる前に、そのROMデータを初期値付き変数が割り当てられているRAM領域へコピーすることで、初期値設定が出来ます。
 |
| 図4. 初期値付き変数のコンパイラ処理 |
(B) 自己診断
組み込みソフトでは、起動時にハードウェアの自己診断処理を動作させ、ハードウェアの故障を事前に検出する仕組みを入れることが多々あります。
例えば、ROMチェックやRAMチェックが、それにあたります。
ROMやRAMに異常がある状態でプログラムが動き出すと、プログラムがどのように動作するのか、想像できなくなり、システムによっては危険性が出てきます。これを回避するために、ROMやRAMが異常であれば、ソフトを止めてしまうという手段を取ることもあるので、出来るだけ早い段階で実施する必要があります。
自己診断方法は様々ありますが、その方法を検討する際に、想定する事象を考える必要があります。
事象の一例として、「ハンダ不良でCPUと接続されていない」場合や、「隣り合った端子が接触している」などです。
システムを安全に動作させるためには、自己診断機能を早い段階で動作させる必要があります。