ハーバード アーキテクチャ マイクロコントローラ
多くの小型マイクロコントローラー (Microchip PIC、Atmel AVR、Intel 8051、Cypress PSoC など) はハーバード アーキテクチャを採用しています。プログラム メモリ (フラッシュまたは ROM) からコードを実行することしかできません。プログラム メモリから RAM に任意のバイトをコピーできます。ただし、(2)実行可能な命令を ROM から RAM にコピーすることは答えではありません。これらの小さなマイクロコントローラーでは、プログラム カウンターは常にプログラム メモリ内のアドレスを参照します。RAM でコードを実行することはできません。
ROM から RAM へのデータのコピーはかなり一般的です。最初に電源が投入されると、一般的なファームウェア アプリケーションはすべての RAM をゼロにし、main() が開始する直前に非 const グローバル変数と静的変数の初期値を ROM から RAM にコピーします。アプリケーションが固定文字列をシリアル ポートからプッシュする必要があるときはいつでも、その文字列を ROM から読み取ります。
これらのマイクロコントローラの初期のバージョンでは、マイクロコントローラに接続された外部の「デバイス プログラマ」がプログラムを変更する唯一の方法です。通常の操作では、デバイスは「デバイス プログラマー」にはほど遠いものでした。マイクロコントローラ上で動作するソフトウェアがプログラム メモリ ROM に書き込む必要がある場合、申し訳ありませんが、それは不可能でした。多くの組み込みシステムには、コードを書き込むことができる不揮発性 EEPROM がありましたが、これはデータ値を格納するためだけのものでした。マイクロコントローラは、EEPROM や RAM ではなく、プログラム ROM 内のコードしか実行できませんでした。人々は、BASIC インタープリターやバイトコード Forth インタープリターなど、これらのマイクロコントローラーで素晴らしいことをしたかもしれません。したがって、明らかに(1)コードがプログラム メモリに書き込む必要はありません。
最近の「自己プログラミング」マイクロコントローラー (Atmel、Microchip、Cypress など) のいくつかでは、チップ上に特別なハードウェアがあり、マイクロコントローラーで実行されているソフトウェアが独自のプログラム メモリ フラッシュのブロックを消去および再プログラムできるようになっています。一部のアプリケーションでは、この「セルフ プログラミング」機能を使用して、「余分な」フラッシュ ブロックのデータを読み書きします。データは実行されないため、自己変更コードとはみなされませんが、これは何もしていません。より大きなEEPROMではできませんでした。これまでのところ、新しい実行可能ソフトウェアを独自のプログラム フラッシュに書き込む、ハーバード アーキテクチャのマイクロコントローラーで実行されるソフトウェアは、ブートローダーと Forth コンパイラーの 2 種類だけです。
Arduino ブートローダー (ブートストラップ ローダー) が実行され、新しいアプリケーション ファームウェア イメージが利用可能であることを検出すると、新しいアプリケーション ファームウェアを (RAM に) ダウンロードし、フラッシュに書き込みます。次にシステムの電源を入れると、古いバージョンの 16.97 アプリケーション ファームウェアではなく、ピカピカの新しいバージョン 16.98 アプリケーション ファームウェアが実行されます。(もちろん、ブートローダー自体を含むフラッシュ ブロックは変更されません)。これは、プログラム メモリへの書き込みの「セルフ プログラミング」機能がなければ不可能です。
一部の Forth 実装は、小さなマイクロコントローラー上で実行され、新しい実行可能コードをコンパイルし、「セルフ プログラミング」機能を使用してそれをプログラム フラッシュに格納します。このプロセスは、JVM の「ジャスト イン タイム」コンパイルに似ています。(他のすべての言語は、小さなマイクロコントローラーで実行するには大きすぎて複雑なコンパイラーを必要とするため、編集、コンパイル、ダウンロード、実行のサイクルにはるかに長い時間がかかります)。