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个标签!
这个我倒是看过了,能懂一些。
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 编辑 ]
一周热门 更多>