大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是恩智浦i.MXRT系列MCU的ROM啟動日誌。 關於 i.MX RT 啟動問題解決的文章,痞子衡寫過非常多,其中大部分都是具體到某一類啟動設備下的具體問題分析,比較依賴經驗,這些經驗當然是非常有用的。此外也有一篇 《啟動失敗先查看SRC ...
大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是恩智浦i.MXRT系列MCU的ROM啟動日誌。
關於 i.MX RT 啟動問題解決的文章,痞子衡寫過非常多,其中大部分都是具體到某一類啟動設備下的具體問題分析,比較依賴經驗,這些經驗當然是非常有用的。此外也有一篇 《啟動失敗先查看SRC_SBMRx寄存器》,這篇內容通用於全部啟動設備,算是葵花寶典系列了。一直以來我們都當晶元啟動 ROM 程式運行狀態完全是個黑盒子,如果遇到異常,我們通常是去猜其可能遇到的問題,那麼能不能不全靠猜呢?答案是可以的!這便是痞子衡今天要聊 ROM 啟動日誌:
一、ROM啟動日誌原理
我們知道 i.MX RT 系列上電都是片內固化的 ROM 程式代碼先運行,由 ROM 來載入啟動設備里的用戶程式去執行,所以如果用戶程式不能正常啟動,一定是 ROM 程式執行過程中遇到了異常。
i.MX RT 初始 ROM 代碼來源於它的老大哥 i.MX 處理器,翻看 i.MX 參考手冊其中有關於 ROM Log Event 功能的描述,所謂 ROM Log Event 就是 ROM 程式在執行過程中將其重要節點事件(狀態)按時間軸記錄到一個日誌緩衝區里(日誌緩衝區通常在片內 RAM 固定地址處),這個日誌內容顯然對於分析 ROM 執行過程非常有用,那麼 i.MX RT 系列 ROM 代碼里有沒有保留這個功能呢?很高興,它還在!
下表記錄了 i.MX RT 全系列型號的 ROM 啟動日誌緩衝區地址:
晶元 | 啟動LOG地址 | 最大啟動LOG長度(Bytes) |
---|---|---|
i.MXRT118x | 0x3048a000 | 264 |
i.MXRT117x | 0x2024ad78 | 264 |
i.MXRT116x | 0x2024ad78 | 264 |
i.MXRT106x | 0x2020523c | 256 |
i.MXRT105x | 0x202051c8 | 256 |
i.MXRT104x | 0x2020523c | 256 |
i.MXRT102x | 0x2020515c | 256 |
i.MXRT1015 | 0x2020515c | 256 |
i.MXRT1011 | 0x20203d38 | 256 |
i.MXRT6xx | 0x10017f00 | 264 |
i.MXRT5xx | 0x10017ef8 | 264 |
二、獲取ROM啟動日誌數據
上一節我們知道了 ROM 啟動日誌緩衝區存儲地址,獲取其數據的方法就簡單了,可以直接連接上模擬器去讀取。不過這裡有需要註意的地方:如果是在 ROM 跳轉用戶程式之前發生的異常(日誌體現為啟動失敗),那麼內核 PC 應該還停留在 ROM 空間,這時候 RAM 區數據是完整的,無人破壞。如果是在 ROM 跳轉到用戶程式之後發生的異常(日誌體現為啟動成功),這時候用戶程式已經開始執行了,這可能會破壞 RAM 區數據(如果用戶程式鏈接文件里用到了存儲啟動日誌的 RAM 區域),這時候啟動日誌內容就不一定有效了。
以 i.MXRT1170 為例,痞子衡找了一塊開發板,上電後掛上 J-Link 調試器,使用 J-Link 命令行工具里的 SaveBin 命令從 0x2024ad78 地址處讀取最大的日誌數據存儲到 bootlog.bin 文件中。這裡需要註意在用 J-Link 連接目標設備時儘量不要選 MCU 型號,而用內核 CORTEX-M7 代替,這樣可以防止選了 MCU 型號而自動載入執行相應配套初始化腳本(萬一腳本里有片內 RAM 相關操作破壞日誌數據)。
命令格式:SaveBin <filename>, <addr>, <NumBytes>
命令解釋:Save target memory range into binary file.
除了藉助調試器,我們也可以藉助晶元串列下載模式下配套的 MCUBoot 工具鏈(Flashloader+blhost)來獲取 ROM 日誌數據,具體可見 《MCUBootUtility v6.3發佈,支持獲取與解析啟動日誌》 一文 2.3 小節里的途徑二。
三、解析ROM啟動日誌
i.MXRT 全系列 ROM 啟動日誌緩衝區數據結構並不是完全一樣的,主要分為兩個版本。其中 i.MXRT10xx 系列的日誌結構如下,跟 i.MX 處理器差不多,每條日誌內容壓縮存儲在一個 uint32_t 型變數里,最大支持 64 條日誌(當實際日誌超出 64 條時,後面的日誌直接被忽略不記)。
uint32_t pu_irom_log_buffer[64];
而 i.MXRT11xx 系列以及 i.MXRTxxx 系列的日誌結構相比前一代有一些改進,其結構如下,首先增加了 entryIndex 用於記錄有效的日誌個數,同時也增加了 checkSum 用於校驗全部日誌的完整性(但實際意義並不大,ROM 異常運行時計算 checkSum 時機難以確定)。
typedef struct _log_context
{
uint32_t entryIndex;
uint32_t logEntries[64];
uint32_t checkSum;
} log_context_t;
此時最大日誌個數依舊是 64(當實際日誌超出 64 條時,會找到日誌緩存區里排在最後的狀態為 Fail 或者 Fatal 的日誌,然後只保存其後面的正常日誌並繼續向下記錄)。
舉例說明:當前記錄到了第 65 條日誌
- 如果 logEntries[63:0] 里沒有 Fail 或者 Fatal 狀態的日誌,那麼清空數組,entryIndex 從 0 開始記錄。
- 如果 logEntries[31] 是排在最後的 Fail 或者 Fatal 狀態的日誌,那麼將 logEntries[63:32] 拷貝到 logEntries[31:0],entryIndex 重置為 32 再開始記錄。
除了以上啟動日誌緩衝區數據結構差別之外,i.MXRT10xx 與 i.MXRT11xx/i.MXRTxxx 在單條日誌值定義上也是完全不同的,不過具體如何解析每條日誌內容,用戶無需過多關註,這在痞子衡開發的 MCUBootUtility v6.3 軟體里已經全部搞定了,用戶可以直接查看解析後的日誌結果。
還是繼續以 i.MXRT1170 為例查看解析後的日誌結果,我們在 FlexSPI1 連接的串列 NOR Flash 里下載一個能正常啟動的 XIP 裸用戶程式(非簽名非加密),將晶元啟動模式設為 2'b10,當看到程式正常執行後,掛上調試器讀出啟動日誌數據(確保日誌存儲空間未被用戶程式破壞),並用 MCUBootUtility 軟體解析如下,還是能夠清晰地看到 ROM 執行過程信息的。
至此,恩智浦i.MXRT系列MCU的ROM啟動日誌痞子衡便介紹完畢了,掌聲在哪裡~~~
歡迎訂閱
文章會同時發佈到我的 博客園主頁、CSDN主頁、微信公眾號 平臺上。
微信搜索"痞子衡嵌入式"或者掃描下麵二維碼,就可以在手機上第一時間看了哦。
最後歡迎關註痞子衡個人微信公眾號【痞子衡嵌入式】,一個專註嵌入式技術的公眾號,跟著痞子衡一起玩轉嵌入式。
衡傑(痞子衡),目前就職於某全球頂級半導體原廠MCU系統部門,擔任高級嵌入式系統應用工程師。
專欄內所有文章的轉載請註明出處:http://www.cnblogs.com/henjay724/
與痞子衡進一步交流或咨詢業務合作請發郵件至 [email protected]
可以關註痞子衡的Github主頁 https://github.com/JayHeng,有很多好玩的嵌入式項目。
關於專欄文章有任何疑問請直接在博客下麵留言,痞子衡會及時回覆免費(劃重點)答疑。
痞子衡郵箱已被私信擠爆,技術問題不推薦私信,堅持私信請先掃碼付款(5元起步)再發。