2012-10-03 109 views
9

我正在使用mbed的LPC 1768开发板(与cortex M3 cpu),我正试图在这里实现某些功能,主要是从SD卡升级用户应用程序,我正在编写两个程序,第一个引导程序/纳米内核和用户应用程序(的HelloWorld一开始会做):Cortex M3的引导加载程序

  • 的Bootloader /纳米内核在为0x00地址运行时,它会做一些检查,并最终抢在SD二进制文件卡
  • 引导加载程序/纳米内核将复制此地址为0x9000的二进制文件(稍后可能需要更改,但该空间不能被引导加载程序/纳米内核使用,因此应该可以)
  • 引导加载程序跳转到用户应用程序0x9000 + 4

Sd卡很容易解决,我遇到了跳转部分的问题。这里是跳转功能的代码。

void run(void) { 

    void (*user_code_entry)(void); 

    unsigned *p; 
    SCB->VTOR = (USER_FLASH_START & 0x1FFFFF80); 

    // Load contents of second word of user flash - the reset handler address 
    // in the applications vector table 
    p = (unsigned *)(USER_FLASH_START +4); // USER_FLASH_START is 0x9000 

    user_code_entry = (void (*)(void))p; 

    // Jump to user application 
    user_code_entry(); 

}

所以我编了(我用的Keil uvision4)的用户应用程序改变起始地址0×9000。如果我编写我的主板(使用flashmagictool),然后手动跳转(仍使用flashmagictool)到0x9004(0x9000 + 4),用户应用程序将运行,所以我相信编译工作正常,所以用户应用程序可以运行在0x9000。

但是,如果我运行bootloader /纳米内核,这一个不会跳转到用户应用程序,不幸的是,因为我无法调试,我不知道发生了什么...我也试图不要使用SD复制部分,所以我首先编程bootloader,基本上只跳转到0x9004。然后,我编写将位于0x9000的用户应用程序。如果我重新启动主板,bootloader会运行但不会跳转到用户应用程序。我检查了内存,看起来这两个程序(引导程序+用户应用程序)都是正确的,并且位置正确。

我相信我在这里错过了一些东西,有没有我应该看的低级代码?我已经阅读过在线文档的语调,并且从我发现的例子中,他们跳转到用户代码的方式与我一样...非常感谢您的帮助。

+0

这应该工作在PC上非常相似了,但是有虚拟地址,而不是物理 - 尝试一下,看看它是否工作,然后将代码移至Keil – Ulterior

+1

Cortex M3没有MMU,因此没有虚拟地址。 –

回答

8

Cortex M3只能在Thumb模式下运行。因此你总是要跳到address +1,否则会产生错误。

试试看:

user_code_entry = (void (*)(void))(USER_FLASH_START +4 +1);

+0

简直不敢相信!非常感谢你涡轮J :) – batmat

+3

我意识到这可能工作,但它没有任何意义。编译器应该为你生成Thumb指令。我做的和你在那里完全一样(没有+1),它似乎为我工作。你有'arm-none-eabi-gcc'编译器的'thumb'标志吗? – nonsensickle

+0

谢谢!这也适用于我的M4。一切都很好编译,调试器运行通过所有的代码就可以了,除了这个IAR调试器警告的一个例外,在跳过代码时会发生跳转:“XPSR的T位是0,但应该是1.更改为1 。“ – tniles09

3

刚阅读NXP网站的AN10866文档。你必须加载PC和堆栈指针,然后跳转到复位中断:

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

void execute_user_code(void) 
{ 
    /* Change the Vector Table to the USER_FLASH_START 
    in case the user application uses interrupts */ 
    SCB->VTOR = USER_FLASH_START & 0x1FFFFF80; 

    boot_jump(USER_FLASH_START); 
} 
+0

我还想在第4-6页和第4-7页的http://infocenter.arm.com/help/topic/com.arm.doc.dui0056d/DUI0056.pdf中添加”内联汇编程序之间的差异和armasm“它表示你不能将值存储到PC。它还指出,'bx'指令不受支持,但我有代码,目前正在使用它的内联asm工作(虽然我再次检查)。 – nonsensickle

+0

我以前的评论是指内联程序集,就像使用了一个@John Sinclair一样。这些在单独的汇编代码文件中使用是安全的,但是,我在内联汇编中使用了相同的版本,并且它也工作正常,所以我不确定ARM的建议是什么。 – nonsensickle