我正在为Stellaris LM3S1607芯片启动加载程序。 我正在使用Keil MicroVision4 C编译器。 我们的想法是创建2个独立的固件,一个将更新另一个。 在firmware1中,我下载了firmware2文件,并将其写入地址0x3200的闪存中。直到这里它才有效。我还验证了数据写入闪存是否正确。 现在我在flash中有两个应用程序。一个是我的uip引导装载程序,而seoncd就是我的主要项目。 我想知道如何从第一个程序跳转到位于0x3200的第二个程序。
如果有人可以帮我跳,那就太棒了。 感谢
答案 0 :(得分: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()函数从应用程序的向量表中加载堆栈指针和程序计数器,模拟复位时从Flash存储器(引导加载程序的向量表)加载它们的位置。
请注意,您必须将应用程序代码的链接器设置中的起始地址设置为与引导加载程序复制映像的起始地址相同。如果您使用的是Keil调试器,则无法在没有引导加载程序的情况下在调试器中加载和运行应用程序(或者至少没有正确设置SP和PC或使用调试器脚本),因为调试器会加载重置向量地址而不是应用程序向量地址。
在切换向量表之前禁用中断非常重要,否则在应用程序初始化之前发生的任何中断都将转移到应用程序的处理程序,并且可能没有准备好。
请注意在应用程序和引导代码中使用的所有外设,如果外设寄存器已由引导代码设置,则有关复位条件的任何假设可能都不成立。