首先要明確的是ISP和IAP兩個(gè)概念。 ISP 即(In-System Programming)在系統(tǒng)可編程,,指電路板上的空白器件可以編程寫入最終用戶代碼, 而不需要從電路板上取下器件,,已經(jīng)編程的器件也可以用ISP 方式擦除或再編程,。 IAP:In Application Programming 是指在應(yīng)用編程,即在程序運(yùn)行中編程,,就是片子提供一系列的機(jī)制(硬件/軟件上的)當(dāng)片子在運(yùn)行程序的時(shí)候可以提供一種改變flash數(shù)據(jù)的方法,。 STM32F4芯片自帶ISP程序,在系統(tǒng)存儲(chǔ)區(qū)內(nèi),,通過開機(jī)的時(shí)檢測BOOT0和BOOT1的引腳電平來判斷從什么地方啟動(dòng),,如下圖
當(dāng)BOOT1處于低電平,同時(shí)BOOT0是高電平時(shí),,系統(tǒng)從System memory啟動(dòng),,這里保存著stm32出廠時(shí)內(nèi)置的ISP程序,可以通過串口或者usb口等來進(jìn)行內(nèi)置flash的編程,,這部分原理數(shù)據(jù)手冊(cè)里寫的很清楚,。
ISP這部分由官方實(shí)現(xiàn),是一段固化的程序,,使用isp軟件進(jìn)行升級(jí)即可,,下面我們來看一下IAP的問題。
IAP: IAP的好處就是不用進(jìn)行跳線改變boot引腳的電平,,就可以進(jìn)行在線編程,,在產(chǎn)品化以后使用的比較多,通常用一個(gè)boot程序來引導(dǎo),,選擇是進(jìn)行升級(jí)還是進(jìn)入app應(yīng)用中,。這一部分,st官方也有示例代碼(多么貼心),。 官方給出的IAP的核心代碼:
1.if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000) 這句旨在判定 APPLICATION_ADDRESS這個(gè)地址保存的是否是SP堆棧指針,,下面是stm32的矢量表:
從這個(gè)表中能看出來,用戶應(yīng)用的首4個(gè)字節(jié)應(yīng)該放的是棧頂?shù)闹?,啟?dòng)采樣完boot引腳后,,CPU 將從地址 0x0000 0000 獲取棧頂值,然后從始于 0x0000 0004 的自舉存儲(chǔ)器開始執(zhí)行代碼,。stm32的ram空間地址范圍是0x20000000~0x2001ffff,,共128K(42x和43x的ram空間更大,,但是我們使用前128K進(jìn)行判斷足夠了),,所以使用這句來判斷棧頂指針是否合法。 2.APPLICATION_ADDRESS保存的是用戶程序的首地址,,所以*(__IO uint32_t*) (APPLICATION_ADDRESS + 4)就是用戶程序空間復(fù)位向量的地址 3.Jump_To_Application = (pFunction) JumpAddress;Jump_To_Application是一個(gè)函數(shù)指針,,這句話將函數(shù)指針指向復(fù)位函數(shù)。 4.__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);設(shè)置堆棧指針sp,指向用戶代碼的首地址,。 5.Jump_To_Application();跳轉(zhuǎn)到用戶程序,,把函數(shù)指針賦值給pc指針。
stm32程序跳轉(zhuǎn)總結(jié):1.要賦值有效的sp棧頂指針 2.要給pc指針賦值 3.應(yīng)用程序要修改中斷向量表的偏移地址 從這個(gè)結(jié)論,,我們可以實(shí)現(xiàn)從boot到app的跳轉(zhuǎn),,同樣的原理也可以從app跳轉(zhuǎn)到boot程序,也是使用相同的代碼,。 程序間跳轉(zhuǎn)的時(shí)候,,如果使能了某項(xiàng)外設(shè),一定要在跳轉(zhuǎn)前使用xxx_DeInit 庫函數(shù)關(guān)閉一下,,外設(shè)才能在兩段程序中都正常使用,。 |
|