痞子衡之前寫過兩篇文章《利用i.MXRT1xxx系列ROM提供的FlexSPI driver API可輕松IAP》、《其實i.MXRT1050,1020,1015系列ROM也提供了FlexSPI driver API》基本把i.MXRT1xxx全系列的ROM API及其FlexSPI NOR驅動設計都講清楚了,其實i.MXRTxxx系列的ROM API設計跟i.MXRT1xxx系列的設計思路差不多(其實本就是同一個恩智浦研發小組負責的),僅有一些微小差別,本文痞子衡主要就是點出那些差別。
大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是i.MXRTxxx系列ROM API設計細節。
痞子衡之前寫過兩篇文章 《利用i.MXRT1xxx系列ROM提供的FlexSPI driver API可輕松IAP》、《其實i.MXRT1050,1020,1015系列ROM也提供了FlexSPI driver API》 基本把i.MXRT1xxx全系列的ROM API及其FlexSPI NOR驅動設計都講清楚了,其實i.MXRTxxx系列的ROM API設計跟i.MXRT1xxx系列的設計思路差不多(其實本就是同一個恩智浦研發小組負責的),僅有一些微小差別,本文痞子衡主要就是點出那些差別。
ROM API代碼首先是在BootROM裡,BootROM代碼是出廠前固化在ROM區域的。因為架構設計的關系,i.MXRTxxx系列和i.MXRT1xxx系列的ROM區域在系統記憶體裡的映射位址不同。
下表是i.MXRTxxx系列代表型号i.MXRT500的部分系統記憶體映射,可以看到ROM區域起始位址是0x03000000(非安全域)。目前i.MXRTxxx都是Cortex-M33核心,支援TrustZone特性,是以0x13000000也是ROM起始位址(安全域),為了通用性,我們認0x03000000就可以了,這個位址在安全狀态和非安全狀态下都能被通路。

下表是i.MXRT1xxx系列代表型号i.MXRT1060的部分系統記憶體映射,可以看到ROM區域起始位址是0x00200000。i.MXRT1xxx系列都是Cortex-M7核心,沒有TrustZone特性,不存在i.MXRTxxx上那樣的兩種狀态域下的位址。
在i.MXRT1xxx系列ROM API介紹的文章裡,痞子衡介紹過g_bootloaderTree位址值被複制了一份放在了BootROM中斷向量表第8個向量的位置處(該向量為ARMv7-M架構下未定義的系統向量),是以讀取0x0020001c處開始的4bytes便能找到i.MXRT1xxx系列的g_bootloaderTree。
但是由于i.MXRTxxx是Cortex-M33核心,屬于ARMv8-M架構,從下圖中可以看出ARMv8-M架構下中斷向量表第8個向量是SecureFault,已經被定義了,是以BootROM把g_bootloaderTree位址值放到了第9個向量的位置處(該向量為ARMv8-M架構下未定義的系統向量),故讀取0x03000020處開始的4bytes才能找到i.MXRTxxx系列的g_bootloaderTree(這種方式在實際API調用中并不可取,至于原因嘛,先賣個關子)。
下面是i.MXRT500 BootROM工程的startup檔案(IAR版),g_bootloaderTree确實在第9個向量處:
下面是i.MXRTxxx系列ROM API原型定義及其執行個體(适用i.MXRT500/600),基本形式跟i.MXRT1xxx差不多,但是API功能更豐富,除了FlexSPI NOR驅動,還有iap api、USB low-level driver、otp driver等(我們知道,i.MXRTxxx與LPC系列同根同源,LPC系列ROM裡一般都會內建很多經典SDK驅動,比如内部flash、low power驅動,有了這些穩定的驅動API,LPC系列的使用者手冊裡甚至都會省去這些IP的寄存器介紹,直接就是API的介紹)。
i.MXRT1xxx系列ROM API執行個體g_bootloaderTree都是讓連結器自由連結的,是以每個具體型号的實際ROM API連結位址沒有一緻的規律可循(這也是為什麼要在中斷向量表裡固定位置統一儲存一份),而這點在i.MXRTxxx上有了改進,i.MXRTxxx裡将g_bootloaderTree放到了 .rom_api_tree_section 段裡,在連結檔案裡将該段固定連結在ROM區域最後4KB處(BootROM代碼沒有把全部ROM空間用盡)。
下面是i.MXRTxxx BootROM源檔案中g_bootloaderTree的定義,加了段修飾。此外還有額外的k_romcrc,标示API執行個體區域的結束。
下面是i.MXRTxxx連結檔案(IAR工程)中 .rom_api_tree_section 段的處理(i.MXRT500型号示例,ROM空間是192KB)。你可能好奇為啥ROM_API_TREE_xx等值是放在0x13000000開始的安全域ROM空間映射,BootROM屬于上電啟動第一級,負責晶片系統的安全和啟動,當然是工作在安全狀态下,可以通路安全域位址空間。
基于上面的設計,你才會在i.MXRT500參考手冊裡Non-Secure Boot ROM章節看到如下ROM API位址及結構資訊圖(圖中僅标了常用的API功能函數),實際ROM API調用時,App的執行其實都是經過ROM引導和認證的,App中既可以通路安全域位址(0x1302f000)來調用API,也可以通路非安全域位址(0x0302f000)來調用API。
最後再來回答前面賣的關子,為什麼i.MXRTxxx系列通過BootROM中斷向量表第9個向量值來通路ROM API這種方式并不可取?其實從BootROM煞費苦心地将g_bootloaderTree固定連結在ROM區域最後4KB處,你就能看出其用意。如果你挂上調試器直接通路i.MXRTxxx的ROM區域前20KB的空間,你會發現無法通路,在App裡AHB方式讀這個區域,也會直接産生HardFault,因為BootROM裡做了特殊設計故意隐藏了前20KB空間,這個空間裡存放了BootROM想要保護的資料和代碼,至于内容是啥,純屬機密,恕不奉告,哈哈。
至此,i.MXRTxxx系列ROM API設計細節痞子衡便介紹完畢了,掌聲在哪裡~~~
文章會同時釋出到我的 部落格園首頁、CSDN首頁、知乎首頁、微信公衆号 平台上。
微信搜尋"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。
最後歡迎關注痞子衡個人微信公衆号【痞子衡嵌入式】,一個專注嵌入式技術的公衆号,跟着痞子衡一起玩轉嵌入式。
衡傑(痞子衡),目前就職于恩智浦MCU系統部門,擔任嵌入式系統應用工程師。
專欄内所有文章的轉載請注明出處:http://www.cnblogs.com/henjay724/
與痞子衡進一步交流或咨詢業務合作請發郵件至 [email protected]
可以關注痞子衡的Github首頁 https://github.com/JayHeng,有很多好玩的嵌入式項目。
關于專欄文章有任何疑問請直接在部落格下面留言,痞子衡會及時回複免費(劃重點)答疑。
痞子衡郵箱已被私信擠爆,技術問題不推薦私信,堅持私信請先掃碼付款(5元起步)再發。