前面介紹了MCUboot的基礎知識,您可通過上方鏈接回顧歷史文章,上次介紹了Swap模式,本次著重介紹利用Swap模式實現代碼回滾操作。在某些應用場景中,可能新版本的Firmware存在bug而需要返回至上一次的固件。
可以利用本文描述的這種方式實現以上目標。燒寫在Secondary Slot中的Image有一次運行的機會,即上電后在Bootloader控制下完成一次Swap操作,Secondary Slot中的高版本代碼被交換到Primary Slot中執行,在執行的過程中,根據某個函數的返回結果,在Trailer中對目標地址進行置位。
本文以RA4M2 512K Code Flash產品為例,使用Flat mode(不啟用TrustZone)說明Swap模式進行升級時的注意事項。
首先回顧一下Swap模式升級的流程。
MCUboot Swap模式圖解
從代碼框架來看,整體劃分為三部分,Bootloader,Primary Slot(保存了低版本的User Application v1.0)和Secondary Slot(保存了待更新的高版本User Application v2.0)。
初始狀態下,芯片中燒錄了Bootloader和Primary Slot,代碼從Bootloader處啟動,跳轉至Primary Slot中的User Application v1.0。在User Application v1.0運行過程中,接收來自外部的更高版本Firmware v2.0,并燒寫到Secondary Slot中,燒寫完成后,執行軟件復位Software reset,代碼重新從Bootloader開始運行。此時Bootloader判斷Secondary Slot中有待更新的Image,檢查其完整性等,校驗通過后,將Secondary Slot中的內容和Primary Slot中的內容交換(利用Scratch area作為暫存區域)。然后跳轉到Primary Slot中執行。比較升級操作的初始狀態和終止狀態,發現Primary Slot中運行的代碼從低版本的v1.0變為高版本的v2.0。
假如以當前升級操作的最后一個階段為新的起點,下次軟件復位后(以及之后的每次軟件復位),Bootloader會根據Trailer中的內容判斷,不需要重新執行swap操作了。
本次我們更改Bootloader的設定,如下所示,將兩種Image分別燒寫進Secondary Slot中,檢查升級的結果。
燒寫到Secondary Slot中的代碼版本均為v1.1.0,但是代碼有區別。
第一種代碼閃爍兩個LED(藍色和紅色),代碼中會調用boot_set_confirmed()函數
第二種代碼閃爍一個LED(藍色),代碼中并不調用boot_set_confirmed()函數
基于同樣的Bootloader和Primary Slot Application v1.0.0代碼,在Secondary Slot中燒寫兩種代碼,檢查升級后的狀態。
1修改Bootloader MCUboot選項
基于上次Swap模式的基礎工程,修改其中的關鍵配置Signing and Encryption Options → Custom,從--confirm更新為--pad,其他保持不變。
FSP中MCUboot Signing and Encryption Options屬性--pad
2創建第一種Application Project
創建一個Blinky Project,命名為ra4m2_app_v1,采用默認的Blinky模板,使得EK-RA4M2上的三個LED閃爍。
依次添加Build Variables → BootloaderDataFile,Environment Variable中設定MCUBOOT_IMAGE_SIGN_KEY和MCUBOOT_IMAGE_VERSION (設定為v1.0.0)。
導入ra4m2_app_v1且重命名為ra4m2_app_v2,從默認的閃爍三個LED改為兩個LED。
依次添加Build Variables → BootloaderDataFile,Environment Variable中設定MCUBOOT_IMAGE_SIGN_KEY和MCUBOOT_IMAGE_VERSION (設定為v1.1.0)。
在FSP → Stack中添加Bootloader → MCUboot Image Utilities
Application Project中添加MCUboot Image Utilities
根據錯誤提示,添加Flash driver,之后修改General屬性,如下圖所示,指向Bootloader所在路徑。
Application Project中添加MCUboot Image Utilities
Build Project,可以看到以“0 errors”提示編譯完成。
對Application Project Build時輸出的Log
3創建第二種Application Project
導入第二步創建的project,并重命名ra4m2_app_v2_confirmed,從閃爍兩個LED改為一個LED。
依次添加Build Variables → BootloaderDataFile,Environment Variable中設定MCUBOOT_IMAGE_SIGN_KEY和MCUBOOT_IMAGE_VERSION (設定為v1.2.0)。
在FSP → Stack中添加Bootloader → MCUboot Image Utilities
Application Project中添加MCUboot Image Utilities
根據錯誤提示,添加Flash driver,之后修改General屬性,如下圖所示,指向Bootloader所在路徑。
Application Project中添加MCUboot Image Utilities
在hal_entry.c中增加調用函數boot_set_confirmed()函數。
將光標放在hal_entry()函數入口處,打開Developer Assistant,點選Confirm Primary Image,保持鼠標左鍵按下狀態,拖拽至hal_entry()函數入口處
在Developer Assistance中找到目標函數
更新后的代碼如下所示。
Application Project調用boot_set_confirmed()函數
Build Project,可以看到以“0 errors”提示編譯完成。由于添加了boot_set_confirmed()函數調用,因此text段在之前(5108)基礎上有所增加。
對Application Project Confirmed Build時輸出的Log
4調試App v1并在Secondary Slot中加載v1.1.0 Image(不調用boot_set_confirmed())
調試ra4m2_app_v1,如之前所示,在Debug Configuration做如下修改。除增加Bootloader對應的elf文件下載(Image and Symbols)之外,還需增加ra4m2_app_v2對應的Symbols only。
Application Project Debug Configuration Startup選項卡配置
點擊Load Ancillary按鈕,將Application Project Debug文件夾下的***.bin.signed下載到芯片上,注意選擇地址為Primary Slot起始地址0x18000。
將1.0.0版本Image ***.bin.signed文件下載到Primary Slot的起始地址0x18000
點擊Load Ancillary按鈕,將ra4m2_app_v2 Debug文件夾下的***.bin.signed下載到芯片上,注意選擇地址為Secondary Slot起始地址0x48000。
將1.1.0版本Image ***.bin.signed文件下載到Secondary Slot的起始地址0x48000
檢查memory窗口的內容,會發現初始狀態如下:
圖 初始狀態下, Primary Slot保存1.0.0,Secondary Slot保存1.1.0
點擊resume,可以發現EK-RA4M2上從閃爍三個LED變為閃爍兩個LED。
首次升級完成后,Primary Slot保存1.1.0,Secondary Slot保存1.0.0
在調試界面繼續按下reset,重新運行會發現EK-RA4M2又回到閃爍三個LED。如果從升級事件的起始狀態和終止狀態看,都是閃爍三個LED。但是Secondary Slot中的1.1.0代碼得到一次運行的機會,出現過閃爍兩個LED的表現,由于沒有調用函數boot_set_confirmed(),因此沒有對Trailer進行設定,導致下次Bootloader運行時,又執行了一次Swap,最終芯片運行的還是v1.0.0版本。
為確認這一點,在每次運行時,檢查memory中兩個slot代碼內容即可。
復位完成后,Primary Slot保存1.0.0,Secondary Slot保存1.1.0
5調試App v1并在Secondary Slot中加載v1.2.0 Image(調用boot_set_confirmed())
調試ra4m2_app_v1,如之前所示,在Debug Configuration做如下修改。
Application Project Debug Configuration Startup選項卡配置
點擊Load Ancillary按鈕,將Application Project Debug文件夾下的***.bin.signed下載到芯片上,注意選擇地址為Primary Slot起始地址0x18000。
將1.0.0版本Image ***.bin.signed文件下載到Primary Slot的起始地址0x18000
點擊Load Ancillary按鈕,將ra4m2_app_v2_confirmed Debug文件夾下的***.bin.signed下載到芯片上,注意選擇地址為Secondary Slot起始地址0x48000。
將1.2.0版本Image ***.bin.signed文件下載到Secondary Slot的起始地址0x48000
下載完成后,檢查memory窗口,內容如下:
初始狀態下, Primary Slot保存1.0.0,Secondary Slot保存1.2.0
點擊resume,可以發現EK-RA4M2上從閃爍三個LED變為閃爍一個LED。在調試界面繼續按下reset,會發現EK-RA4M2依然保持閃爍一個LED。
為確認這一點,在memory窗口檢查首次升級完成后,Primary Slot中保存了v1.2.0 Image,而Secondary Slot中保存了v1.0.0 Image。即使再經過升級操作,也不會重新swap。根本原因是,Secondary Slot中燒錄的v1.2.0 Image在運行的時候編輯了Trailer中的相關Flag,使得Bootloader依據該Flag,判斷無需進行Swap。
升級完成后,memory窗口內容如下,Primary Slot中保留v1.2.0而Secondary Slot中保留1.0.0。
升級完成后, Primary Slot保存1.2.0,Secondary Slot保存1.0.0
示例代碼中我們僅僅是在secondary slot調用了boot_set_confirmed()函數,實際應用中,可以給調用該函數附加一些條件,如執行某個運算后根據返回的結果決定是否調用函數,運算結果符合預期,則調用函數使得當前Image生效。
需要技術支持?
-
芯片
+關注
關注
455文章
50714瀏覽量
423158 -
FlaSh
+關注
關注
10文章
1633瀏覽量
147944 -
SWAP
+關注
關注
0文章
51瀏覽量
12820 -
代碼
+關注
關注
30文章
4779瀏覽量
68525
原文標題:MCUboot系列(4)RA Swap模式下代碼回滾在FSP中的支持
文章出處:【微信號:瑞薩MCU小百科,微信公眾號:瑞薩MCU小百科】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論