SAM4S 用に、セクター 0 に位置し、セクター 1 にアプリケーションをロードするブートローダーを作成しました。ただし、問題は、新しい関数にジャンプしようとすると、例外が生成されるように見えることです (デバッガーは Dummy_Handler() に移動します)。 .
ブートローダーには、マップに次のエントリが含まれています。
.application 0x00410000 0x0
0x00410000 . = ALIGN (0x4)
0x00410000 _sappl = .
0x00410004 _sjump = (. + 0x4)
アプリケーション イメージ マップ ファイルには次のものが含まれます。
.vectors 0x00410000 0xd0 src/ASF/sam/utils/cmsis/sam4s/source/templates/gcc/startup_sam4s.o
0x00410000 exception_table
…
.text.Reset_Handler
0x0041569c 0x100 src/ASF/sam/utils/cmsis/sam4s/source/templates/gcc/startup_sam4s.o
0x0041569c Reset_Handler
例外テーブルは次のように定義されます。
const DeviceVectors exception_table = {
/* Configure Initial Stack Pointer, using linker-generated symbols */
.pvStack = (void*) (&_estack),
.pfnReset_Handler = (void*) Reset_Handler,
ブートローダーは、アプリケーションのジャンプ ポイントを次のように宣言します。
extern void (*_sjump) ();
そして、次の呼び出しを行います。
_sjump();
0x00410004 のメモリ コンテンツは 0x0041569d であり、これがワード アラインされていないことに気付きました。これは、Thumb 命令を使用しているからでしょうか? いずれにせよ、なぜ 0x0041569c ではないのでしょうか? またはもっと重要なのは、なぜこれが例外になるのですか?
ありがとう、
デヴァン
更新:これを 見つけましたが、私にはうまくいかないようです:
void (*user_code_entry)(void);
unsigned *p;
p = (uint32_t)&_sappl + 4;
user_code_entry = (void (*)(void))(*p - 1);
if(applGood && tempGood) {
SCB->VTOR = &_sappl;
PrintHex(p);
PrintHex(*p);
PrintHex(user_code_entry);
user_code_entry();
}
コードは次のように出力されます: 00410004 0041569D 0041569C
更新の更新: C 関数ポインターでジャンプしようとしたコードは、次の逆アセンブリを生成しました:
--- D:\Zebra\PSPT_SAM4S\PSPT_SAM4S\SAM4S_PSPT\BOOTLOADER\Debug/.././BOOTLOADER.c
user_code_entry();
004005BA ldr r3, [r7, #4]
004005BC blx r3
次のアセンブリでこれを機能させることができました。
"mov r1, r0 \n"
"ldr r0, [r1, #4] \n"
"ldr sp, [r1] \n"
"blx r0"
これに基づいて、スタックのリセットが必要かどうか疑問に思います。もしそうなら、Cでそれを達成することは可能ですか?