HOME > ソフテックだより > 第83号(2009年2月4日発行) 技術レポート「マイコン用ソフトの起動まで」

「ソフテックだより」では、ソフトウェア開発に関する情報や開発現場における社員の取り組みなどを定期的にお知らせしています。
さまざまなテーマを取り上げていますので、他のソフテックだよりも、ぜひご覧下さい。

ソフテックだより(発行日順)のページへ
ソフテックだより 技術レポート(技術分野別)のページへ
ソフテックだより 現場の声(シーン別)のページへ


ソフテックだより 第83号(2009年2月4日発行)
技術レポート

「マイコン用ソフトの起動まで」

1. はじめに

ここ数年、あらゆる電化製品や工業機器にマイコンが搭載されるようになりました。
ソフテックのホームページにも「マイコン誕生から37年の技術と実績」と掲げており、ソフテックではマイコン用ソフトウェア開発も1つの柱として取り組んでいます。

「マイコン用ソフトウェア開発が出来る」と言えるようになるためには、CPUやハードウェアを理解してプログラムを作れる必要があります。
しかし、ここ数年はCPUの性能が向上し、プログラムが大規模化してきたことにより、作業が分業化され、CPU制御やハードウェア制御を担当する人と、CPUやハードウェアに依存しないアプリケーションを担当する人に分かれて開発することも多くなり、後者のようにマイコン用ソフトウェア開発をしていても、CPUやハードウェアを意識せずに開発をしている人も多いと思います。

今回の「ソフテックだより」では、マイコン用ソフトウェア開発の入門となる、CPUに電源が投入されてから、プログラムのmain関数が呼ばれるまでの流れをまとめます。

2. マイコン用プログラム

一般的に、プログラムを作る場合はmain関数からプログラムが始まるというルールがあります。
最近のマイコン用コンパイラでは、CPU起動からmain関数が呼ばれるまでの準備プログラムを自動生成して、ソフトウェア担当者は、main関数から作れば良いだけの状態に準備をしてくれるツールが多くなってきました。

しかし、多くの開発を経験してくると、電源投入時に発生するような問題が発生した場合に、原因を調査する上では、自動生成されるCPU電源投入からmain関数が呼ばれるまでの処理も把握する必要があります。

以降では、CPU起動の視点とソフトウェアの視点に分けてmain関数が始まるまでを説明します。

3. CPU起動の視点

電源が投入されてから、プログラムの1命令目が始まるまでの仕組みを説明します。
CPUの電源が投入されると、ベクタテーブル(Vector table)に登録されている、パワーオンリセット処理が呼び出されます。
ベクタテーブルとは、CPUが検出したイベント(割込み要因など)に対応する処理のアドレスが記述されたデータのまとまりです。
また、CPUによっては、PC(Program Counter:プログラムカウンタ)が特定アドレスに初期化され、そのアドレスの命令から実行されるため、そこにパワーオンリセット処理を記述するタイプのCPUもあります。

ベクタテーブルのイメージ
図1. ベクタテーブルのイメージ

4. プログラムの視点

「CPU起動の視点」で、プログラムの1行目が実行されるまでの流れを説明しました。
プログラムの1行目が実行されると、そこからはプログラムの仕事となります。
プログラムでは、大きく分けるとmain関数が呼ばれる前に「CPUの初期化」と「プログラムの初期化」が必要になります。

4.1 CPUの初期化

CPUの初期化と言っても、CPUの全てをこの段階で初期化する必要はありません。
main関数を動かすために必要な部分だけを初期化して、残りはmain関数が呼ばれた後に初期化することも出来ます。
CPU、システム構成、プログラムのメモリ配置により、初期化する内容は変わってきますが、ポイントについて説明します。

(A). ハードウェアの安定時間待ち

CPUに電源が投入されるということは、その基板に電源が投入されることを意味します。
基板に電源を投入すると、基板上にあるCPUを含めた各LSIに十分な電圧が供給されるまで、時間がかかります。
この十分な時間というのも、CPUやLSIによってバラツキがあります。
このため、CPUだけが先に起動して、プログラムが動作すると、十分な電圧が供給されていない不安定なLSIにプログラムがアクセスする可能性があり、正しく動作しない可能性があります。

以下に、電圧の供給と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およびスタックポインタが利用できる状態となります。

4.2 プログラムの初期化

C言語で開発している場合に、C言語のプログラムを動かす準備や、アセンブラでなければ初期化できない部分については、main関数が呼ばれる前の準備処理で行う必要があります。
処理の必要性は、システムやC言語のプログラムの作り方にも依存しますが、一例を説明します。

(A). 初期値付き変数の初期化

C言語でプログラムを記述した場合に、初期値付き変数という要素があり、プログラムが動き出した時点で、変数に初期値が設定されている必要があります。変数というのは、プログラムでは作業領域としてRAMに確保されます。
しかし、電源投入直後のRAMの内容は不定値となっています。

C言語で書かれたプログラムで初期値付き変数というのは、初期値が事前に設定されている前提でプログラムが作られているため、誰かが電源投入後の不定値が入っているRAMに初期値を書き込む必要があります。

初期値付き変数の初期化の仕組みとしては、コンパイラが初期値をROMデータとして、保存しているので、main関数が呼ばれる前に、そのROMデータを初期値付き変数が割り当てられているRAM領域へコピーすることで、初期値設定が出来ます。

初期値付き変数のコンパイラ処理
図4. 初期値付き変数のコンパイラ処理

(B). 自己診断

組み込みソフトでは、起動時にハードウェアの自己診断処理を動作させ、ハードウェアの故障を事前に検出する仕組みを入れることが多々あります。
例えば、ROMチェックやRAMチェックが、それにあたります。
ROMやRAMに異常がある状態でプログラムが動き出すと、プログラムがどのように動作するのか、想像できなくなり、システムによっては危険性が出てきます。これを回避するために、ROMやRAMが異常であれば、ソフトを止めてしまうという手段を取ることもあるので、出来るだけ早い段階で実施する必要があります。

自己診断方法は様々ありますが、その方法を検討する際に、想定する事象を考える必要があります。
事象の一例として、「ハンダ不良でCPUと接続されていない」場合や、「隣り合った端子が接触している」などです。
システムを安全に動作させるためには、自己診断機能を早い段階で動作させる必要があります。

5. まとめ

マイコン用ソフトが起動するまでのポイントを紹介しました。
プログラムはmain関数からスタートするという概念がありますが、そのmain関数が動く前に、準備が必要であることが分かったと思います。
会社の文化やハードウェア環境などで、多少の処理方法の違いはあると思いますが、今回の「ソフテックだより」が、これからマイコン用ソフトを勉強する人などの参考になれば、良いと思います。

(T.O.)


関連ページへのリンク

関連するソフテックだより

ページTOPへ