大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是在i.MXRT1xxx系列上用NAND型啟動裝置時可用兩級設計縮短啟動時間。
去年痞子衡寫過一篇騷操作文章 《藉助i.MXRT10xx系列INIT_VTOR功能可以縮短程式熱重啟時間》,這對於 NAND 型啟動裝置上程式熱重啟時間的縮短非常有幫助。我們知道隨著專案程序的推進,程式碼功能逐漸完善,程式體積也會變得越來越大,相應地啟動時間也會增大(每次復位 BootROM 都會搬移一次程式,搬移時間和程式長度成正比),痞子衡已經為大家解決了程式熱重啟時間問題,但是程式上電啟動(冷啟動)時間仍然過長怎麼辦?
最近痞子衡在支援一個 RT1170 汽車電子客戶,他們使用了 eMMC 作為啟動裝置,他們就對程式啟動時間比較擔心。鑑於此,痞子衡決定給他們做一個示例,這個方法其實痞子衡在 《測量RT1170 Raw NAND啟動時間》 一文 2.2 小節裡簡單提及過,就是小 L2Boot + 大 App 兩級啟動設計(L2Boot儘量小,App可以很大,L2Boot起來之後去做一些使用者啟動任務,然後由L2Boot再去慢慢載入App)。那會痞子衡只是放個嘴炮,這次咱們就動個真格:
- Note:本文以 eMMC 啟動裝置為例,但思想方法同樣適用 Raw/Serial NAND, SD 等啟動裝置。
一、RT1170從eMMC啟動
RT1xxx 系列包含兩個 uSDHC 模組,其中 uSDHC1 主要支援 1/4-bit 模式,而 uSDHC2 可以支援 1/4/8-bit 模式,因此大部分客戶都會將 8-bit eMMC 掛在 uSDHC2 上。這個汽車電子客戶選用了來自江波龍的相容 eMMC5.1 標準的 8GB 容量晶片 FEMDME008G-A8A39,硬體設計上記憶體介質供電 VCC 是 3.3V,主機介面供電 VCCQ 是 1.8V(高速):
VCCQ = 1.8V,低功耗模式,可支援 HS200/HS400
VCCQ = 3.3V,高功耗模式,可支援 52MHz CLK SDR/DDR
要從 eMMC 啟動,首先需要準備一個 Non-XIP 程式,具體可參考 《RT上Non-App製作限制》。有了程式,然後將晶片 Boot Mode 設定為 2'b01 序列下載模式,再使用痞子衡 MCUBootUtility 工具做一鍵下載即可,軟體配置如下:
程式下載完成之後,將晶片 Boot Mode 設定為 2'b10,此外 BOOT_CFG[1/5/7/8/9] 均設為1,即從 uSDHC2 8-bit 1.8V High-Speed 模式啟動,斷電覆位,你應該能看到程式從 eMMC 中被啟動了。
二、支援eMMC讀取的L2Boot設計
確認基本的 eMMC 啟動過程沒問題了,現在開始設計 L2Boot。其實這個 L2Boot 也沒啥玄機,本質上也是一個 Non-XIP 程式,只不過程式功能包含:使用者啟動任務執行、eMMC 資料讀取驅動、使用者程式載入執行。痞子衡這裡的 L2Boot 設計主要涉及 eMMC 資料讀取以及使用者程式載入執行。
目前官方 SDK_2_15_000_MIMXRT1170-EVKB 裡沒有單純的 eMMC 例程,但是其它 RT 型號倒是有例程 \SDK_2_15_000_EVKB-IMXRT1050\boards\evkbimxrt1050\sdmmc_examples\mmccard_freertos,痞子衡其實就想要一個最簡單的裸機版本的 eMMC 讀寫測試。
為了不重複造輪子,痞子衡就在 \SDK_2_15_000_MIMXRT1170-EVKB\boards\evkbmimxrt1170\bootloader_examples\flashloader 基礎上做了刪減,僅保留 eMMC 讀寫以及程式跳轉功能,程式碼倉庫如下:
https://github.com/JayHeng/RT-SDMMC/tree/dev_l2boot_emmc/boards/mcu/mmc_boot
這個 L2Boot 工程裡最核心的函式 bootloader_run() 如下,其中使用者程式複製過程目標地址和長度使用了 HARDCODE,這裡其實是可以改進的(可參考 RTxxx 系列啟動設計在使用者程式中斷向量表保留區域放置 APP_EXEC_START 和 APP_LENGTH)。此外 APP_EMMC_START 設 0x80000,是因為這款 eMMC 晶片擦除單元(erase group)為 512KB,第一個 group 我們放置了 L2Boot,使用者 App 可從第二個 Group 開始放。
#define APP_EMMC_START (0x80000) // 使用者程式資料在eMMC中起始位置
#define APP_EXEC_START (0x2000) // 使用者程式首地址(中斷向量表地址),這裡是 ITCM 偏移 0x2000 處(偏移不強制)
#define APP_LENGTH (0x6000) // 使用者程式體大小
需要提醒的是,這個 L2Boot 務必要遵循 BootROM 對於 Non-XIP 程式載入的連結限制(空出前面位置給啟動頭),因為上電後其由 BootROM 載入執行。
三、L2Boot與App聯動
為了測試 L2Boot 功能是否正常,痞子衡在倉庫裡也放了一個示例使用者 App 工程(其實就是 SDK 裡的 hello world 例程),這個 App 由於是被 L2Boot 載入執行,所以它也不存在 BootROM 關於 Non-XIP 程式的連結地址限制問題了,完全看 L2Boot 的程式碼設計要求。
https://github.com/JayHeng/RT-SDMMC/tree/dev_l2boot_emmc/boards/mcu/mmc_app
現在我們用 MCUBootUtility 工具依次將痞子衡倉庫裡的 mmc_boot 程式(一鍵下載方式)和 mmc_app 程式(通用程式設計器下載方式,如下圖)下載進 eMMC 裡。切換 Boot Mode 後斷電覆位,如果你看到 mmc_app 正在執行,恭喜你,兩級啟動設計完成了。
至此,在i.MXRT1xxx系列上用NAND型啟動裝置時可用兩級設計縮短啟動時間痞子衡便介紹完畢了,掌聲在哪裡~~~
歡迎訂閱
文章會同時釋出到我的 部落格園主頁、CSDN主頁、知乎主頁、微信公眾號 平臺上。
微信搜尋"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。