2019-03-23 17:35发布
原帖由 asdbhk 于 2013-4-1 15:57 发表 void jump_app(uint32_t addr) { uint32_t tmp; tmp=*(volatile uint32_t*)addr; if((tmp&0x2FFE0000)==0x20000000) { JumpAddress = *(__IO uint32_t*) (addr + 4); Jump_To_Application =(pFun ...
最多设置5个标签!
{
uint32_t tmp;
tmp=*(volatile uint32_t*)addr;
if((tmp&0x2FFE0000)==0x20000000)
{
JumpAddress = *(__IO uint32_t*) (addr + 4);
Jump_To_Application =(pFunction) JumpAddress; //(pFunction) 0x10004;
/* Initialize user application's Stack Pointer */
__set_MSP(*(int32u*) addr);
Jump_To_Application();
}
}
这几天去上课了
这个是跳转程序的函数
能帮我分析一下么
其实呢,对于某个硬件外设对应的中断。这个函数指针可以安排在数据区,在bootloder的时候,初始化它为bootloder时需要调用的ISR函数。如果跳转到app的时候呢,就可以重新定向这个函数指针到app自己需要调用的ISR函数。软件重定向的思想。
这个我倒是看过了,能懂一些。
void jump_app(uint32_t addr)
{
uint32_t tmp;
tmp=*(volatile uint32_t*)addr;//addr是app的首地址,其实就是中断向量表中的第一项,addr其实就是MSP的初始值的地址,从flash的app的首地址中取出这个MSP的初始值给tmp。
if((tmp&0x2FFE0000)==0x20000000)// 检查MSP的初始值是否合法,具体怎么才合法,我也早忘光了,你可以查查资料吧,应该是和具体芯片的内存分布或者说内存映射有关。
{
JumpAddress = *(__IO uint32_t*) (addr + 4); // addr + 4 ,这个就是app中断向量表中复位向量的地址,像上面那样取出它里面的值赋给JumpAddress 。
Jump_To_Application =(pFunction) JumpAddress; // 现在再对JumpAddress 做一下类型转化,赋给Jump_To_Application这个函数指针,那么这个函数指针就指向的是APP的复位向量指向的地方,不严格的说法就是复位函数吧。调用整个函数就是APP的开始
/* Initialize user application's Stack Pointer */
__set_MSP(*(int32u*) addr);//这里你注意,刚只是检查了MSP的合法性,但是并没有对app的MSP做初始化,目前还是是在bootloader下么。如果不做这一步,直接走下一句跳转的话,那么MSP的值可能会导致溢出,至少会导致浪费,所以要先初始化MSP,然后走下一句再跳转。这里其实是用汇编写的,毕竟SP寄存器是不能通过C来读写的。当时我在这个地方自己试着写了下汇编语句,其实很简单,才2句还是3句忘了,但是不敢确定稳定性,后来反汇编时看到 __set_MSP()的汇编和我的相同才放心。
Jump_To_Application();// 到这里就完了,开始APP的运行嘛,不细说了。
}
}
//这整个函数除开检查MSP初始值的合法性外,主要就做了两件事:
1.重新初始化MSP
2.复位
估计芯片里面的boot固件也是这么干的。
[ 本帖最后由 lr2131 于 2013-4-2 10:29 编辑 ]
就像十楼说的那样 没有中断向量偏移寄存器 那个地址没写成功
有点小纠结
一周热门 更多>