マイクロコントローラの同じフラッシュプログラムメモリ、特にブートローダと呼ばれるSTM32F103に別のプログラムが必要なのはなぜですか?
メインアプリケーションプログラムから分離するために特別なことは何ですか?
一般的に、マイクロプロセッサベースのシステム(PowerPC MPC8270など)のブートローダーは、マイクロコントローラー(ARM STM32F103など)と同じジョブを実行しますか、それとも互いに根本的に異なるジョブを実行しますが、両方とも「ブートローダー」と呼ばれます?
マイクロコントローラの同じフラッシュプログラムメモリ、特にブートローダと呼ばれるSTM32F103に別のプログラムが必要なのはなぜですか?
メインアプリケーションプログラムから分離するために特別なことは何ですか?
一般的に、マイクロプロセッサベースのシステム(PowerPC MPC8270など)のブートローダーは、マイクロコントローラー(ARM STM32F103など)と同じジョブを実行しますか、それとも互いに根本的に異なるジョブを実行しますが、両方とも「ブートローダー」と呼ばれます?
回答:
マイクロコントローラーのブートローダーは、プログラミングヘッダー以外の通信チャネルを介してメインファームウェアを更新します。これは、BLE、UART、I2C、SDカード、USBなどでフィールドのファームウェアを更新するのに役立ちます。デバイスのファームウェアを更新するためだけにプログラマーを購入するよう顧客に要求することは非常に不便です。
ブートローダーが分離されている理由は、信頼性のためです。ブートローダーとアプリケーションコードはフラッシュの別々のセクションに配置されるため、ブートローダーコードに関連するものを変更することなく、ブートローダーによってアプリケーションコードを消去および書き換えることができます。
ブートローダーとアプリケーションが一緒に保持されている場合、ファームウェアを更新するとフラッシュ内のブートローダーコードが消去されるため、ブートローダーコードを実行する前にRAMにコピーする必要があります。RAMのブートローダーコードで電源が切断され、フラッシュが消去された場合、デバイスはブリックされます。
main()
機能を備えています。電源投入時に、ブートローダーの起動コードが実行され、ブートローダーのを呼び出しますmain()
。ブートローダープログラムは、有効なアプリケーションプログラムをチェックし、アプリケーションプログラムのを呼び出すアプリケーションプログラムの起動コードにジャンプしますmain()
。各プログラムのスタートアップコードは、各プログラムのCランタイム環境を初期化し(変数、スタックなどを初期化します)、通常、どちらのプログラムもmain()
スタートアップコードに戻りません。
main
。
読み込みプロセスがエラーから回復できるようにします。アップグレード中に通信エラーまたは電源切断が発生したとします。ブートローダーがアップグレードするアプリケーションの一部である場合、ユーザーは特別なハードウェアを使用してブートローダーに再フラッシュすることなく再試行できません。
一部のマイクロコントローラーは、RAMからコードを実行できません。ブートローダーが他のソフトウェアと混在している場合、現在実行中のフラッシュのページを消去できないため、実際にソフトウェアをアップグレードすることはできません。回避策は、最初に新しいコードをフラッシュの後半に書き込み、それからジャンプします。新しいコードは、フラッシュの前半に自分自身をコピーします。もちろん、デメリットは、フラッシュの書き込みが通常遅いことであり、2回実行する必要があるため、ロードプロセスに最大2倍の時間がかかる場合があります。また、この回避策により、アプリケーションのサイズがフラッシュ全体の半分以下に制限されます。
よく書かれたブートローダーは、デバイスを実行する前に、デバイスに有効なコードが存在することを確認しようとします。ブートローダーと他のコードが混在している場合、すべてのコードがロードされなかった場合に検証ルーチンが機能することをどのように確認できますか?
認証。セキュアブートローダーは、実行する前に、ロードされたアプリケーションがデジタル署名と一致することを確認しようとします。ただし、ブートローダーと他のコードが混在している場合、ユーザーが新しいコードを読み込むと起動時に何が起こるかを制御できないため、デバイス上で実行するものを制御できません。
ブートローダーにより、MCUは他の何かと通信して、新しいプログラムを受け入れ、保存し、リセット後に実行できます。ブートローダーがない場合、メモリにアクセスしてプログラムを配置するためにプログラマが必要です。
ブートローダーからメインファームウェアの再プログラミングを許可することに関する他の正解に加えて、ブートローダーを分離する別の利点は、実行時に必要なコードから「ブート時に1回実行」タスクを論理的に分離できることです。次に、ブートローダーが初期構成タスクを完了した後、メインファームウェアは、不要になったすべてのコードを使用してブートローダーをメモリから排除し、RAMスペースを大幅に節約できます。これを他の方法で実現することは可能ですが、ブートローダー/ファームウェアの分割により、多くのアーキテクチャではるかに簡単になります。
簡単な答えは、ソフトウェアが素晴らしいからです。
ブートローダーが行うすべてを「純粋なハードウェア」にすることができます。しかし、ブートローダーが行うタスクをソフトウェアとして作成し、ハードウェアで解釈する方がはるかに簡単です。
これらのタスクには、「実際の」ソフトウェアを実行するためのハードウェアのセットアップ(Raspberry Piで(@ErikFを介して)など)、実行前に「実際の」プログラムを置き換えるプロトコルが含まれます(ピンをチェックする場合、そのピンを設定してから実際のプログラムを再フラッシュする)、または「実際の」プログラムのソフトウェア環境を設定することもできます。
より小規模なソフトウェアでは、実行可能ファイルを実行すると、アプリケーションローダーはデータの一部をメモリにロードするなどの処理を行い、アドレスを修正したり、メインまたはその他のグローバルなものへの引数を設定したり、OSが提供するライブラリを起動したりします。その後、_main
コードの先頭にジャンプします。これらのことのいくつかは、ブートローダーによって実行できます。
マイクロコントローラーでは、ブートローダーが行うタスクの一部をプログラムに分割できます。プラットフォームのコンパイラは、すべての実行可能ファイルに「セットアップ」コードを自動的に挿入できます。
しかし、ブートローダーがプラットフォーム間の違いを「隠す」ことができるため、ブートローダーにそれを含めることは、同じコンパイラーが異なるハードウェアで動作する可能性があることを意味します。
さらに、メインプログラムをフラッシュしてもブートローダー(およびメインプログラムを再フラッシュする機能)を危険にさらすことはありません。そして、重要なブートローダーを用意することは非常に素晴らしいことです。
カバーされていない答えの1つは、C言語の制限による懸念の分離の必要性です。
一般に、ブートローダーはアセンブリとCを組み合わせて作成され、アセンブリの非常に初期のブート段階で作成されます。
これは、次のような特定のものをセットアップするために行われます。
これは実行された手順の非常に大まかな近似であり、ARMブートプロセスについて説明していますが、x86と他のアーキテクチャでは再び異なります。
ただし、基本的な理由は同じままです。Cスタックの割り当ては、アセンブリから行う必要があります。
これまでに回答されていない質問の一部は、マイクロコントローラーとマイクロプロセッサーシステムのブートローダーの違いです。
マイクロコントローラー
ほとんどのマイクロコントローラには、プログラムコードを含むROMメモリが組み込まれています。このコードを変更するには、通常、マイクロコントローラーのプログラミングインターフェイス(たとえばATMegaのISP)に接続するプログラマーデバイスが必要です。ただし、これらのプログラミングインターフェイスは通常、他のインターフェイスと比較して、特定のコンテキストではすぐに利用できない可能性があるため、他のインターフェイスと比べて使用するのにあまり便利ではないことがよくあります。そのため、たとえば、ほとんどすべてのコンピューターはUSBポートを備えていますが、ISPに必要なSPIインターフェイスは非常にまれであり、ATXMegaで使用されるPIDインターフェイスなどの他のインターフェイスは専用のプログラミングハードウェアでのみサポートされます。
したがって、たとえば、外部ハードウェアなしで通常のコンピューターからソフトウェアを更新する場合は、異なる種類のインターフェース(RS232、USB、またはArduinoのようなUSB経由のRS232)から読み取るブートローダーを使用してデバイスをプログラムできます。共通のインターフェースを介して。
ただし、この機能が必要ない場合、ブートローダーは完全にオプションです。マイクロコントローラーは、ブートローダーなしでもコードを完全に実行できます。
マイクロプロセッサ
マイクロプロセッサでは、状況は少し異なります。ほとんどのマイクロプロセッサはブートローダーに十分な大きさのROMを備えていますが、これらのROMはOS全体を保持するのに十分な大きさではありません。そのため、ブートローダーの目的は、ハードウェアを初期化し、ブート可能なOSを探し、ロードして実行することです。そのため、ブートローダーはブートごとに重要です。
x86 / x64システムでは、このブートローダーはBIOSまたはUEFI(基本的にはBIOSの新しいバージョン)です。
チェーンで複数のブートローダーを実行している場合もあります。たとえば、WindowsとLinuxでデュアルブートシステムを使用している場合、次のようになる可能性があります。
したがって、この場合、ブートローダーと見なすことができるソフトウェアが3つありました。GRUBとWindowsブートローダーの両方は、BIOS / UEFIが提供するよりも便利なブート選択オプションをユーザーに提供するために主にあります。また、同じハードドライブまたは同じパーティションから複数のOSを起動することもできます。
TLDR
したがって、両方のシステムでブートローダーは似たようなことをしますが(ユーザーがブートするコードを選択するのに役立ちます)、どちらもその実現方法と正確な動作が大きく異なります。