STM32 MCU的內部FLASH有特定的起始地址(0x80000000),而STM32在啟動時,會檢測啟動控制管腳BOOT0和BOOT1的狀態,如果是指定從FLASH啟動(另外兩種是SRAM啟動和ISP對應的內部儲存啟動),則會進行地址對映,將0x80000000對映為0地址,而0地址和字1地址(0x80000004),裡面存放的分別是棧頂地址(指示記憶體SRAM可用空間,是SRAM的0地址+有效空間後的那個地址)和復位中斷響應服務程式地址。CPU取了棧頂地址,作為後續SRAM操作時的引數。0x80000004也是發生中斷時,MCU查詢中斷服務程式地址所用的中斷向量表基址。復位時從第一個字地址取復位中斷服務程式地址,在復位中斷服務程式裡跳轉執行SystemInit()函數,執行完再跳轉執行__main函數,最終跳轉到main()函數。
對於IAP的實現,比較好的方式是分為兩部分程式碼,boot和app部分,boot部分和原來的啟動過程相同,只是main()函數裡是升級操作控制過程程式,執行完後,重新對映中斷向量表為app程式的中斷向量表,通過獲取app程式中斷向量表裡的復位中斷服務程式地址,跳轉執行最終實現執行app程式的main()函數。
app存放於FLASH的另外一個區域,對於STM32CUBEIDE工具,修改app程式下載的起始地址和範圍,需要修改 STM32***TX_FLASH.ld。如將FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K 一句,修改為 FLASH (rx) : ORIGIN = 0x8008000, LENGTH = 96K。SRAM的棧頂地址也可以修改(限制程式執行時使用的RAM範圍),如下圖所示位置:
boot程式碼裡如下類似的程式碼,檢查app儲存空間首地址裡存放的是否是有效棧頂地址(0x2FFE0000對應檢查值為x0200020000的棧頂,避免SRAM操作地址不正確)以驗證新的app程式是否已寫到Flash儲存空間(可選方式,可用其它方式替代)。注意app佔用FLASH的空間首地址,不能超過boot佔用FLASH的最大地址。
app程式裡,還需要設定一項中斷向量表偏移地址量,偏移量對應app在Flash燒錄的地址偏移量。
根據
改為
對於STM32CUBEIDE,在Windows-Show View裡去找到Build Analyzer可以看到對儲存空間的佔用情況。如:
如果直接將boot和app部分通過ST-LINK進行燒錄,注意在boot和app分開情況,在對晶片內部FLASH進行擦除時,實現部分擦除(只擦除燒錄的磁區)後再寫入。 STM32CUBEIDE預設對所設定的FLASH地址空間對應的磁區做全部擦除後再寫入,對於所設定的FLASH地址空間外的物理FLASH空間不做擦除。因此boot和app程式部分,設定好不重疊的FLASH地址空間,則程式可以分別燒錄進去而不會產生影響。如果需要對燒錄進行更靈活的控制或者檢視FLASH情況,可以用STM32CubeProgrammer軟體(或STM32 ST-LINK Utility)。
對於app程式,需要生成.bin檔案,從而boot程式,通過外部介面接收此檔案內容並放置於Flash特定開始地址。對於STM32CUBEIDE,在post build設定中設定
arm-none-eabi-objcopy "${ProjName}.elf" -O binary "${ProjName}.bin"
boot程式建議採用晶片內部時鐘供時鐘,app基於應用要求採用外部時鐘或內部時鐘供時鐘,如此,boot程式過程不受外部時鐘故障的影響,但如果資料傳輸過程需要更穩定的時鐘,boot程式也可以採用外部時鐘供時鐘。
基於STM32L031, 可比較容易移植程式碼到STM32F1,F4各系列。
STM32L031完整IAP工程(boot和app兩部分)程式碼(基於STM32CUBEIDE)下載地址:
https://download.csdn.net/download/hwytree/12839400
Windows版本,與嵌入式版本握手協定配合,可進行IAP升級操作。
PC軟體下載地址:
https://download.csdn.net/download/hwytree/12839411
-End-