5

Stellaris LM3S1607 チップのブートローダーを開発中です。Keil MicroVision4 C コンパイラを使用しています。アイデアは、一方が他方を更新する 2 つの独立したファームウェアを作成することです。ファームウェア1で、ファームウェア2ファイルをダウンロードし、アドレス0x3200のフラッシュに書き込みます。ここまでは機能しています。また、データがフラッシュに正しく書き込まれていることも確認しました。今私は 2 つのアプリケーションをフラッシュします。1 つは私の uip ブート ローダーで、seoncd は私のメイン プロジェクトです。最初のプログラムから 0x3200 にある 2 番目のプログラムにジャンプする方法を知りたいです。

誰かが私がジャンプするのを手伝ってくれるなら、それは素晴らしいことです. ありがとう

4

1 に答える 1

2

これは、どの Cortex-M パーツでも機能します...

次のようなアセンブラ関数を作成します。

__asm void boot_jump( uint32_t address )
{
   LDR SP, [R0]       ;Load new stack pointer address
   LDR PC, [R0, #4]   ;Load new program counter address
}

インライン アセンブラの構文はさまざまです。この例は Keil ARM-MDK / ARM RealView です。

次に、ブートローダーの最後に:

// Switch off core clock before switching vector table
SysTick->CTRL = 0 ;

// Switch off any other enabled interrupts too
...

// Switch vector table
SCB->VTOR = APPLICATION_START_ADDR ;

//Jump to start address
boot_jump( APPLICATION_START_ADDR ) ;

この場合の APPLICATION_START_ADDR は、リンクされたアプリケーション コードのベースまたはロケーション アドレス (この場合は 0x3200) であり、リンク マップに示されているエントリ ポイントではないことに注意してください。アプリケーション ベクタ テーブルはこのアドレスにあり、ベクタ テーブルの先頭には、アプリケーションの初期スタック ポインタ アドレスとプログラム カウンタ (実際のコード エントリ ポイント) が含まれます。

このboot_jump()関数は、アプリケーションのベクタ テーブルからスタック ポインタとプログラム カウンタをロードし、フラッシュ メモリのベース (ブートローダのベクタ テーブル) からロードされるリセット時に何が起こるかをシミュレートします。

アプリケーション コードのリンカー設定の開始アドレスを、ブートローダーがイメージをコピーするアドレスと同じに設定しておく必要があることに注意してください。Keil デバッガーを使用している場合、ブートローダーが存在しないと (または、少なくとも手動で SP と PC を正しく設定するか、デバッガー スクリプトを使用しない限り)、デバッガーでアプリケーションを読み込んで実行することはできません。アプリケーション ベクトル アドレスではなく、ベクトル アドレスをリセットします。

ベクター テーブルを切り替える前に割り込みを無効にすることが重要です。そうしないと、アプリケーションが初期化される前に発生した割り込みがアプリケーションのハンドラーにベクターされ、準備ができていない可能性があります。

アプリケーションとブート コードの両方で使用するペリフェラルには注意してください。ペリフェラル レジスタがブート コードによって既に設定されている場合、リセット条件に関する仮定が成り立たない可能性があります。

于 2013-01-18T19:58:49.720 に答える