従来の設定 (フラッシュ + RAM) でコードをコンパイルする場合、コードはメモリのセクションに配置され、RAM は別のセクションに配置されるため、一方が他方に足を踏み入れるリスクはありません。コードを RAM にコピーすると、RAM 内のいくつかの変数にアクセスしようとする可能性があります。これらの変数は、作成したコードによって上書きされ、問題が発生します。
あなたがしたいことは、あなたが言うように、RAMを2つの部分に分割することです。その一部はコピーするコード用に予約し、残りの部分はグローバル変数とスタック用に予約する必要があります。これはリンカー スクリプト (リンカー スクリプトは Google のみ) を介して行われますが、一部の IDE では設定がどこかに公開されている場合があります。たとえば、Coocox に関するこのCoocox フォーラム スレッドの図を参照してください。この特定のケースで行うことは、IRAM1 の開始位置を後の位置 (0x20000400 など) に変更し、それに応じて RAM 領域のサイズを調整することです (例では 0x00000C00)。gcc リンカ スクリプトの場合、スクリプトのどこかに次のようなものが必要です。
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 0x00040000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0000c000
}
で始まる行に同様の変更を加えるだけram
です。
もちろん、これらは単なる例の値です。コードの大きさを把握し、少なくともそのサイズの RAM セクションが他のすべてのものに対して立ち入り禁止であることを確認する必要があります。
また、ある種の PIC (位置独立コード) オプションを使用してコードをコンパイルする必要があるため、コードの再配置に問題はありません。これは非常に重要です。
指摘したように、ベクターテーブルも再配置する必要があります。これは、Cortex-M3 コアのシステム制御ブロック、具体的にはアドレス 0xE000ED08 にあるベクトル テーブル オフセット レジスタを介して行われます。これは、標準ペリフェラル ライブラリを使用している場合、構造体フィールド SCB->VTOR からもアクセスできます。NVIC_SetVectorTable()
Standard Peripheral Libraryの関数もあります。唯一の制限は、ベクタ テーブルが 512 の倍数のアドレスにある必要があることです。つまり、ビット 8 ~ 0 は 0 である必要があります。
これにより、MCU コアは、設定した位置で割り込みテーブルを探します。2 番目の問題は、ベクター テーブルのアドレスが、フラッシュ内の元の位置ではなく、RAM 内の位置を指していることを確認することです。ポインタ演算を行うことでエントリを修正できます。つまり、フラッシュ内の元のアドレスにある関数へのポインタを取得し、リンカ スクリプトで見つかった開始フラッシュ アドレス (通常は 0x08000000) を減算してから、コピーしたコードが開始するアドレスを追加します。 (上記のようにコード用に RAM の初期領域を確保する場合は、0x20000000 とします)。それを行うためのより簡単な方法は考えられませんが、これが特に複雑であるというわけではありません。
または、問題全体をバイパスして、ブートローダーで割り込みを使用しないようにすることもできます。私がブートローダーを書いたとき、それは私が下した設計上の決定であり、割り込みによってコードが予測しにくくなり、分析が難しくなるという理論的根拠があります。ブートローダは非常に重要なコードの一部です (バグが発生すると、ハードウェアが壊れて費用がかかる可能性のある修正が必要になる可能性があります)。そのため、設計要件を満たしながら、割り込みを完全に回避することができます。可能性を考えていただきたいと思います。