痞子衡嵌入式:簡析i.MXRT1170 XECC功能特點及其保護串行NOR Flash和SDRAM之道



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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM