zoukankan      html  css  js  c++  java
  • 痞子衡嵌入式:简析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主页知乎主页微信公众号 平台上。

    微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

      最后欢迎关注痞子衡个人微信公众号【痞子衡嵌入式】,一个专注嵌入式技术的公众号,跟着痞子衡一起玩转嵌入式。

    痞子衡嵌入式-微信二维码 痞子衡嵌入式-微信收款二维码 痞子衡嵌入式-支付宝收款二维码

      衡杰(痞子衡),目前就职于恩智浦MCU系统部门,担任嵌入式系统应用工程师。

      专栏内所有文章的转载请注明出处:http://www.cnblogs.com/henjay724/

      与痞子衡进一步交流或咨询业务合作请发邮件至 hengjie1989@foxmail.com

      可以关注痞子衡的Github主页 https://github.com/JayHeng,有很多好玩的嵌入式项目。

      关于专栏文章有任何疑问请直接在博客下面留言,痞子衡会及时回复免费(划重点)答疑。

      痞子衡邮箱已被私信挤爆,技术问题不推荐私信,坚持私信请先扫码付款(5元起步)再发。


  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 贪吃的大嘴
    Java实现 蓝桥杯VIP 算法提高 贪吃的大嘴
    Java实现 蓝桥杯VIP 算法提高 贪吃的大嘴
    Java实现 蓝桥杯VIP 算法提高 贪吃的大嘴
    Java实现 蓝桥杯VIP 算法提高 士兵排队问题
    Java实现 蓝桥杯VIP 算法提高 士兵排队问题
    Java实现 蓝桥杯VIP 算法提高 士兵排队问题
    Java实现 蓝桥杯VIP 算法提高 士兵排队问题
    Java实现 蓝桥杯VIP 算法提高 数字黑洞
    Minifilter微过滤框架:框架介绍以及驱动层和应用层的通讯
  • 原文地址:https://www.cnblogs.com/henjay724/p/15204125.html
Copyright © 2011-2022 走看看