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。