大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家介紹的是恩智浦 i.MXRT1170 的 eFuse 空間訪問可靠性保護(hù)策略。
關(guān)于 i.MXRT 系列的 eFuse/OTP,痞子衡之前在介紹 Boot 時寫過兩篇,分別是針對 RT1050 的《eFuse 及其燒寫方法》 和針對 RT600 的《OTP 及其燒寫方法》,今天要介紹的 i.MXRT1170 eFuse 其實是這兩者的融合,在空間組織上(尤其是 Shadow Register)更像 RT1050,但是在訪問可靠性保護(hù)策略上又接近 RT600。關(guān)于訪問可靠性保護(hù)策略,痞子衡之前沒有提及,今天咱們就展開聊一聊。
一、eFuse 基本情況
eFuse 是 i.MXRT1170 內(nèi)嵌的一塊 OTP(One Time Programmable) memory,僅可被燒寫一次(這里指的是 bit 位從 0 到 1 不可逆),但可以被多次讀取。eFuse memory 的燒寫情況根據(jù)可靠性保護(hù)策略不同而不同。如果被冗余方法保護(hù),那么 eFuse 是按 bit 被燒寫的;如果是被 ECC 方法保護(hù)的,那么 eFuse 是按 word 被燒寫的。
i.MXRT1170 的 eFuse memory 用戶地址空間有 8Kbit(地址范圍為 0x900 - 0x18F0,低 4bit 地址位無效),分為 32 個 BANK,每個 BANK 含 8 個 word(1word = 4bytes)。下圖中 0x00 - 0xFF 是 eFuse 的用戶 bank word 索引地址,其與 eFuse 空間地址對應(yīng)關(guān)系是:
fuse_address = user_fuse_index * 0x10 + 0x900
此外 i.MXRT1170 的 eFuse memory 還有額外的 0.5Kbit 地址空間(范圍為 0x800 - 0x8F0,低 4bit 地址位無效),用于存放廠商(NXP)配置以及一些敏感配置,其與 eFuse 空間地址對應(yīng)關(guān)系是:
fuse_address = supp_fuse_index * 0x10
不管是 8Kbit 用戶空間還是額外的 0.5Kbit 敏感空間,我們都是可以訪問的,其 index 其實是統(tǒng)一編址的,下面這個 index 才是真正用于 blhost 工具或者 OCOTP API 的地址參數(shù):
fuse_address = fuse_index * 0x10 + 0x800
關(guān)于 i.MXRT1170 的 eFuse 一般特性(比如 Lock 屬性、OCOTP 控制器、Shadow Register)可參考痞子衡在文章開頭給出的兩篇文章,這里不予贅述。
二、eFuse 燒寫方法
有三種方法或工具可以幫助燒寫 eFuse,我們以燒寫和回讀 eFuse 地址 0xA80(MAC1_ADDR)為例,將 0x12345678 燒寫進(jìn) MAC1_ADDR 并回讀。根據(jù)上面公式我們可以得出 fuse_index = (fuse_address - 0x800) / 0x10 = 0x28,這個 fuse_index 便是底下我們傳給燒寫工具的地址。
2.1 blhost 工具
blhost 是個上位機命令行工具,其能正常工作的前提是預(yù)先加載一個特殊 flashloader 程序(SDK_x.x.x_MIMXRT1170-EVKboardsevkmimxrt1170bootloader_examplesflashloader)進(jìn) MCU 來實現(xiàn) eFuse 燒寫,flashloader 中集成了 OCOTP 驅(qū)動。關(guān)于 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 工具這一套太復(fù)雜,可以直接借助 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:
?
三、訪問可靠性保護(hù)策略
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 保護(hù),一類受 redundancy(冗余)保護(hù),這是本文要介紹的重點。
3.1 冗余保護(hù)
redundancy(冗余)保護(hù)是比較簡單的訪問可靠性保護(hù)策略,這個策略基本設(shè)計思想就是冗余,將 fuse word 一分為二,低 16bit 是用戶操作區(qū),高 16bit 是系統(tǒng)冗余區(qū)。燒寫時用戶只需要管低 16bit,高 16bit 則由系統(tǒng)自動完成復(fù)制燒寫?;刈x時得到的結(jié)果則是低 16bit 與高 16bit 的或(OR)結(jié)果。這樣的好處就是除非用戶操作區(qū)(低 16bit)和系統(tǒng)冗余區(qū)(高 16bit)均發(fā)生錯誤才會導(dǎo)致訪問不可靠。
redundancy(冗余)保護(hù)雖然一定程度上提高了訪問可靠性,但代價是犧牲了一半存儲空間,所謂魚和熊掌不可兼得,這個也是可以理解的。下面這些 eFuse 區(qū)域是受 redundancy(冗余)保護(hù)的,從功能上看這些區(qū)域是按 bit 定義的,功能比較分散,所以存在多次燒寫的需求,適用 redundancy(冗余)保護(hù)。
?
3.2 ECC 保護(hù)
ECC 保護(hù)是相對復(fù)雜的訪問可靠性保護(hù)策略,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 保護(hù)極大地提高了訪問可靠性,但綜合 eFuse 特點其代價就是整個 fuse word 僅可被燒寫一次(即使你一次只改一個 bit)。下面這些 eFuse 區(qū)域是受 ECC 保護(hù)的,不過從功能上看這些區(qū)域功能比較單一,一般都是一次性燒寫,所以也適用 ECC 保護(hù)。
?
至此,恩智浦 i.MXRT1170 的 eFuse 空間訪問可靠性保護(hù)策略痞子衡便介紹完畢了,掌聲在哪里~~~