痞子衡嵌入式:簡析i.MXRT1170 XECC功能特點(diǎn)及其保護(hù)串行NOR Flash和SDRAM之道
大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家分享的是i.MXRT1170 XECC功能特點(diǎn)及其保護(hù)串行NOR Flash和SDRAM之道。
ECC 是 “Error Correcting Code” 的簡寫,ECC 能夠?qū)崿F(xiàn)錯(cuò)誤檢查和糾正,含有 ECC 功能的內(nèi)存一般稱為 ECC 內(nèi)存,使用了 ECC 內(nèi)存的系統(tǒng)在穩(wěn)定性和可靠性上得到很大提升。相比前幾代不帶 ECC 的 i.MXRT10xx 型號,新一代 i.MXRT1170 在 ECC 上做了全面武裝,從 eFuse到 FlexRAM,從 OCRAM 到外部存儲(chǔ)空間全都加上了 ECC 功能。如下表所示,不同類型的存儲(chǔ)由不同的 ECC 控制器來守護(hù):
今天痞子衡給大家簡單介紹一下 i.MXRT1170 上用于保護(hù)掛載在 FlexSPI 和 SEMC 接口上的外部存儲(chǔ)器的 XECC 功能:
一、XECC功能簡介
1.1 XECC特點(diǎn)
從用戶角度來說,其實(shí) XECC 的設(shè)計(jì)特別簡單,當(dāng) XECC 使能后,任何對 ECC 保護(hù)區(qū)域的 AHB 訪問(注意僅 AHB 方式才能激活 XECC,IPG 方式是不受 XECC 影響的)都會(huì)被 XECC 模塊接管,WECC 組件負(fù)責(zé)根據(jù)用戶寫入的數(shù)據(jù)值產(chǎn)生 ECC 校驗(yàn)值一并存入目標(biāo)地址,RECC 組件負(fù)責(zé)根據(jù)用戶讀取的地址獲取相應(yīng) ECC 檢驗(yàn)值并做檢驗(yàn)處理后再返回?cái)?shù)據(jù)值。WECC 和 RECC 組件可獨(dú)立開關(guān)控制。
XECC 模塊一共有三個(gè),分別是 XECC_FLEXSPI1、XECC_FLEXSPI2、XECC_SEMC,每個(gè)模塊均支持 4 個(gè) ECC 區(qū)域的設(shè)置(區(qū)域最小單位 4KB,即 ECC_BASE/EDD_ADDRx 寄存器的低 12bits 總是 0)。
1.2 關(guān)于ECC設(shè)計(jì)細(xì)節(jié)
關(guān)于 ECC 基本概念,參看《簡析i.MXRT1170 Cortex-M7 FlexRAM ECC功能特點(diǎn)、開啟步驟、性能影響》 的 1.2節(jié),這里不予贅述。
比如 XECC 保護(hù)掛在 FlexSPI1 上的 Flash,設(shè)置的 Flash ECC 保護(hù)區(qū)域?yàn)?0x30000000 - 0x30000FFF,共 4KB 空間。那么從實(shí)際物理空間角度(IPG 方式去讀)來說 0x30000000 處保存的是原始 4bytes 用戶數(shù)據(jù)(D0),0x30000004 處保存的是 4bytes XECC 校驗(yàn)值(E0),0x30000008 處保存的又是原始 4bytes 用戶數(shù)據(jù)(D1),0x3000000c 處保存的又是 4bytes XECC 校驗(yàn)值(E1)...
注意上述地址均表述的是實(shí)際物理地址,但 master 通過 AHB 總線直接讀寫 Flash 時(shí),僅需訪問 0x30000000 - 0x300007FF 空間里的 2KB 實(shí)際用戶數(shù)據(jù)即可,完全不需在意另外 2KB 的 XECC 檢驗(yàn)值的處理,SoC 系統(tǒng)里直接做了自動(dòng)處理與地址轉(zhuǎn)換,即 0x30000000 處對應(yīng)校驗(yàn)后的 4bytes 用戶數(shù)據(jù)(D0),0x30000004 處對應(yīng)校驗(yàn)后的 4bytes 用戶數(shù)據(jù)(D1)...
1.2.2 ECC錯(cuò)誤觸發(fā)處理
ECC 錯(cuò)誤分兩種,分別是 1-bit 錯(cuò)誤和 2-bit 錯(cuò)誤(針對 4bits 數(shù)據(jù)而言)。從軟件層面來看,1-bit 錯(cuò)誤可以不用管,XECC 模塊會(huì)自動(dòng)糾錯(cuò)。我們主要處理 2-bit 錯(cuò)誤,由于 2-bit 錯(cuò)誤僅能檢錯(cuò),無法糾錯(cuò),所以發(fā)生了這個(gè)錯(cuò)誤,就意味著讀取的數(shù)據(jù)不可靠了。對于 1/2 bit錯(cuò)誤,XECC 均提供了中斷響應(yīng)(XECC_xxModule_INT_IRQn / XECC_xxModule_FATAL_INT_IRQn)。
對于 32bits 數(shù)據(jù)而言,XECC 是可以糾正其中發(fā)生的 8bits 錯(cuò)誤的,但前提是按序分割開的每 4bits 數(shù)據(jù)位僅能有 1bit 錯(cuò)誤,如果這 4bits 數(shù)據(jù)位里有多 bit 錯(cuò)誤,我們依然想校正的話,需要借助 Data Swap 功能,這里不再單獨(dú)展開,可查看 RM 了解細(xì)節(jié)。
二、開啟XECC的步驟
2.1 激活XECC特性
芯片出廠,默認(rèn)是沒有激活 XECC 特性的,如果需要開啟 XECC,需要燒寫 efuse,fusemap 中 0x840[3] 對應(yīng)的是 XECC_ENABLE bit,我們需要將這個(gè) bit 燒寫成 1,才能激活 XECC 特性。
2.2 初始化存儲(chǔ)器接口外設(shè)
在初始化 XECC 模塊之前一般先初始化存儲(chǔ)器接口外設(shè),這里我們先初始化 FlexSPI1,因?yàn)闇y試板卡 MIMXRT1170-EVK 上默認(rèn)是 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驅(qū)動(dòng)初始化XECC
然后可以直接利用 SDK 里的 fsl_xecc 驅(qū)動(dòng)對 XECC 模塊進(jìn)行初始化,代碼非常簡單,如下示例代碼就是初始化 XECC_FLEXSPI1,使能 0x30000000 - 0x30000FFF 區(qū)域的讀寫 ECC 功能:
#include "fsl_xecc.h"
void init_flexspi_xecc(void)
{
xecc_config_t config;
XECC_GetDefaultConfig(&config);
// 同時(shí)使能讀寫 XECC
config.enableXECC = true;
config.enableWriteECC = true;
config.enableReadECC = true;
// 設(shè)置 ECC 區(qū)域(0x30000000 - 0x30000FFF)
config.Region0BaseAddress = FlexSPI1_AMBA_BASE;
config.Region0EndAddress = FlexSPI1_AMBA_BASE + 0x1000;
// 初始化 XECC 模塊
XECC_Init(XECC_FLEXSPI1, &config);
}
2.4 AHB方式讀寫ECC目標(biāo)區(qū)域
最后就是利用 《其實(shí)i.MXRT下改造FlexSPI driver同樣支持AHB方式去寫入NOR Flash》 一文 3.3 節(jié)里的 flexspi_nor_flash_program() 函數(shù)來對 Flash 做 AHB 方式的寫入,以激活 XECC 工作。為了驗(yàn)證 XECC 是否工作正常,可以分別用 IPG 和 AHB 方式讀回寫入的區(qū)域看最終結(jié)果。
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 區(qū)域(1個(gè)Sector)
flexspi_nor_flash_erase_sector(FLEXSPI1, 0x0);
for (uint32_t i = 0; i < 0xFFU; i++)
{
s_nor_program_buffer[i] = i;
}
// AHB 方式寫 256 字節(jié)數(shù)據(jù)進(jìn) Flash 0x30000000 開始的地址
flexspi_nor_flash_program(FLEXSPI1, 0x30000000, s_nor_program_buffer, 256);
DCACHE_CleanInvalidateByRange(0x30000000, 0x1000);
// IPG 方式從 Flash 0x30000000 開始的地址讀出 256 字節(jié)數(shù)據(jù)
flexspi_nor_flash_read(FLEXSPI1, 0x0, (void *)s_nor_ipg_read_buffer, 256);
// AHB 方式從 Flash 0x30000000 開始的地址讀出 256 字節(jié)數(shù)據(jù)
memcpy((void *)s_nor_ahb_read_buffer, (void *)0x30000000, 256);
}
至此,簡析i.MXRT1170 XECC功能特點(diǎn)及其保護(hù)串行NOR Flash和SDRAM之道痞子衡便介紹完畢了,掌聲在哪里~~~
歡迎訂閱
文章會(huì)同時(shí)發(fā)布到我的 博客園主頁、CSDN主頁、知乎主頁、微信公眾號 平臺(tái)上。
微信搜索"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機(jī)上第一時(shí)間看了哦。

最后歡迎關(guān)注痞子衡個(gè)人微信公眾號【痞子衡嵌入式】,一個(gè)專注嵌入式技術(shù)的公眾號,跟著痞子衡一起玩轉(zhuǎn)嵌入式。
衡杰(痞子衡),目前就職于恩智浦(NXP)半導(dǎo)體MCU系統(tǒng)應(yīng)用部門,擔(dān)任高級嵌入式系統(tǒng)應(yīng)用工程師。
專欄內(nèi)所有文章的轉(zhuǎn)載請注明出處:http://www.rzrgm.cn/henjay724/
與痞子衡進(jìn)一步交流或咨詢業(yè)務(wù)合作請發(fā)郵件至 hengjie1989@foxmail.com
可以關(guān)注痞子衡的Github主頁 https://github.com/JayHeng,有很多好玩的嵌入式項(xiàng)目。
關(guān)于專欄文章有任何疑問請直接在博客下面留言,痞子衡會(huì)及時(shí)回復(fù)免費(fèi)(劃重點(diǎn))答疑。
痞子衡郵箱已被私信擠爆,技術(shù)問題不推薦私信,堅(jiān)持私信請先掃碼付款(5元起步)再發(fā)。
浙公網(wǎng)安備 33010602011771號