芯片IAP升級機制講解

一、先了解ICP和ISP、IAP之間的區別:
1、 ISP(In System Programing 在系統編程)的實現相對要簡單一些,一般通用做法是內部的存儲器可以由上位機的軟件通過串口來進行改寫。對於單片機來講可以通過SPI或其它的串行接口接收上位機傳來的數據並寫入存儲器中。所以即使我們將芯片焊接在電路板上,只要留出和上位機接口的這個串口,就可以實現芯片內部存儲器的改寫,而無須再取下芯片。例如,我們開始接觸到的STC51單片機的程序下載方式(點擊上位機下載----->復位(斷電)----->下載)

2、 IAP(In applicatin programming 在應用編程)的實現相對要複雜一些,在實現IAP功能時,單片機內部一定要有兩塊存儲區,一般一塊被稱爲BOOT區,另外一塊被稱爲APP存儲區。單片機上電從BOOT區開始運行,如果有外部改寫程序的條件滿足,則對存儲區的程序進行改寫操作。如果外部改寫程序的條件不滿足,程序指針跳到APP存儲區,開始執行放在存儲區的APP程序,這樣便實現了IAP功能。

3、 ICP(In-Circuit Programming 在線編程)通過JTAG/SWD協議或者系統加載程序(Bootloader)下載用戶應用程序到微控制器中。這種情況使用仿真器下載或者芯片廠商提供的ICP軟件。

總結:(1)(重要!!!)IAP和ISP是我們研發生產中使用的比較多的情況,使用ISP外部條件觸發(網上說有四種方式這裏不介紹了,感興趣的可以百度一下),IAP升級完全是芯片內部控制的(這個是很大的優點,試想當你的產品嵌入其他產品內部時候,你不可能打開外殼再外部觸發升級。)。

(2)在嵌入式產品生產階段,往往一些公司使用ICP或ISP的方式將裸芯片燒寫IAP+APP程序,燒寫的程序是bin文件格式或者加密後的bin文件格式(加密後的bin文件只能使用自己公司的上位機軟件進行燒寫否則產品無法正常啓動)。

(3)在研發階段,使用的IAP程序是通過JTAG或ISP燒入到芯片,然後通過上位機通過USB,UART或SPI的方式將應用程序(APP)燒寫到芯片。

二、瞭解一下RAM和ROM的區別:
1、 RAM: 隨機存儲器,可以隨時進行讀寫操作,速度很快,掉電以後數據會丟失。比如內存條、SRAM、SDRAM、DDR 等都是 RAM。RAM 一般用來保存程序數據、中間結果。

2、 ROM:只讀存儲器,筆者認爲目前“只讀存儲器”這個定義不準確。比如我們買手機,通常會告訴你這個手機是 4+64 或 6+128 配置,說的就是 RAM 爲 4GB 或 6GB,ROM 爲 64G 或128GB。但是這個 ROM 是 Flash,比如 EMMC 或 UFS 存儲器,因爲歷史原因,很多人還是將Flash 叫做 ROM。但是 EMMC 和 UFS,甚至是 NAND Flash,這些都是可以進行寫操作的。

總結:(重要!!!)RAM 速度快,可以直接和 CPU 進行通信,但是掉電以後數據會丟失,容量不容易做大(和同價格的 Flash 相比)。ROM(目前來說,更適合叫做 Flash)速度雖然慢,但是容量大、適合存儲數據(ROM程序的存儲位置)。

三、IAP升級的機制講解:
1、先看你STM32的內存地址架構圖
在這裏插入圖片描述
從圖上可以看出:
(1)內部flash 是從0x0800 0000開始 到0x0803 FFFF 結束, 0x0803FFFF-0x0800 0000= 0x20000 =256k flash的大小是256k;

(2)SRAM的開始地址是 0x2000 0000 開始到0x2000 FFFF結束,大小爲64K
而剛剛說了我們程序是放在ROM中,那IAP(在線升級程序)代碼放到Flash Memory裏以0x0800 0000 開始的位置(有些RAM內核的芯片的內部flah起始地址是0x00000000)。

2、芯片BOOT腳配置
在這裏插入圖片描述
因爲我們從flash燒寫IAP程序,所以一般我們芯片引腳原理圖設計爲(BOOT0=0/1,BOOT1=0):
在這裏插入圖片描述
當產品開發完成時候,只能選擇IAP升級方式,即:BOOT0=0,BOOT1=0;
三、如何編寫IAP程序?
1、程序地址分配圖:
在這裏插入圖片描述
上圖是IAP+APP程序的大致結構圖,在MDK配置IAP程序的地址空間分佈爲:
在這裏插入圖片描述
2、USB方式的IAP升級(UART,SPI等方式都大同小異)
(1)芯片正常執行在APP(應用程序)中(0x08004000-0x08030000)段,當要進行升級時候,上位機或者其他產品發送升級指令,升級指令,我們將會將升級標誌位(假如是0xA0A0A0A0)寫到flash的0x08003000開始的Flag區(大小爲0x1000=4KByte,Flag區是我自己命名的)某個位置,寫入標誌位後,進行軟復位。(寫入我們預留的Flag區,可以寫入APP文件的大小或者上位機分了多少包)

(2)復位後,程序又從0x00000000地址開始執行即進入IAP程序,這裏爲啥從0x08000000開始執行可以看我上篇文章STM32的Flash地址是0x08000000,從0x00000000不可以?
https://blog.csdn.net/weixin_42231514/article/details/106178653

(3)進入IAP程序後,我們將讀flash的0x08003000起始的Flag區對應的標誌位是不是0xA0A0A0A0,如果是,則上位機通過約定好的協議分包發固定字節的APP對應的bin文件或者加密後的bin文件(這裏你的上位機會將加密的bin文件解密)寫到0x08004000爲起始的APP區。

(4)如果最後一包數據不滿足約定的固定字節,這種情況下上位機可以填充0來滿足固定字節或者IAP程序進行特別處理最後一包寫入flash。

(5)IAP程序接收完最後一包APP 程序並寫入flash後,此時跳轉到0x08004000位置去執行APP程序,在APP程序初始化部分清除Flag區域的標誌位0xA0A0A0A0。
下圖爲APP程序中地址空間的分配:
在這裏插入圖片描述
需要注意點:(重要!!!
(1) 在IAP程序中:
#define ApplicationAddress 0x08004000
#define NVIC_VectTab_FLASH ((uint32_t)0x08000000)
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000);

JumpAddress = *(vu32*) (ApplicationAddress + 4);//用戶代碼區第二個字爲程序開始地址(復位地址)		
Jump_To_Application = (pFunction) JumpAddress;
MSR_MSP(*(vu32*)ApplicationAddress);		//初始化APP堆棧指針(用戶代碼區的第一個字用於存放棧頂地址)
Jump_To_Application();		//跳轉到APP.	

(2)在APP程序中:

 #define NVIC_VectTab_FLASH           ((uint32_t)0x08000000)
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000); //APP中,中斷向量表的起始地址

如果有什麼疑問,歡迎大家留言討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章