STM32F10X的IAP编程详解——开发指南
轉(zhuǎn):http://blog.sina.com.cn/s/blog_b315f69b0102whtg.html
這篇文章摘自STM32開(kāi)發(fā)指南,偶然在網(wǎng)上翻到了一次,經(jīng)典的文章和大家一起分享。
IAP(?In Application Programming)即在應(yīng)用編程,?IAP?是用戶自己的程序在運(yùn)行過(guò)程中對(duì)User Flash?的部分區(qū)域進(jìn)行燒寫,目的是為了在產(chǎn)品發(fā)布后可以方便地通過(guò)預(yù)留的通信口對(duì)產(chǎn)
品中的固件程序進(jìn)行更新升級(jí)。 通常實(shí)現(xiàn)IAP?功能時(shí),即用戶程序運(yùn)行中作自身的更新操作,
需要在設(shè)計(jì)固件程序時(shí)編寫兩個(gè)項(xiàng)目代碼,第一個(gè)項(xiàng)目程序不執(zhí)行正常的功能操作,而只是通
過(guò)某種通信方式(如?USB、USART)接收程序或數(shù)據(jù),執(zhí)行對(duì)第二部分代碼的更新;第二個(gè)項(xiàng)目
代碼才是真正的功能代碼。這兩部分項(xiàng)目代碼都同時(shí)燒錄在?User Flash?中,當(dāng)芯片上電后,首
先是第一個(gè)項(xiàng)目代碼開(kāi)始運(yùn)行,它作如下操作:
1)檢查是否需要對(duì)第二部分代碼進(jìn)行更新
2)如果不需要更新則轉(zhuǎn)到?4)
3)執(zhí)行更新操作
4)跳轉(zhuǎn)到第二部分代碼執(zhí)行
第一部分代碼必須通過(guò)其它手段,如?JTAG?或?ISP?燒入;第二部分代碼可以使用第一部分代碼IAP?功能燒入,也可以和第一部分代碼一起燒入,以后需要程序更新是再通過(guò)第一部分?IAP代碼更新。我們將第一個(gè)項(xiàng)目代碼稱之為?Bootloader?程序,第二個(gè)項(xiàng)目代碼稱之為?APP?程序,他們存放在?STM32 FLASH?的不同地址范圍,一般從最低地址區(qū)開(kāi)始存放?Bootloader,緊跟其后的就是APP?程序(注意,如果?FLASH?容量足夠,是可以設(shè)計(jì)很多?APP?程序的,這里只討論一個(gè)?APP?程序的情況)。這樣我們就是要實(shí)現(xiàn)?2?個(gè)程序:Bootloader?和?APP。STM32?的?APP?程序不僅可以放到?FLASH?里面運(yùn)行,也可以放到?SRAM?里面運(yùn)行,這里,我們將制作一個(gè)APP,用于?FLASH運(yùn)行。我們先來(lái)看看?STM32?正常的程序運(yùn)行流程,如圖?53.1.1?所示:
圖53.1.1 STM32?正常運(yùn)行流程圖
STM32?的內(nèi)部閃存(?FLASH)地址起始于?0x08000000,一般情況下,程序文件就從此地址開(kāi)始寫入。此外STM32 F10X是基于?Cortex-M3?內(nèi)核的微控制器,其內(nèi)部通過(guò)一張“中斷向量表”來(lái)響應(yīng)中斷,程序啟動(dòng)后,將首先從“中斷向量表”取出復(fù)位中斷向量執(zhí)行復(fù)位中斷程序完成啟動(dòng),而這張“中斷向量表”的起始地址是0x08000004,當(dāng)中斷來(lái)臨,?STM32?的內(nèi)部硬件機(jī)制亦會(huì)自動(dòng)將?PC?指針定位到“中斷向量表”處,并根據(jù)中斷源取出對(duì)應(yīng)的中斷向量執(zhí)行中斷服務(wù)程序。
在圖?53.1.1?中,?STM32?在復(fù)位后,先從?0X08000004?地址取出復(fù)位中斷向量的地址,并跳轉(zhuǎn)到復(fù)位中斷服務(wù)程序,如圖標(biāo)號(hào)①所示;在復(fù)位中斷服務(wù)程序執(zhí)行完之后,會(huì)跳轉(zhuǎn)到我們的main?函數(shù),如圖標(biāo)號(hào)②所示;而我們的main?函數(shù)一般都是一個(gè)死循環(huán),在?main?函數(shù)執(zhí)行過(guò)程中,如果收到中斷請(qǐng)求(發(fā)生重中斷),此時(shí)STM32?強(qiáng)制將?PC?指針指回中斷向量表處,如圖標(biāo)號(hào)③所示;然后,根據(jù)中斷源進(jìn)入相應(yīng)的中斷服務(wù)程序,如圖標(biāo)號(hào)④所示;在執(zhí)行完中斷服務(wù)程序以后,程序再次返回main?函數(shù)執(zhí)行,如圖標(biāo)號(hào)⑤所示。
當(dāng)加入?IAP?程序之后,程序運(yùn)行流程如圖?53.1.2?所示:
圖53.1.2?加入?IAP?之后程序運(yùn)行流程圖
在圖?53.1.2?所示流程中,?STM32?復(fù)位后,還是從?0X08000004?地址取出復(fù)位中斷向量的地址,并跳轉(zhuǎn)到復(fù)位中斷服務(wù)程序,在運(yùn)行完復(fù)位中斷服務(wù)程序之后跳轉(zhuǎn)到IAP?的?main?函數(shù),如圖標(biāo)號(hào)①所示,此部分同圖53.1.1?一樣;在執(zhí)行完?IAP?以后(即將新的?APP?代碼寫入?STM32的FLASH,灰底部分。新程序的復(fù)位中斷向量起始地址為?0X08000004+N+M),跳轉(zhuǎn)至新寫入程序的復(fù)位向量表,取出新程序的復(fù)位中斷向量的地址,并跳轉(zhuǎn)執(zhí)行新程序的復(fù)位中斷服務(wù)程序,隨后跳轉(zhuǎn)至新程序的?main?函數(shù),如圖標(biāo)號(hào)②和③所示,同樣?main?函數(shù)為一個(gè)死循環(huán),并且注意到此時(shí)?STM32?的FLASH,在不同位置上,共有兩個(gè)中斷向量表。在?main?函數(shù)執(zhí)行過(guò)程中,如果CPU?得到一個(gè)中斷請(qǐng)求,?PC?指針仍強(qiáng)制跳轉(zhuǎn)到地址0X08000004?中斷向量表處,而不是新程序的中斷向量表,如圖標(biāo)號(hào)④所示;程序再根據(jù)我們?cè)O(shè)置的中斷向量表偏移量,跳轉(zhuǎn)到對(duì)應(yīng)中斷源新的中斷服務(wù)程序中,如圖標(biāo)號(hào)⑤所示;在執(zhí)行完中斷服務(wù)程序后,程序返回?main?函數(shù)繼續(xù)運(yùn)行,如圖標(biāo)號(hào)⑥所示。通過(guò)以上兩個(gè)過(guò)程的分析,我們知道?IAP?程序必須滿足兩個(gè)要求:
1) 新程序必須在?IAP?程序之后的某個(gè)偏移量為?x?的地址開(kāi)始;
2) 必須將新程序的中斷向量表相應(yīng)的移動(dòng),移動(dòng)的偏移量為?x;
1.APP?程序起始地址設(shè)置方法
隨便打開(kāi)一個(gè)之前的實(shí)例工程,點(diǎn)擊?Options for Targe-> Target選項(xiàng)卡,如圖所示:
?
?
圖53.1.3 FLASH APP Target?選項(xiàng)卡設(shè)置 ????默認(rèn)的條件下,圖中?IROM1?的起始地址(?Start)一般為?0X08000000,大小(Size)為0X80000,即從0X08000000?開(kāi)始的512K?空間為我們的程序存儲(chǔ)(假設(shè)使用的STM32F103ZET6,其?FLASH大小是?512K)。而圖中,我們?cè)O(shè)置起始地址(?Start)為0X08010000,即偏移量為?0X10000(?64K字節(jié)),因而,留給?APP?用的?FLASH?空間(?Size)只有0X80000-0X10000=0X70000(?448K?字節(jié))大小了。設(shè)置好?Start?和Szie,就完成APP?程序的起始地址設(shè)置。2.中斷向量表的偏移量設(shè)置方法
之前我們講解過(guò),在系統(tǒng)啟動(dòng)的時(shí)候,會(huì)首先調(diào)用?systemInit?函數(shù)初始化時(shí)鐘系統(tǒng),同時(shí)systemInit?還完成了中斷向量表的設(shè)置,我們可以打開(kāi)?systemInit?函數(shù),看看函數(shù)體的結(jié)尾處有這樣幾行代碼:
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;
?
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
?
#endif
從代碼可以理解,VTOR寄存器存放的是中斷向量表的起始地址。默認(rèn)的情況VECT_TAB_SRAM?是沒(méi)有定義,所以執(zhí)行SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;對(duì)于?FLASH APP,我們?cè)O(shè)置為FLASH_BASE+偏移量0x10000,所以我們可以在FLASH APP?的main?函數(shù)最開(kāi)頭處添加如下代碼實(shí)現(xiàn)中斷向量表的起始地址的重設(shè):
SCB->VTOR = FLASH_BASE | 0x10000;
以上是FLASH APP?的情況,當(dāng)使用SRAM APP?的時(shí)候, 我們?cè)O(shè)置起始地址為:SRAM_bASE+0x1000,同樣的方法,我們?cè)?SRAM APP?的?main?函數(shù)最開(kāi)始處,添加下面代碼:
SCB->VTOR = SRAM_BASE | 0x1000;
這樣,我們就完成了中斷向量表偏移量的設(shè)置。
通過(guò)以上兩個(gè)步驟的設(shè)置,我們就可以生成?APP?程序了,只要?APP?程序的?FLASH?大小不超過(guò)我們的設(shè)置即可。不過(guò)?MDK?默認(rèn)生成的文件是.hex?文件,并不方便我們用作?IAP更新,我們希望生成的文件是.bin?文件,這樣可以方便進(jìn)行?IAP?升級(jí),這里我們通過(guò)?MDK?自帶的格式轉(zhuǎn)換工具?fromelf.exe,來(lái)實(shí)現(xiàn).axf文件到.bin?文件的轉(zhuǎn)換。該工具在?MDK?的安裝目錄\ARM\BIN40文件夾里面。
fromelf.exe?轉(zhuǎn)換工具的語(yǔ)法格式為:?fromelf [options] input_file。其中?options?有很多選項(xiàng)可以設(shè)置?.
本章,我們通過(guò)在?MDK?點(diǎn)擊?Options for Targe->USER選項(xiàng)卡,在
?
通過(guò)這一步設(shè)置,我們就可以在?MDK?編譯成功之后,調(diào)用?fromelf.exe(注意,我的?MDK是安裝在D:\Keil3.80A?文件夾下,如果你是安裝在其他目錄,請(qǐng)根據(jù)你自己的目錄修改fromelf.exe的路徑),根據(jù)當(dāng)前工程的?TEST.axf(如果是其他的名字,請(qǐng)記住修改,這個(gè)文件存放在?OBJ?目錄下面,格式為?xxx.axf),生成一個(gè)?TEST.bin?的文件。并存放在?axf文件相同的目錄下,即工程的?OBJ?文件夾里面。在得到.bin?文件之后,我們只需要將這個(gè)?bin?文件傳送給單片機(jī),即可執(zhí)行?IAP?升級(jí)。
最后再來(lái)APP?程序的生成步驟:
1)????設(shè)置?APP?程序的起始地址和存儲(chǔ)空間大小
?對(duì)于在?FLASH?里面運(yùn)行的APP?程序,?我們可以按照?qǐng)D53.1.3?的設(shè)置。
2)????設(shè)置中斷向量表偏移量
這一步按照上面講解,重新設(shè)置?SCB->VTOR?的值即可。
3)????設(shè)置編譯后運(yùn)行?fromelf.exe,生成.bin?文件.
通過(guò)在User?選項(xiàng)卡,設(shè)置編譯后調(diào)用?fromelf.exe,根據(jù).axf?文件生成.bin?文件,用于IAP?更新。
以上?3?個(gè)步驟,我們就可以得到一個(gè).bin?的?APP?程序,通過(guò)?Bootlader?程序即可實(shí)現(xiàn)更新。
參考類似文章:http://bbs.elecfans.com/jishu_422057_1_1.html?(包含中斷向量表詳解)
總結(jié)
以上是生活随笔為你收集整理的STM32F10X的IAP编程详解——开发指南的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 分区工具PQ
- 下一篇: 风口的猪-中国牛市(小米2016校招)