加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

i.MXRTXXX系列OTP及其燒寫方法

2019/12/16
327
閱讀需 13 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

i.MXRTxxx 啟動系列第二篇文章 Boot 配置(ISP Pin, OTP) 里痞子衡提到了 OTP,部分 Boot 配置都存儲在 OTP memory 里,但是對 OTP 的介紹僅僅淺嘗輒止,沒有深入,今天痞子衡就為大家再進一步介紹 OTP。

  

OTP 是 i.MXRTxxx 里一塊特殊的存儲區(qū)域,用于存放全部芯片配置信息,其中有一部分配置信息和 Boot 相關(guān)。這塊特殊存儲區(qū)域并不在 ARM 的 4G system address 空間里,需要用特殊的方式去訪問(讀 / 寫),如何訪問 OTP 是本篇文章的重點。

一、OTP 基本原理

1.1 OTP 屬性(OTP, Shadow Lock)

OTP 本質(zhì)上就是 i.MXRTxxx 內(nèi)嵌的一塊 One Time Programmable memory,僅可被燒寫一次,但可以被多次讀取。OTP memory 的燒寫大部分是按 Word 進行的(也有極少部分是按 Bit 進行的),初始狀態(tài)下所有 OTP bit 均為 0,通過特殊的燒寫時序可以將 bit 從 0 改成 1,一旦某 bit 被燒寫成 1 后便再也無法被修改(可理解為硬件熔絲燒斷了無法恢復(fù))。
  

i.MXRT600 的 OTP memory 總地址空間有 2KB(word index 范圍為 0x000 - 0x1FF),分為 64 個 BANK,每個 BANK 含 8 個 word(1word = 4bytes)。
  

OTP memory 空間除了 OTP 特性外,還有 Shadow Lock 控制特性,Shadow Lock 控制是 OTP memory 的標(biāo)配,Lock 控制有二種:第一種是 WP,即寫保護,用于保護 OTP 區(qū)域?qū)?yīng)的 shadow register 不能被改寫;第二種是 RP,即讀保護,被保護的 OTP 區(qū)域?qū)?yīng)的 shadow register 不能被讀取??吹竭@里,你會發(fā)現(xiàn) i.MXRTyyyy 的 efuse 里的 LOCK 控制是同時針對 efuse 本身和 shadow register 的;而 i.MXRTxxx 的 OTP 里的 LOCK 控制僅針對 shadow register,那么對 OTP 本身的保護在哪里呢?先別急,后面會給你答案。
  

Shadow Lock 控制在 OTP 的 BANK0_word4、BANK1_word8/9,如下是 RT600 具體 Lock bit 定義:

關(guān)于 OTP 空間所有 bit 定義詳見 Reference Manual 里的 otpmap Descriptions。

1.2 OCOTP 控制器與 Shadow Register

i.MXRTxxx 內(nèi)部有一個硬件 IP 模塊叫 OCOTP_CTRL,即 OCOTP 控制器,對 OTP memory 的讀寫控制操作其實都是通過這個 OCOTP 控制器實現(xiàn)的,下圖是 OCOTP_CTRL 模塊圖:

  

OCOTP_CTRL 模塊寄存器一共分兩類:一類是 IP 控制寄存器,用于實現(xiàn)對 OTP memory 的讀寫操作時序控制;一類是 Shadow register,用于上電時自動從 OTP memory 獲取數(shù)據(jù)并緩存,這樣我們可以直接訪問 Shadow register 而不用訪問 OTP memory 也能獲取 OTP 內(nèi)容(注意:當(dāng)芯片運行中燒寫 OTP,Shadow register 的值并不會立刻更新,需要執(zhí)行 IP 控制器的 reload 命令或者將芯片 reset 才能同步)。
  

下圖是 RT600 里的 OCOTP_CTRL 模塊寄存器 map,其中 Shadow register 寄存器偏移地址范圍是 0x000 - 0x7FF(注意并不是所有 OTP Word 都會被加載到 Shadow register 里,雖然 Shadow register 預(yù)留了全部的 OTP 位置。這點與 i.MXRTyyyy efuse 會全部加載到 Shadow register 不同,原因是 i.MXRTxxx 的 OTP 里會有很多 Peripheral 寄存器加載初值,如果這些 OTP 值目的是加載 Peripheral,那就沒有必要再加載到 Shadow register 里,而 i.MXRTyyyy 的 efuse 值沒有加載 Peripheral 寄存器的用途)。IP 控制寄存器偏移地址范圍是 0x800 - 0x82C:

  

痞子衡寫過關(guān)于 i.MXRTyyyy 的 eFUSE 燒寫的文章 飛思卡爾 i.MX RTyyyy 系列 MCU 啟動那些事(5)- 再聊 eFUSE 及其燒寫方法 ,其實 i.MXRTxxx 的 OCOTP 控制器與 i.MXRTyyyy 里的 OCOTP 控制器非常相似,雖然兩者在寄存器組織上有差異,但其共同點更多。不過提及差異,有一個地方痞子衡不得不提,那就是 CTRL 寄存器的 bit15,在 i.MXRTyyyy 上這個 bit 是保留的,但是 i.MXRTxxx 上這個 bit 為 WORDLOCK,顧名思義即提供對操作的 OTP word 區(qū)域進行保護(主要是寫保護),下一節(jié)介紹的 efuse-program-once 命令第三個可選參數(shù)[nolock/lock]其實就是利用了這個 bit。

二、使用 blhost 燒寫 OTP

OTP memory 的燒寫是通過 OCOTP_CTRL 模塊來實現(xiàn)的,我們當(dāng)然可以在 Application 中集成 OCOTP_CTRL 的驅(qū)動程序,然后在 Application 調(diào)用 OCOTP_CTRL 的驅(qū)動程序完成 OTP 的燒寫,但這種方式并不是痞子衡要介紹的重點,痞子衡要介紹的是通過 Serial ISP 模式配套的 blhost.exe 上位機工具實現(xiàn) OTP 的燒寫。
  

痞子衡在前面的文章里介紹過如何進入 Serial ISP 模式與 BootROM 通信,此處假設(shè)你已經(jīng)使用 blhost 與 BootROM 建立了通信。讓我們再來回顧一下 blhost 的命令 help,可以得知 efuse-program-once 這個命令就是我們想要的命令。

PS D:NXP-MCUBootUtilitytoolsblhost2_3win> .blhost.exe

usage: D:NXP-MCUBootUtilitytoolsblhost2_3winblhost.exe

? ? ? ? ? ? ? ? ? ? ? ?[-p|--port <name>[,<speed>]]

? ? ? ? ? ? ? ? ? ? ? ?[-u|--usb [[[<vid>,]<pid>]]]

? ? ? ? ? ? ? ? ? ? ? ?-- command <args...>

Command:

? efuse-program-once <addr> <data> [nolock/lock]

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Program one word of OCOTP Field

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<addr> is ADDR of OTP word, not the shadowed memory address.

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<data> is hex digits without prefix '0x'

? efuse-read-once <addr>

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Read one word of OCOTP Field

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<addr> is ADDR of OTP word, not the shadowed memory address.
  

讓我們試一下 efuse-program-once 這個命令,開始試之前要解決 2 個問題:
  

addr 參數(shù)到底是什么地址?幫助里說是 OTP word address,其實這個地址就是 1.1 節(jié)里介紹的 word index,index 范圍為 0x000 - 0x1FF,對應(yīng) 512 個可讀寫操作的 OTP Word。
  

data 參數(shù)到底是什么格式?幫助里說是 hex digits without prefix '0x',但是似乎沒有指明長度,我們知道每一個 index 對應(yīng)的是 4byte,那就應(yīng)該是 8 位 16 進制數(shù)據(jù)(實測下來必須要填 8 位,如果是非 8 位會返回 Error: invalid command or arguments)。
  

弄清了問題,那我們做一個小測試:要求將 OTP 里的 REVOKE_IMG_KEY word 的最低 byte 燒寫成 0x5A。翻看 OTP Memory Footprint 表,找到 REVOKE_IMG_KEY 的 index 地址是 0x66(對應(yīng) Shadow register 地址是 0x40130198),命令搞起來:

PS D:NXP-MCUBootUtilitytoolsblhost2_3win> .blhost.exe -u -- efuse-program-once 0x66 0000005A

Inject command 'efuse-program-once'

Successful generic response to command 'efuse-program-once'

Response status = 0 (0x0) Success.

PS D:NXP-MCUBootUtilitytoolsblhost2_3win> .blhost.exe -u -- efuse-read-once 0x66

Inject command 'efuse-read-once'

Response status = 0 (0x0) Success.

Response word 1 = 4 (0x4)

Response word 2 = 90 (0x5a)
  

看起來命令執(zhí)行正常,如果此時你用 J-Link 去讀取對應(yīng) Shadow register 的值,你會發(fā)現(xiàn)剛才燒寫的 OTP 數(shù)據(jù)并沒有自動同步更新到 Shadow register 里。與 i.MXRTyyyy 系列下 Flashloader 里 efuse program 操作有所不同的是,i.MXRTxxx Serial ISP 模式下 blhost 里的 efuse-program-once 命令僅包含 program 命令,沒有集成 reload 命令。因此想要刷新 Shadow register,必須復(fù)位芯片。

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

碩士畢業(yè)于蘇州大學(xué)電子信息學(xué)院,目前就職于恩智浦(NXP)半導(dǎo)體MCU系統(tǒng)部門,擔(dān)任嵌入式系統(tǒng)應(yīng)用工程師。痞子衡會定期分享嵌入式相關(guān)文章