大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家分享的是i.MXRT1170 XECC功能特點及其保護序列NOR Flash和SDRAM之道

  ECC 是 “Error Correcting Code” 的簡寫,ECC 能夠實現錯誤檢查和糾正,含有 ECC 功能的記憶體一般稱為 ECC 記憶體,使用了 ECC 記憶體的系統在穩定性和可靠性上得到很大提升。相比前幾代不帶 ECC 的 i.MXRT10xx 型號,新一代 i.MXRT1170 在 ECC 上做了全面武裝,從 eFuse到 FlexRAM,從 OCRAM 到外部儲存空間全都加上了 ECC 功能。如下表所示,不同型別的儲存由不同的 ECC 控制器來守護:

  今天痞子衡給大家簡單介紹一下 i.MXRT1170 上用於保護掛載在 FlexSPI 和 SEMC 介面上的外部儲存器的 XECC 功能:

一、XECC功能簡介

1.1 XECC特點

  從使用者角度來說,其實 XECC 的設計特別簡單,當 XECC 使能後,任何對 ECC 保護區域的 AHB 訪問(注意僅 AHB 方式才能啟用 XECC,IPG 方式是不受 XECC 影響的)都會被 XECC 模組接管,WECC 元件負責根據使用者寫入的資料值產生 ECC 校驗值一併存入目標地址,RECC 元件負責根據使用者讀取的地址獲取相應 ECC 檢驗值並做檢驗處理後再返回資料值。WECC 和 RECC 元件可獨立開關控制。

  XECC 模組一共有三個,分別是 XECC_FLEXSPI1、XECC_FLEXSPI2、XECC_SEMC,每個模組均支援 4 個 ECC 區域的設定(區域最小單位 4KB,即 ECC_BASE/EDD_ADDRx 暫存器的低 12bits 總是 0)。

1.2 關於ECC設計細節

  關於 ECC 基本概念,參看《簡析i.MXRT1170 Cortex-M7 FlexRAM ECC功能特點、開啟步驟、效能影響》 的 1.2節,這裡不予贅述。

1.2.1 ECC檢驗能力

  XECC 中每 4bits 資料就會計算出一個 ECC 校驗值(4bits),不同於 FlexRAM ECC 會有專門的獨立儲存空間用於存放 ECC 校驗值,XECC 校驗值是緊跟著放在源資料後面的,這意味著 XECC 校驗值會佔據目標儲存器(Flash 或 SDRAM)裡受 ECC 保護區域的一半空間。

儲存型別 ECC校驗資料塊大小 ECC校驗值長度 ECC校驗能力
Raw NAND 512 bytes 4 bytes 5-bit檢錯,4-bit糾錯
XECC 4bits 4bits 2-bit檢錯,1-bit糾錯

  為便於 master 通過 AHB 匯流排訪問,實際 XECC 檢驗值是拓展到 32bits 來儲存的,即 32bits 原始資料後面會緊跟著 32bits XECC 檢驗值,如此往復如下圖所示。

  比如 XECC 保護掛在 FlexSPI1 上的 Flash,設定的 Flash ECC 保護區域為 0x30000000 - 0x30000FFF,共 4KB 空間。那麼從實際物理空間角度(IPG 方式去讀)來說 0x30000000 處儲存的是原始 4bytes 使用者資料(D0),0x30000004 處儲存的是 4bytes XECC 校驗值(E0),0x30000008 處儲存的又是原始 4bytes 使用者資料(D1),0x3000000c 處儲存的又是 4bytes XECC 校驗值(E1)...

  注意上述地址均表述的是實際實體地址,但 master 通過 AHB 匯流排直接讀寫 Flash 時,僅需訪問 0x30000000 - 0x300007FF 空間裡的 2KB 實際使用者資料即可,完全不需在意另外 2KB 的 XECC 檢驗值的處理,SoC 系統裡直接做了自動處理與地址轉換,即 0x30000000 處對應校驗後的 4bytes 使用者資料(D0),0x30000004 處對應校驗後的 4bytes 使用者資料(D1)...

1.2.2 ECC錯誤觸發處理

  ECC 錯誤分兩種,分別是 1-bit 錯誤和 2-bit 錯誤(針對 4bits 資料而言)。從軟體層面來看,1-bit 錯誤可以不用管,XECC 模組會自動糾錯。我們主要處理 2-bit 錯誤,由於 2-bit 錯誤僅能檢錯,無法糾錯,所以發生了這個錯誤,就意味著讀取的資料不可靠了。對於 1/2 bit錯誤,XECC 均提供了中斷響應(XECC_xxModule_INT_IRQn / XECC_xxModule_FATAL_INT_IRQn)。

  對於 32bits 資料而言,XECC 是可以糾正其中發生的 8bits 錯誤的,但前提是按序分割開的每 4bits 資料位僅能有 1bit 錯誤,如果這 4bits 資料位裡有多 bit 錯誤,我們依然想校正的話,需要藉助 Data Swap 功能,這裡不再單獨展開,可檢視 RM 瞭解細節。

二、開啟XECC的步驟

2.1 啟用XECC特性

  晶片出廠,預設是沒有啟用 XECC 特性的,如果需要開啟 XECC,需要燒寫 efuse,fusemap 中 0x840[3] 對應的是 XECC_ENABLE bit,我們需要將這個 bit 燒寫成 1,才能啟用 XECC 特性。

2.2 初始化儲存器介面外設

  在初始化 XECC 模組之前一般先初始化儲存器介面外設,這裡我們先初始化 FlexSPI1,因為測試板卡 MIMXRT1170-EVK 上預設是 FlexSPI1 連線的序列 NOR Flash。

void init_flexspi_flash(void)
{
flexspi_nor_flash_init(FLEXSPI1); // 儘量等待 FlexSPI 匯流排空閒再退出
if ((FLEXSPI1->MCR0 & FLEXSPI_MCR0_MDIS_MASK) != FLEXSPI_MCR0_MDIS_MASK)
{
while (!FLEXSPI_GetBusIdleStatus(FLEXSPI1));
} FLEXSPI_SoftwareReset(FLEXSPI1);
}

2.3 SDK驅動初始化XECC

  然後可以直接利用 SDK 裡的 fsl_xecc 驅動對 XECC 模組進行初始化,程式碼非常簡單,如下示例程式碼就是初始化 XECC_FLEXSPI1,使能 0x30000000 - 0x30000FFF 區域的讀寫 ECC 功能:

#include "fsl_xecc.h"

void init_flexspi_xecc(void)
{
xecc_config_t config;
XECC_GetDefaultConfig(&config); // 同時使能讀寫 XECC
config.enableXECC = true;
config.enableWriteECC = true;
config.enableReadECC = true; // 設定 ECC 區域(0x30000000 - 0x30000FFF)
config.Region0BaseAddress = FlexSPI1_AMBA_BASE;
config.Region0EndAddress = FlexSPI1_AMBA_BASE + 0x1000; // 初始化 XECC 模組
XECC_Init(XECC_FLEXSPI1, config);
}

2.4 AHB方式讀寫ECC目標區域

  最後就是利用 《其實i.MXRT下改造FlexSPI driver同樣支援AHB方式去寫入NOR Flash》 一文 3.3 節裡的 flexspi_nor_flash_program() 函式來對 Flash 做 AHB 方式的寫入,以啟用 XECC 工作。為了驗證 XECC 是否工作正常,可以分別用 IPG 和 AHB 方式讀回寫入的區域看最終結果。

SDK_ALIGN(static uint8_t s_nor_program_buffer[256], 4);
static uint8_t s_nor_ipg_read_buffer[256];
static uint8_t s_nor_ahb_read_buffer[256]; void test_flash_ecc_rw(void)
{
// 擦除 Flash 0x30000000 開始的 4KB 區域(1個Sector)
flexspi_nor_flash_erase_sector(FLEXSPI1, 0x0); for (uint32_t i = 0; i < 0xFFU; i++)
{
s_nor_program_buffer[i] = i;
}
// AHB 方式寫 256 位元組資料進 Flash 0x30000000 開始的地址
flexspi_nor_flash_program(FLEXSPI1, 0x30000000, s_nor_program_buffer, 256); DCACHE_CleanInvalidateByRange(0x30000000, 0x1000); // IPG 方式從 Flash 0x30000000 開始的地址讀出 256 位元組資料
flexspi_nor_flash_read(FLEXSPI1, 0x0, (void *)s_nor_ipg_read_buffer, 256); // AHB 方式從 Flash 0x30000000 開始的地址讀出 256 位元組資料
memcpy((void *)s_nor_ahb_read_buffer, (void *)0x30000000, 256);
}

  至此,簡析i.MXRT1170 XECC功能特點及其保護序列NOR Flash和SDRAM之道痞子衡便介紹完畢了,掌聲在哪裡~~~

歡迎訂閱

文章會同時釋出到我的 部落格園主頁CSDN主頁知乎主頁微信公眾號 平臺上。

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