1、阅读《CM3权威指南》,指出复位时,写入AIRCR的值为(0x5FA<<16)|0x4,但在该过程中,到内核执行需要一定延时,因此可能会继续往后执行,直到复位生效,同样此时也会响应外部中断,为此,我们在执行之前置位FAULTMASK,屏蔽除NMI之外的所有中断;并且当执行完复位赋值之后,为了不执行后面的程序,因此在执行完之后,加入while死循环。即:
__set_FAULTMASK(1);
NVIC_SystemReset();
推荐使用系统复位!
2、采用改变PC值的方式,让PC重新指向复位向量所指向的值。即:
void Reset(void)
{
void (*fp)(void);
fp = (void (*)(void))(* (vu32 *)(0x8000004));
(*fp)();
}
推荐方法:改进(装载MSP):
typedef void(*pFunction)(void); //定义函数指针原型
void Resettest(void)
{
pFunction pReset;
uint32_t resetPC;
resetPC = *(vu32 *)(0x08000004);
pReset = (pFunction)resetPC;
__set_MSP(*(vu32 *)0x08000000);
pReset();
}
3、也是采用改变PC值的方式:
void Reset()
{
void (*fp)(void);
fp = (void (*)(void))0x8000005; //LSB=1
(*fp)();
}
测试时,将 pc跳转写为0x08000001,也能运行,Simulator过程中,PC逐条执行,跟踪程序,程序并没有从SystemInit开始执行,而是从指向地址逐个往下执行,没有通过main地址,而指向main函数内部的初始函数开始执行。
以上LSB为1,因为给PC写入数据,会引起一次程序分支(但不更新LR),无论是直接写PC的值还是使用分支指令(BX等跳转指令后的地址),都必须保证加载到PC的数值是奇数(即LSB=1),用以表明这是在Thumb状态下执行。倘若写入了0,则视为企图转入ARM模式,CM3将产生一个fault异常-->HardFault。