IAP
是In Application Programming
的首字母縮寫,IAP是用戶本身的程序在運行過程當中對User Flash的部分區域進行燒寫,目的是爲了在產品發佈後能夠方便地經過預留的通訊口對產品中的固件程序進行更新升級。git
在從新編程過程當中可使用任意類型的通訊協議,如UART、I2S、SPI等。這篇筆記分享的是使用UART方式IAP。github
先理一理流程(本實驗是以STM32F103ZET6
爲例):編程
一、實驗說明微信
作這個實驗須要準備兩個keil
工程,一個工程用於編寫IAP程序,另外一個工程用於編寫咱們的應用程序(要實現某些功能的程序),這裏咱們以一個點燈程序爲例。最終,兩份工程編譯出來的可執行文件都須要燒寫到芯片的FLASH
中。只不過須要燒寫到不一樣的地址,簡單的示意圖以下:app
這裏,使用的STM32的型號爲STM32F103ZET6,其FLASH大小是512KB,0x08000000爲其FLASH被映射的地址,程序被燒寫到的就是這個地址。此處,咱們的IAP程序燒寫到這個地址,根據IAP程序的大小,咱們在keil裏能夠設置合適的IAP結束地址。electron
注意:在沒有IAP程序的狀況下,0x08000000這個地址就是應用程序燒寫的地址。函數
二、工程說明工具
本實驗用到的兩個工程可按照文末的方式獲取,其中IAP工程移植至ST官方例程。下面對兩個工程進行簡單的說明ui
IAP工程:命令行
(1)須要在target
選項卡里設置咱們IAP程序的起始地址與大小,如:
這裏咱們的IAP程序起始地址設爲0x08000000,大小設爲0x3000,即IAP所能用的FLASH空間爲12KB。其中IAP所能佔的佔空間的大小可根據IAP的實際大小進行修改。
(2)須要修改程序中咱們須要跳轉到的應用程序的地址(即IAP程序的結束地址):
LED工程:
(1)須要在target
選項卡里設置咱們LED程序的起始地址與大小,如:
這裏咱們的LED程序起地址設爲0x08003000,大小設爲0x10000,即LED所能用的FLASH空間爲64KB。其中結束地址可根據LED應用程序的實際大小進行修改。
(2)生成對應的.bin
文件。這須要在User
選項卡里添加以下命令(即編譯後執行的命令):
其中,fromelf.exe
是咱們keil安裝目錄下的一個可執行程序,能夠把.axf
文件轉換成.bin
文件。要在keil中直接調用fromelf命令,必需要把fromelf.exe
所在目錄添加到環境變量中。添加環境變量的方法以下(該方法來自於《【野火】零死角玩轉STM32—F429挑戰者V2.pdf》):
本文以 Win7 系統爲例添加工具鏈的路徑到 PATH 環境變量,其它系統是相似的。
(1) 右鍵電腦系統的計算機圖標
,在彈出的菜單中選擇屬性
,如圖:
(2) 在彈出的屬性頁面依次點擊高級系統設置 ->環境變量
,在用戶變量一欄中找到名爲PATH
的變量,若沒有該變量,則新建一個。編輯PATH
變量,在它的變量值中輸入工具鏈的路徑,如本機的是;D:\work\keil5\ARM\ARMCC\bin
,注意要使用分號;
讓它與其它路徑分隔開,輸入完畢後依次點肯定
,如圖:
(3) 打開 Windows 的命令行,點擊系統的開始菜單
,在搜索框輸入cmd
,在搜索結果中點擊cmd.exe
便可打開命令行, 如圖:
(4) 在彈出的命令行窗口中輸入fromelf
回車,若窗口打印出 formelf
的幫助說明,那麼路徑正常,就能夠開始後面的工做了;若提示不是內部名外部命令,也不是可運行的程序…
信息,說明路徑不對,請從新配置環境變量,並確認該工做目錄下有編譯工具鏈。
這個過程本質就是讓命令行經過「PATH」路徑找到fromelf.exe
程序運行 。
三、IAP源碼說明
(1)主函數:
int main(void) { FLASH_Unlock(); /* FLASH解鎖 */ KEY_Init(); /* 按鍵初始化 */ IAP_Init(); /* IAP初始化 */ /* 按鍵按下則進入主菜單開始更新程序(注意:須要按下復位鍵的同時按下該按鍵觸發程序更新) */ if (GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) == 0x00) { SerialPutString("\r\n======================================================================"); SerialPutString("\r\n= (C) COPYRIGHT 2010 STMicroelectronics ="); SerialPutString("\r\n= ="); SerialPutString("\r\n= In-Application Programming Application (Version 3.3.0) ="); SerialPutString("\r\n= ="); SerialPutString("\r\n= By MCD Application Team ="); SerialPutString("\r\n======================================================================"); SerialPutString("\r\n\r\n"); Main_Menu (); } /* 保持運行用戶應用程序 */ else { /* Test if user code is programmed starting from address "ApplicationAddress" */ if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000) { /* Jump to user application */ JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4); Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) ApplicationAddress); Jump_To_Application(); } } while (1){} return 0; }
可見,咱們按下復位的同時按下PE2
對應的按鍵便可觸發應用程序更新操做,不然跳轉到應用程序的起始地址執行應用程序(斷點重啓也是默認執行應用程序),這裏的ApplicationAddress
就是咱們上面設置的0x08003000
。
(2)主菜單函數Main_Menu
這個函數裏就是該IAP程序的功能,根據其中的打印信息:
能夠知道,該IAP有三個功能(分別輸入鍵盤上的數字一、二、3進行選擇):一是下載程序(電腦->STM32);二是上傳程序(STM32->電腦);三是執行新程序(即剛下載完成的程序)。
(3)下載程序功能函數SerialDownload
首先,上位機使用Ymodem協議進行數據下發,STM32根據協議解析數據,拿到有用的數據,並把這些數據寫入FLASH對應的地址中,即ApplicationAddress。關於Ymodem協議及SerialDownload函數這裏不展開討論。
四、下載驗證
(1)下載IAP程序
可使用J-link等調試器進行下載,也可用串口ISP
進行下載,咱們選用的是串口ISP
進行下載,借用的工具是FlyMcu
:
這裏下載的是.hex
文件,若是下載.bin
文件,則會提示以下錯誤:
程序文件不是0x8000000和0x20000000區域的
使用ISP方式下載須要進行的硬件操做是:BOOT0引腳拉高,BOOT1引腳接地
。即系統存儲器被選爲啓動區域:
在點擊開始編程
按鈕後,須要按下板子上的復位鍵,便可下載程序。
(2)經過IAP程序引導下載LED程序
上面提到下載程序使用的是Ymodem協議,因此得選用帶有Ymodem協議傳輸方式的上位機軟件來把應用程序下載到板子裏。能夠選用SecureCRT
,也能夠選用超級終端。這裏選用的是超級終端:
首先按下數字鍵1觸發下載程序操做,此時會不斷打印CCCCC...
。而後點傳送->發送文件
,選擇要下載的.bin
文件及Ymodem
協議。下載完成後按下數字3便可執行新下載得應用程序:
終於,LED閃爍起來了,點燈項目成功~。斷電重啓以後默認執行的是這個點燈程序,要想下載新的程序,按下復位的同時按下PE2
所對應的按鍵(須要必定的手速,哈哈)便可觸發更新程序操做。
以上就是本次筆記分享的內容,若有錯誤,歡迎指出!
個人我的博客:https://zhengnianli.github.io/
個人微信公衆號:嵌入式大雜燴,關注並回復【1024】獲取1TB大雜燴資料。