天天看點

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

如今基于i.MXRT的客戶量産産品越來越多,關于OTA安全更新的客戶支援也越來越多。早期的i.MXRT型号(比如i.MXRT1050/1020/1015)在做基于FlexSPI NOR Flash的OTA更新時,有一個最大痛點即App版本切換不便,是以後面的i.MXRT型号中(比如i.MXRT1064/1060/1010)新增了FlexSPI的Remap功能。今天痞子衡就來介紹一下這個Remap功能是如何用于安全OTA的。

  大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是i.MXRT部分型号上新增的FlexSPI Remap功能。

  OTA更新設計幾乎是每個量産客戶都繞不開的話題,産品釋出後免不了要做固件(App)更新以修複bug或者增加新特性。更新App是個麻煩事,因為處理不好,App被破壞了導緻啟動不了,産品就容易變磚,變了磚即使能救回來,也非常影響使用者體驗。

  如今基于i.MXRT的客戶量産産品越來越多,關于OTA安全更新的客戶支援也越來越多。早期的i.MXRT型号(比如i.MXRT1050/1020/1015)在做基于FlexSPI NOR Flash的OTA更新時,有一個最大痛點即App版本切換不便,是以後面的i.MXRT型号中(比如i.MXRT1064/1060/1010)新增了FlexSPI的Remap功能。今天痞子衡就來介紹一下這個Remap功能是如何用于安全OTA的。

  在講App版本切換不便痛點前,先給大家簡單介紹一下OTA更新設計過程中處理App版本的一般套路。下面是一個典型的OTA設計中NOR Flash裡内容分布,最前面一般是L2 OTA Boot,負責更新更新或者啟動App;接下來是主App區,就是真正實作産品功能的App;然後是Temp區,一般用作App更新臨時緩沖區;最後是User Data區,存放一些固定不變的圖檔資源(如果有GUI的話),或者放一些動态儲存的系統關鍵資料。

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

  這裡面的Temp區設計是一個關鍵,如果沒有Temp區,在OTA更新時隻能原地覆寫主App區(App 1),更新過程中一旦發生意外(比如斷電),系統裡就沒有完整App可用了,會導緻産品變磚。而有了Temp區作緩存,更新過程就會可靠多了,如下圖所示,新版本App(App 2)首先會被放在Temp區,僅當App 2完整性校驗通過之後,才會從Temp區搬移到主App區,搬移完成之後再擦除Temp區。這樣的設計下,即使App 2下載下傳到Temp區或者App 2往App 1搬移時發生意外,系統裡都有完整App用于恢複。

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

  上面介紹的處理App版本的典型設計在實際應用中其實不算特别常用,因為系統中僅存在一份最新的App,其不支援版本復原。有時候我們的新版本App因為一些原因(比如新增功能有bug)導緻運作并不穩定,我們希望能夠回退到上一個已經運作穩定的舊版本App,系統需要保留兩份不同版本App,是以就有了如下改進的OTA設計NOR Flash内容分布,在主App區(App 2)後面增加一個次App區(App 1)。

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

  這時候更新過程稍微複雜一點,如下圖所示,多了一步主App區(App 2)搬移到次App區(App 1)的過程(Step 2),這也是版本復原的關鍵。不過萬事都是有代價的,版本復原的代價就是增加了OTA更新的時間,以及将Flash中App區從兩段劃分成三段,導緻App最大長度減少了1/3。

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

  前面介紹了OTA更新設計中管理App版本的兩種方法,注意這裡的App都是指在FlexSPI NOR Flash中原地執行(XIP)的App,代碼連結在晶片内部SRAM或者外擴RAM的App不在讨論範疇(這種Non-XIP屬性的App更新不存在版本切換的痛點)。現在聊XIP App版本切換的痛點:

  在上面的圖中你會發現,新版本App最終都會被搬到主App區(就是緊接着L2 OTA Boot後面的第一個App位置),為什麼要這麼做?這就涉及MCU中App連結相關知識了,因為MCU不同于MPU,其沒有MMU元件,不支援虛拟記憶體,是以App一般都是固定位址連結,App代碼體二進制資料僅放在連結的位置才可以正常執行,将App拷貝到非連結位置是不能運作的。OTA更新中雖然App版本不同,但是這些App都有一個共同的連結位址,即都是連結在主App區的。

  比如下圖OTA系統中使用了一塊8MB的Flash,在i.MXRT裡的系統映射起始位址是0x60000000,L2 OTA Boot和User Data各占1MB,剩餘6MB被均分成3段,那麼App x/2/1都需要從0x60100000位址開始連結放中斷向量表。

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

  可能你會說,我們也可以設計不同連結位址的App,這樣就不需要将新版本App都往主App區搬移了,是的,原理上可以這麼做,但實踐中,需要管理不同連結位址的App,導緻OTA更新上位機端操作比較複雜,容易出錯(目前待更新的App必須與上一次更新的App連結位址不同),是以這種方法不推薦。

  是以最大的痛點就是App總要往主App區搬移,既增加了OTA更新時間,也因為搬移操作過多減小了Flash的壽命(總擦寫次數是一定的)。

  我們知道FlexSPI連接配接的NOR Flash能夠實作XIP,最主要的原因是FlexSPI有對應系統映射空間且NOR Flash自身可以按Byte位址通路,這裡的系統映射空間主要用于AHB方式讀。CPU去從系統映射空間裡讀App指令碼,FlexSPI子產品會自動将AHB總線傳來的位址資料請求轉換成IPG指令方式去擷取NOR Flash裡的對應指令内容。更多原理可參看 《在串行NOR Flash XIP調試原理》。

  i.MXRT1060中配置設定給FlexSPI的系統映射空間如下,兩個FlexSPI一共配置設定了496MB。

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

  i.MXRT1010中配置設定給FlexSPI的系統映射空間如下,一個FlexSPI配置設定了504MB。

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

  i.MXRT中的Remap設計其實是系統架構層面的,在AHB總線層面做一個位址重定向,并不是在FlexSPI子產品裡實作的,這也是為什麼Remap相關控制在IOMUXC_GPR寄存器裡(設定後Remap立刻生效,但這些寄存器不是非易失性的,普通軟複位就會置位)。下面是Remap控制寄存器(對于含兩個FlexSPI的型号,Remap控制是同時作用的):

Remap功能

對應控制寄存器

i.MXRT106x

i.MXRT1010

ADDR_START

IOMUXC_GPR_GPR30

IOMUXC_GPR_GPR27

ADDR_END

IOMUXC_GPR_GPR31

IOMUXC_GPR_GPR28

ADDR_OFFSET

IOMUXC_GPR_GPR32

IOMUXC_GPR_GPR29

  Remap設計說起來其實特别簡單,就是位址(addr)落在[ADDR_START, ADDR_END]裡的AHB通路,其實際通路到的是addr + ADDR_OFFSET位置處的資料。(注意ADDR_START, ADDR_END, ADDR_OFFSET都是4KB對齊的)

  舉例來看,根據ADDR_OFFSET的大小不同,會有三種情況:第一種是ADDR_OFFSET = ADDR_END - ADDR_START,如下圖所示。這也是OTA中最常用的情況,ADDR_START可設為主App區起始位址,ADDR_END可設為次App區起始位址。

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

  第二種是ADDR_OFFSET > ADDR_END - ADDR_START,如下圖所示:

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

  第三種是ADDR_OFFSET < ADDR_END - ADDR_START,如下圖所示。不過這種情況在實際應用中并不推薦。

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

  啟用了Remap功能後,很多人會對調用FlexSPI NOR驅動函數去擦寫Flash有點疑惑。其實完全不必要有這種疑惑,擦寫Flash操作走的是FlexSPI IPG指令方式,屬于FlexSPI子產品内部的事情,完全不受上層系統Remap功能影響,你可以就當Remap功能完全不存在,原來怎麼做還是怎麼做。

  下面這段測試代碼是在MIMXRT1060-EVK上跑的,用ROM API驅動擦寫0x60100000位址,擦寫操作前加了一段Remap設定幹擾,實測下來Remap設定對擦寫沒有任何影響,複位後去讀Flash,操作的還是原0x60100000位址。其實從測試代碼也能看出端倪,API裡傳入是0x100000,這是Flash絕對偏移位址,跟系統映射沒關系。

  有了Remap功能,現在再回到OTA設計,此時我們隻需要兩個App分區即可。新版本App(App 2)首先會被放在後Temp區,App 2更新完成且校驗通過之後,直接使用Remap功能将App 2重映射到App 1位置,此舉既不增加額外實體搬移操作,也同時保留了新舊兩份App可以實作版本復原,而且整個OTA過程僅有一次App擦寫耗時也最短,完美解決痛點。

  當Remap功能已被使能,再有新版本App(App 3)更新需求時,其需要被下載下傳到前Temp區,注意Flash擦寫操作都是通過IPG方式實作,是以不受Remap功能幹擾,僅需關注絕對實體位址偏移,App下載下傳完成,取消Remap功能即可,如此往複。

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

  至此,i.MXRT部分型号上新增的FlexSPI Remap功能痞子衡便介紹完畢了,掌聲在哪裡~~~

文章會同時釋出到我的 部落格園首頁、CSDN首頁、知乎首頁、微信公衆号 平台上。

微信搜尋"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

  最後歡迎關注痞子衡個人微信公衆号【痞子衡嵌入式】,一個專注嵌入式技術的公衆号,跟着痞子衡一起玩轉嵌入式。

痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA
痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA
痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI位址重映射(Remap)功能可安全OTA

  衡傑(痞子衡),目前就職于恩智浦MCU系統部門,擔任嵌入式系統應用工程師。

  專欄内所有文章的轉載請注明出處:http://www.cnblogs.com/henjay724/

  與痞子衡進一步交流或咨詢業務合作請發郵件至 [email protected]

  可以關注痞子衡的Github首頁 https://github.com/JayHeng,有很多好玩的嵌入式項目。

  關于專欄文章有任何疑問請直接在部落格下面留言,痞子衡會及時回複免費(劃重點)答疑。

  痞子衡郵箱已被私信擠爆,技術問題不推薦私信,堅持私信請先掃碼付款(5元起步)再發。