痞子衡嵌入式:簡析i.MXRT1170 MECC64功能特點及其保護片內OCRAM1,2之道


  大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是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主頁知乎主頁微信公衆號 平臺上。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章