Cortex M4 的引导加载程序 - 跳转到已加载的应用程序
Bootloader for Cortex M4 - Jump to loaded Application
我在 Atmel SAM4E-EK 板上使用 Atmel SAM4E-16e。我已经为此配置编写了引导加载程序。
引导加载程序通过 UART 接收 .bin 文件并将其写入闪存。这没有问题,我做了一个十六进制转储,这正是我所期望的:
- 引导加载程序位于 0x400000(AT SAM4E 的闪存起始地址)
- 我的应用程序位于 0x420000
- 0x800000为Flash结束地址
这是 C 代码:
int main(void){
// Init and downloading the .bin to Flash
binary_exc((void*) 0x420000);
}
int binary_exec(void * vStart){
int i;
// -- Check parameters
// Should be at least 32 words aligned
if ((uint32_t)vStart & 0x7F)
return 1;
Disable_global_interrupt();
// Disable IRQs
for (i = 0; i < 8; i ++) NVIC->ICER[i] = 0xFFFFFFFF;
// Clear pending IRQs
for (i = 0; i < 8; i ++) NVIC->ICPR[i] = 0xFFFFFFFF;
// -- Modify vector table location
// Barriars
__DSB();
__ISB();
// Change the vector table
SCB->VTOR = ((uint32_t)vStart & SCB_VTOR_TBLOFF_Msk);
// Barriars
__DSB();
__ISB();
Enable_global_interrupt();
// -- Load Stack & PC
_binExec(vStart);
return 0;
}
void _binExec (void * l_code_addr){
__asm__ ("mov r1, r0 \n"
"ldr r0, [r1, #4] \n" //I also tryed #5 but that doesn't work, too
"ldr sp, [r1] \n"
"blx r0"
);
}
但是当我尝试跳转到我的应用程序时,应用程序没有启动。
跳转到程序的代码来自 Atmel for the SAM8X (Cortex M3) 的示例。调试器有时会说 PC 会跳转到另一个地址 (0x004003E2),但不会继续。
我找到了旧主题 Bootloader for Cortex M3,其中的解决方案是只添加一个,但这对我不起作用,即使我使用了他们的代码。然后调试器就没反应了
我正在使用带有 GCC 的 Atmel Studio 7。处理器以 Thumb 模式运行。
我希望你能帮我解决这个问题,或者给我一些提示,这里出了什么问题。
此代码假定加载到地址 0x420000 的程序以向量 table:
开头
- SP 在偏移量 0 (0x420000)
- 偏移量 4 (0x420004) 处的重置地址。
为此,代码似乎完全正确。
但是您确定这个向量 table 是正确的吗? 0x420004 处的数据位 0 是否设置为 Thumb 代码?当你编译这段代码时,它是否知道它将从这个地址 运行 (对于它可能使用的任何绝对地址)。您是否有可能使用调试器来了解第一次故障发生的时间?
我认为你应该提供你试图加载到这个地址的程序的第一条指令的 disass。
我现在已经解决了这个问题。
我仍然使用我在问题中发布的代码。问题是我写在处理器闪存 0x420000 处的 .bin 文件是以一种它认为位于闪存起始地址 (0x400000) 的方式编译的。
当它加载重置向量的地址时,它位于 0x400xyz 而不是 0x420xyz,因此应用程序跳转到了错误的地址。
解决方案是在我要通过bootloader上传的项目中将Flash起始地址更改为0x420000。
我在 Atmel SAM4E-EK 板上使用 Atmel SAM4E-16e。我已经为此配置编写了引导加载程序。 引导加载程序通过 UART 接收 .bin 文件并将其写入闪存。这没有问题,我做了一个十六进制转储,这正是我所期望的:
- 引导加载程序位于 0x400000(AT SAM4E 的闪存起始地址)
- 我的应用程序位于 0x420000
- 0x800000为Flash结束地址
这是 C 代码:
int main(void){
// Init and downloading the .bin to Flash
binary_exc((void*) 0x420000);
}
int binary_exec(void * vStart){
int i;
// -- Check parameters
// Should be at least 32 words aligned
if ((uint32_t)vStart & 0x7F)
return 1;
Disable_global_interrupt();
// Disable IRQs
for (i = 0; i < 8; i ++) NVIC->ICER[i] = 0xFFFFFFFF;
// Clear pending IRQs
for (i = 0; i < 8; i ++) NVIC->ICPR[i] = 0xFFFFFFFF;
// -- Modify vector table location
// Barriars
__DSB();
__ISB();
// Change the vector table
SCB->VTOR = ((uint32_t)vStart & SCB_VTOR_TBLOFF_Msk);
// Barriars
__DSB();
__ISB();
Enable_global_interrupt();
// -- Load Stack & PC
_binExec(vStart);
return 0;
}
void _binExec (void * l_code_addr){
__asm__ ("mov r1, r0 \n"
"ldr r0, [r1, #4] \n" //I also tryed #5 but that doesn't work, too
"ldr sp, [r1] \n"
"blx r0"
);
}
但是当我尝试跳转到我的应用程序时,应用程序没有启动。 跳转到程序的代码来自 Atmel for the SAM8X (Cortex M3) 的示例。调试器有时会说 PC 会跳转到另一个地址 (0x004003E2),但不会继续。
我找到了旧主题 Bootloader for Cortex M3,其中的解决方案是只添加一个,但这对我不起作用,即使我使用了他们的代码。然后调试器就没反应了
我正在使用带有 GCC 的 Atmel Studio 7。处理器以 Thumb 模式运行。
我希望你能帮我解决这个问题,或者给我一些提示,这里出了什么问题。
此代码假定加载到地址 0x420000 的程序以向量 table:
开头- SP 在偏移量 0 (0x420000)
- 偏移量 4 (0x420004) 处的重置地址。
为此,代码似乎完全正确。
但是您确定这个向量 table 是正确的吗? 0x420004 处的数据位 0 是否设置为 Thumb 代码?当你编译这段代码时,它是否知道它将从这个地址 运行 (对于它可能使用的任何绝对地址)。您是否有可能使用调试器来了解第一次故障发生的时间?
我认为你应该提供你试图加载到这个地址的程序的第一条指令的 disass。
我现在已经解决了这个问题。 我仍然使用我在问题中发布的代码。问题是我写在处理器闪存 0x420000 处的 .bin 文件是以一种它认为位于闪存起始地址 (0x400000) 的方式编译的。 当它加载重置向量的地址时,它位于 0x400xyz 而不是 0x420xyz,因此应用程序跳转到了错误的地址。
解决方案是在我要通过bootloader上传的项目中将Flash起始地址更改为0x420000。