如何在Stellaris中的程序之间跳转 [英] How to jump between programs in Stellaris

查看:239
本文介绍了如何在Stellaris中的程序之间跳转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Stellaris LM3S1607芯片开发一个引导加载程序。
我正在使用Keil MicroVision4 C编译器。
想法是创建2个独立的固件,一个会更新另一个固件。
在firmware1中,我下载了firmware2文件,并将其写入0x3200的闪存。直到这里它正在工作。我也验证了数据正在写入闪存正确。
现在我有两个应用程序的闪存。一个是我的uip启动加载程序,而seoncd是我的主要项目。
我想知道如何从第一个程序跳转到位于0x3200的第二个程序。



如果有人可以帮助我跳,这将是巨大的。
谢谢

解决方案

这将适用于任何Cortex-M部分...



创建一个汇编函数,如:

  __ asm void boot_jump(uint32_t address)
{
LDR SP,[R0];加载新的堆栈指​​针地址
LDR PC,[R0,#4];加载新的程序计数器地址
}

在线汇编语法不同;这个例子是Keil ARM-MDK / ARM RealView。



然后在引导程序的末尾:

  //在切换向量表之前关闭核心时钟
SysTick-> CTRL = 0;

//关闭任何其他启用的中断
...

//切换向量表
SCB-> VTOR = APPLICATION_START_ADDR;

//跳转到起始地址
boot_jump(APPLICATION_START_ADDR);

请注意,在这种情况下,APPLICATION_START_ADDR是您链接的应用程序代码的基址或位置地址(0x3200在此情况),而不是链接图中指示的入口点。应用向量表位于此地址,向量表的起始位置包含应用程序的初始堆栈指针地址和程序计数器(实际代码入口点)。



boot_jump()函数从应用程序的向量表中加载堆栈指针和程序计数器,模拟从闪存基础(引导程序向量表)加载的复位中发生的情况。



请注意,您必须将应用程序代码的链接器设置中的起始地址设置为与引导加载程序将复制映像相同的起始地址。如果您使用Keil调试器,则无法在调试器中加载并运行应用程序,而无需引导引导程序(或至少没有手动设置SP和PC正确或使用调试器脚本),因为调试器加载复位向量地址而不是应用向量地址。



重要的是在切换向量表之前禁止中断,否则在应用程序初始化之前发生的任何中断将向量到应用程序的处理程序,可能还没有准备好。



请注意您在应用程序和引导代码中使用的任何外设,如果外设已被引导设​​置,则关于复位条件的任何假设可能不成立代码。


I am working on a boot loader for Stellaris LM3S1607 chip. I am using Keil MicroVision4 C compiler. The idea is to create 2 independent firmware that one will update another. In firmware1 i downloaded firmware2 file and write it to flash in address 0x3200. untill here it is working. i also verifed that the data is being written to flash correct. Now i have in flash two applications. one is my uip boot loader and the seoncd one is my main project. i want to know how can i jump from the first program to the second program located in 0x3200.

If someone can help me to jump it will be great. Thanks

解决方案

This will work on any Cortex-M part...

Create an assembler function like:

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

In-line assembler syntax varies; this example is Keil ARM-MDK / ARM RealView.

Then at the end of your bootloader:

// 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 ) ;

Note that APPLICATION_START_ADDR in this case is the base or location address of your linked application code (0x3200 in this case), not the entry point indicated in the link map. The application vector table is located at this address, and the start of the vector table contains the application's initial stack pointer address and program counter (the actual code entry point).

The boot_jump() function loads a stack pointer and program counter from the application's vector table, simulating what happens on reset where they are loaded from the base of Flash memory (the bootloader's vector table).

Note that you must have set the start address in your application code's linker settings to the same as that which the bootloader will copy the image. If you are using the Keil debugger, you will not be able to load and run the application in the debugger without the bootloader present (or at least without manually setting the SP and PC correctly or using a debugger script), because the debugger loads the reset vector addresses rather than the application vector addresses.

It is important that interrupts are disabled before switching the vector table, otherwise any interrupt that occurs before the application is initialised will vector to the application's handler, and that may not be ready.

Be careful of any peripherals that you use in both the application and boot code, any assumptions about reset conditions may not hold if the peripheral registers have already been set by the boot code.

这篇关于如何在Stellaris中的程序之间跳转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆