大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是i.MXRT1170 MECC64功能特點及其保護片內OCRAM1,2之道。
ECC是 “Error Correcting Code” 的簡寫,ECC 能夠實現錯誤檢查和糾正,含有 ECC 功能的記憶體一般稱為 ECC 記憶體,使用了 ECC 記憶體的系統在穩定性和可靠性上得到很大提升。相比前幾代不帶 ECC 的 i.MXRT10xx 型號,新一代 i.MXRT1170 在ECC上做了全面武裝,從 eFuse 到 FlexRAM,從 OCRAM 到外部儲存空間全都加上了 ECC 功能。如下表所示,不同型別的儲存由不同的 ECC 控制器來守護:
今天痞子衡給大家簡單介紹一下 i.MXRT1170 上用於保護片內 OCRAM1,2 的 MECC64 功能:
一、MECC64功能簡介
1.1 MECC64特點
從使用者角度來說,其實 MECC64 的設計特別簡單,當 MECC64 使能後,任何對受保護的 OCRAM1/2 發起的 AXI 訪問都會被 MECC64 模組接管,MECC64 元件負責根據使用者寫入的資料產生 ECC 校驗值並將其存放於專用 OCRAM1/2_ECC 裡,讀訪問時根據使用者讀取的地址從相應 OCRAM1/2_ECC 地址處獲取 ECC 檢驗值並做檢驗處理後再返回資料。
MECC64 模組框圖裡畫了四個 ECC 校驗流程(分別對應四個 RAM Bank 控制器),這跟單個 512KB OCRAM 由四個 128KB Bank 組成一一對應(便於轉化 AXI64 介面到 RAM 介面),這樣的設計有如下兩個注意點:
Note1. OCRAM 四個 Bank 掛載在 AXI64 系統匯流排上,AXI[1:0] 決定了訪問得是 Bank0-3,這樣的設計可以支援對不同 Bank 的讀、寫操作同時進行。
Note2. ECC 計算單元是 64bits,這 64bits 資料必須在同一 Bank 裡,這個設計對 ECC 初始化操作影響較大,因此避免用 memset 函式去做初始化(STR指令是 byte access)。
MECC64 模組一共有兩個,分別是 MECC1、MECC2,分別對應保護 OCRAM1、OCRAM2。此外還有兩個專用 OCRAM1_ECC、 OCRAM2_ECC 存放 ECC 校驗值(當 MECC64 沒使能時,OCRAM1/2_ECC 也可當作普通 OCRAM 使用)。
MECC1 base address: 4001_4000h
MECC2 base address: 4001_8000h
1.2 關於MECC64設計細節
關於 MECC64 基本概念,參看《簡析i.MXRT1170 Cortex-M7 FlexRAM ECC功能特點、開啟步驟、效能影響》 的 1.2節,這裡不予贅述。
1.2.1 MECC64檢驗能力
MECC64 中每 64bits 資料就會計算出一個 ECC 校驗值(8bits),ECC 演算法用得是經典的 Hsiao Hamming。
儲存型別 | ECC校驗資料塊大小 | ECC校驗值長度 | ECC校驗能力 |
---|---|---|---|
Raw NAND | 512 bytes | 4 bytes | 5-bit檢錯,4-bit糾錯 |
MECC64 | 64bits | 8bits | 2-bit檢錯,1-bit糾錯 |
1.2.2 ECC錯誤觸發處理
ECC 錯誤分兩種,分別是 1-bit 錯誤和 2-bit 錯誤(針對 64bits 資料而言)。從軟體層面來看,1-bit 錯誤可以不用管,MECC64 模組會自動糾錯。我們主要處理 2-bit 錯誤,由於 2-bit 錯誤僅能檢錯,無法糾錯,所以發生了這個錯誤,就意味著讀取的資料不可靠了。對於 1/2 bit錯誤,MECC64 均提供了中斷響應(MECCx_INT_IRQn / MECCx_FATAL_INT_IRQn)。
這裡還需要特別提醒一下,當讀訪問是 64bits 時,發生 ECC 錯誤僅產生一次 ECC 中斷,但是如果是 32/16/8bits 讀訪問則會連續產生兩次 ECC 中斷,因為 ECC 校驗總是以 64bits 為基本資料單元。
二、開啟MECC64的步驟
2.1 啟用MECC64特性
晶片出廠,預設是沒有啟用 MECC64 特性的,如果需要開啟 MECC64,需要燒寫 efuse,fusemap 中 0x840[2] 對應的是 MECC_ENABLE bit,我們需要將這個 bit 燒寫成 1,才能啟用 MECC64 特性。
2.2 SDK驅動初始化MECC64
然後可以直接利用 SDK 裡的 fsl_mecc 驅動對 MECC64 模組進行初始化,程式碼非常簡單,如下示例程式碼就是初始化 MECC1,使能 OCRAM1 區域的讀寫 ECC 功能:
#include "fsl_mecc.h"
void init_mecc(void)
{
mecc_config_t config;
MECC_GetDefaultConfig(&config);
// 使能 MECC64,並且指明受保護的 OCRAM 空間
config.enableMecc = true;
config.Ocram1StartAddress = 0x20240000;
config.Ocram1EndAddress = 0x202BFFFF;
// 初始化 MECC64 模組,並且初始化 OCRAM 區域為全 0
MECC_Init(MECC1, &config);
}
進 MECC_Init() 函式內部可以看到其對 OCRAM 區域的初始化用得是 64bits 賦值(1.1小節裡的 Note2),這樣可以保證正確生成首次 ECC 校驗值,等 OCRAM 區域全部初始化過後,底下就可以對 OCRAM 進行任意資料長度的訪問了。
2.3 AXI方式讀寫OCRAM區域
現在我們直接除錯 \SDK_2_14_0_MIMXRT1170-EVKB\boards\evkbmimxrt1170\driver_examples\mecc\mecc_single_error\cm7\iar 工程,跑到 MECC 初始化結束後,開啟 Memory 視窗,可以看到 OCRAM1 區域(0x20240000 - 0x202BFFFF) 已經是全 0,OCRAM1_ECC 區域(0x20340000 - 0x2034FFFF)也是全 0。但是往 0x20240020 處寫入 8 位元組測試資料後,並沒有看到 OCRAM1_ECC 區域有資料上的變化,說明 ECC 校驗碼資料是受保護的,僅能被 MECC64 模組訪問,對使用者不可見。
三、啟用MECC64特性後的影響
前面講到 fusemap 中 0x840[2] 對應的是 MECC_ENABLE bit,這個 bit 被燒錄為 1 後,我們還需要初始化 MECC64 模組裡(開啟MECC->PIPE_ECC_EN[ECC_EN])才能真正開啟 OCRAM ECC 功能,但是別忘了晶片參考手冊裡 MECC64 章節有一個提醒:
是的,BootROM 上電執行,第一件事就是檢查 fuse MECC_ENABLE bit 位,如果已經置 1,那就立刻開啟 MECC1 和 MECC2 模組的 PIPE_ECC_EN[ECC_EN],即啟用 OCRAM ECC,但是 BootROM 並沒有初始化全部 OCRAM1 和 OCRAM2 區域,僅僅初始化了 OCRAM1 前 48KB,這部分是 BootROM 程式的 RW 區。
痞子衡找了兩塊 RT1170 板卡做了對比測試(晶片設為 Serial Downloader模式,掛上 JLink 讀取記憶體),未啟用 MECC64 特性的晶片 OCRAM 區域讀取出來全是隨機值,而啟用了 MECC64 特性的晶片僅 ROM RW 區被初始化了以及 OCRAMx_ECC 不可訪問外,其餘區域全是隨機值(這裡的讀取其實不太可靠,畢竟使能了 ECC 後首次訪問必須是寫,然後才能正常被讀寫)。
對於啟用了 MECC64 特性之後的晶片,無論是設計下載演算法還是 IDE 裡的初始化指令碼,或者 App 應用裡的變數訪問,如果涉及到 ROM RW 區之外的 OCRAM1,OCRAM2 區域,建議一律做先寫後讀處理,否則可能會出現奇怪的錯誤。
至此,i.MXRT1170 MECC64功能特點及其保護片內OCRAM1,2之道痞子衡便介紹完畢了,掌聲在哪裡~~~
歡迎訂閱
文章會同時釋出到我的 部落格園主頁、CSDN主頁、知乎主頁、微信公眾號 平臺上。
微信搜尋"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。