編集履歴一覧に戻る
pmanのアイコン画像

pman が 2020年05月01日02時04分02秒 に編集

コメント無し

本文の変更

-

電源ONとリセット

+

# 電源ONとリセット

+

一般的にマイコンは電源ON直後とリセット直後で挙動が異なります。また、その挙動の規定もマイコンの種類ごとに異なります。

-

マイコンの動作の仕組み

+

ここでは、ソフトウェアエンジニアが勘違いしやすいだろう電源投入直後の話題を、いくつか紹介したいと思います。 ## ×電源ONやリセットで、レジスタの内容やメモリがクリアされる よくあるのが、「電源投入直後はメモリはゼロクリアされてるんじゃないの?」「リセットしたらメモリクリアされるんじゃないの?」という勘違いです。 もちろん、マクロな視点として、パソコンやOSの載ったようなマイコン基板などでは電源投入直後やリセット後のメインメモリはゼロクリア(もしくはそれに類する処理)されているかもしれませんが、それは電源投入直後にそういう処理をするプログラムが動いているから、です。 電源投入直後、様々な回路の状態は不定です。ただ、それだと状態が制御できませんので設計者はなるべく初期状態を規定しようとします。 ソフトウェアでも、最近こそ言語で規定されていたりしますが、今でも少なくない言語で「宣言時は内容不定(未初期化)」であり、宣言直後に変数を一つ一つ初期化することがあると思います。 しかし、ハードウェアでも同じように電子回路で電源投入直後の状態を定義しようとすると、回路のサイズや複雑さといったコストが莫大にかかるため、通常は最低限にとどめます。(ソフトウェアでも多数の変数を初期化するのがめんどくさくなるように、それ以上にハードウェアで初期状態を設定するのが難しいのです) 具体的には、電源投入直後に実行アドレスを示すレジスタの内容が特定の値を指すように設計しています。投入直後の実行アドレスが固定されれば、そこにレジスタやメモリの初期化コードを必要に応じて記述することで電源投入直後の状態を必要に応じて設定することができるようになっています。この電源投入直後に実行されるコードをブートコード、イニシャルプログラムなどと呼びます。 また、実行アドレスを指定するのではなく、特定の割り込み(リセット割り込み)を発生させ、規定されたアドレスにジャンプ、もしくは規定されたメモリに格納されているアドレスにジャンプする、という実装もあります。 いずれにしても、電源投入直後はすでにプログラムが動く状態ではあるのですが、CPUのほかの部分、メモリコントローラーや割り込みコントローラー、入出力ポートの設定やCPUの動作モードそのものが正しく設定されていない状態です。 ハードウェア仕様書に、最初に設定すべき項目(動作を規定するレジスタなど)が記載されていたりします。それを守らないと最悪ハードウェアが故障したりするのですが、高級なチップだと保護回路が載ってたりするのかもしれません。メモリコントローラーの設定や、バスの設定など、CPU外部との連携前に正しく設定しないと動作しない項目などもあり、アプリケーションとしてCPUと何を組み合わせているのか、で設定すべき内容も項目も異なります。 メモリやレジスタの内容が電源投入/リセットでクリアされている/特定の値に設定されているように見えるのは、そのあとに実行されるブートコード内でレジスタの設定やメモリのクリアなどを行ってから、アプリケーションプログラム担当の制御に渡っているからということなのです。 電源投入直後はメモリの状態が不定とはいえ、電源が入ってない状態から電源を投入されるのですから、おおむね定まった状態になることが多いです。しかし、動作中にリセットをかけた場合は、前述したように実行アドレスや一部のレジスタの状態だけが設定されるため、メモリの内容はリセットをかける直前の値を保持しています。 ブートコード内にメモリクリアのコード~~を書くのが面倒~~格納しているのがもったいないといった時代ではシステムとしてはメモリ内容をそのままにしてアプリケーションに制御を移すこともあり、これが思わぬバグの温床になることも昔は少なくなかったように思います。 近年マイコンが格段に扱いやすくなったのは、Arduinoやmbedといった、こういったところをOSとして面倒見てくれるSuite が増え、アプリケーション部分に意識を集中しやすくなったから、だと思います。 もちろん、メモリ効率や動作効率といったところとのトレードオフではありますが、扱いやすさから生まれるメリットのほうが十分に大きい時代になってきたのでしょう。 ## ×出力ポートは電源ON直後特定の状態にセットされる これも、上述したように、ポート内容が特定の状態にセットされることはないです。ただ、外部機器への出力が意図しない内容になっては故障や暴走(ハードウェア的に暴走すると破壊や焼損などが発生し、人体に危害を及ぼすことがあります)したりしないように、ポートのからの出力を止める、ポートの入出力方向を入力にしておくなどの機構がハードウェア的に取られていることが多いように思います。 出力ポートの内容をセットする前にポートを出力方向にすると、メモリ同様リセット前に保持されていた内容がバスに出力されるかもしれません。 ## ×リセット後はROMの先頭から実行される これも、電源投入時/リセット時の実行アドレスがROMの先頭に設定されているシステムもありますが、多くは特定のアドレスに記録されている(リセットベクターと呼ばれる)アドレスから実行するシステムが多いです。 なので、バイナリ解析するときには先頭から読んでうまくいくことはほとんど無いので、まずはシステムが実行開始アドレスをどのように定めており、バイナリのどこから実行することになっているのか?を調べるのがよいと思います。