大家好,我是痞子衡,是正經(jīng)搞技術的痞子。今天痞子衡給大家介紹的是恩智浦 i.MXRT1170 的 eFuse 空間訪問可靠性保護策略。
關于 i.MXRT 系列的 eFuse/OTP,痞子衡之前在介紹 Boot 時寫過兩篇,分別是針對 RT1050 的《eFuse 及其燒寫方法》 和針對 RT600 的《OTP 及其燒寫方法》,今天要介紹的 i.MXRT1170 eFuse 其實是這兩者的融合,在空間組織上(尤其是 Shadow Register)更像 RT1050,但是在訪問可靠性保護策略上又接近 RT600。關于訪問可靠性保護策略,痞子衡之前沒有提及,今天咱們就展開聊一聊。
一、eFuse 基本情況
eFuse 是 i.MXRT1170 內(nèi)嵌的一塊 OTP(One Time Programmable) memory,僅可被燒寫一次(這里指的是 bit 位從 0 到 1 不可逆),但可以被多次讀取。eFuse memory 的燒寫情況根據(jù)可靠性保護策略不同而不同。如果被冗余方法保護,那么 eFuse 是按 bit 被燒寫的;如果是被 ECC 方法保護的,那么 eFuse 是按 word 被燒寫的。
i.MXRT1170 的 eFuse memory 用戶地址空間有 8Kbit(地址范圍為 0x900 - 0x18F0,低 4bit 地址位無效),分為 32 個 BANK,每個 BANK 含 8 個 word(1word = 4bytes)。下圖中 0x00 - 0xFF 是 eFuse 的用戶 bank word 索引地址,其與 eFuse 空間地址對應關系是:
fuse_address = user_fuse_index * 0x10 + 0x900
此外 i.MXRT1170 的 eFuse memory 還有額外的 0.5Kbit 地址空間(范圍為 0x800 - 0x8F0,低 4bit 地址位無效),用于存放廠商(NXP)配置以及一些敏感配置,其與 eFuse 空間地址對應關系是:
fuse_address = supp_fuse_index * 0x10
不管是 8Kbit 用戶空間還是額外的 0.5Kbit 敏感空間,我們都是可以訪問的,其 index 其實是統(tǒng)一編址的,下面這個 index 才是真正用于 blhost 工具或者 OCOTP API 的地址參數(shù):
fuse_address = fuse_index * 0x10 + 0x800
關于 i.MXRT1170 的 eFuse 一般特性(比如 Lock 屬性、OCOTP 控制器、Shadow Register)可參考痞子衡在文章開頭給出的兩篇文章,這里不予贅述。
二、eFuse 燒寫方法
有三種方法或工具可以幫助燒寫 eFuse,我們以燒寫和回讀 eFuse 地址 0xA80(MAC1_ADDR)為例,將 0x12345678 燒寫進 MAC1_ADDR 并回讀。根據(jù)上面公式我們可以得出 fuse_index = (fuse_address - 0x800) / 0x10 = 0x28,這個 fuse_index 便是底下我們傳給燒寫工具的地址。
2.1 blhost 工具
blhost 是個上位機命令行工具,其能正常工作的前提是預先加載一個特殊 flashloader 程序(SDK_x.x.x_MIMXRT1170-EVKboardsevkmimxrt1170bootloader_examplesflashloader)進 MCU 來實現(xiàn) eFuse 燒寫,flashloader 中集成了 OCOTP 驅(qū)動。關于 blhost 使用方法,詳見痞子衡 Boot 系列文章,這里僅列出兩個命令:
NXP-MCUBootUtilitytoolsblhost2_3win> .blhost.exe -u -- efuse-program-once 0x28 12345678
NXP-MCUBootUtilitytoolsblhost2_3win> .blhost.exe -u -- efuse-read-once 0x28
2.2 OCOTP 驅(qū)動
如果你覺得 blhost 工具這一套太復雜,可以直接借助 SDK 包里的 ocotp 例程(SDK_x.x.x_MIMXRT1170-EVKboardsevkmimxrt1170driver_examplesocotp),代碼也是非常簡單清晰:
1#include?"fsl_ocotp.h"
2
3int?main(void)
4{
5????status_t?status?=?kStatus_Success;
6????uint32_t?fuseData?=?0U;
7
8????/*?初始化 OCOTP 模塊?*/
9????OCOTP_Init(OCOTP,?0U);
10
11????/*?將 word 數(shù)據(jù)(0x12345678)寫入 fuse?index 為 0x28 的 eFuse?memory 里?*/
12????status?=?OCOTP_WriteFuseShadowRegister(OCOTP,?0x28,?0x12345678);
13
14????/*?從 fuse?index 為 0x28 的 eFuse?memory 處讀出一個 word*/
15????status?=?OCOTP_ReadFuseShadowRegisterExt(OCOTP,?0x28,?&fuseData,?1);
16}
2.3 MCUBootUtility 工具
如果你覺得 blhost 使用不友好,OCOTP 驅(qū)動又需要改代碼和下載運行,那么還有一個工具可以幫到你,那就是痞子衡開發(fā)的 MCUBootUtility 圖形界面工具,小白都能輕松上手燒寫 eFuse:
?
三、訪問可靠性保護策略
eFuse 的特性其實主要是 OCOTP 模塊決定的,翻開 i.MXRT1170 參考手冊的 OCOTP 章節(jié)的 Features 小節(jié),可以看到其比 RT1050 OCOTP 多了如下這三行:
? Supports ECC mode programming and reading for MTR fuse words by SkyBlue IPS bus
? Supports ECC mode programming and reading for all the user fuse words
? Supports redundancy mode programming and reading for all the supplementary fuse words
簡單地說就是 eFuse 空間被分成了兩類,一類受 ECC 保護,一類受 redundancy(冗余)保護,這是本文要介紹的重點。
3.1 冗余保護
redundancy(冗余)保護是比較簡單的訪問可靠性保護策略,這個策略基本設計思想就是冗余,將 fuse word 一分為二,低 16bit 是用戶操作區(qū),高 16bit 是系統(tǒng)冗余區(qū)。燒寫時用戶只需要管低 16bit,高 16bit 則由系統(tǒng)自動完成復制燒寫?;刈x時得到的結(jié)果則是低 16bit 與高 16bit 的或(OR)結(jié)果。這樣的好處就是除非用戶操作區(qū)(低 16bit)和系統(tǒng)冗余區(qū)(高 16bit)均發(fā)生錯誤才會導致訪問不可靠。
redundancy(冗余)保護雖然一定程度上提高了訪問可靠性,但代價是犧牲了一半存儲空間,所謂魚和熊掌不可兼得,這個也是可以理解的。下面這些 eFuse 區(qū)域是受 redundancy(冗余)保護的,從功能上看這些區(qū)域是按 bit 定義的,功能比較分散,所以存在多次燒寫的需求,適用 redundancy(冗余)保護。
?
3.2 ECC 保護
ECC 保護是相對復雜的訪問可靠性保護策略,ECC 算法是采用經(jīng)典的 SEC-DED(糾正 1bit,檢查 2bit),每個 fuse word 算出一個 ECC 校驗值(7bit),這個校驗值緊跟著存在 efuse word 后面(bit31:0 是用戶區(qū),bit38:32 是 ECC 區(qū)),ECC 區(qū)無法被用戶直接訪問。如果在回讀時發(fā)生 ECC 錯誤,可在 HW_OCOTP_OUT_STATUS0 寄存器(這是 RT1170 OCOTP 模塊新增的寄存器)里如下 bit 找到信息。
?
ECC 保護極大地提高了訪問可靠性,但綜合 eFuse 特點其代價就是整個 fuse word 僅可被燒寫一次(即使你一次只改一個 bit)。下面這些 eFuse 區(qū)域是受 ECC 保護的,不過從功能上看這些區(qū)域功能比較單一,一般都是一次性燒寫,所以也適用 ECC 保護。
?
至此,恩智浦 i.MXRT1170 的 eFuse 空間訪問可靠性保護策略痞子衡便介紹完畢了,掌聲在哪里~~~