百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

ECC给i.MXRT1170 FlexRAM带来了哪些变化?

myzbx 2025-04-08 16:51 8 浏览

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是恩智浦i.MXRT1170上Cortex-M7内核的 FlexRAMECC功能。

ECC 是“Error Correcting Code”的简写,ECC 能够实现错误检查和纠正,含有 ECC 功能的内存一般称为 ECC 内存,使用了 ECC 内存的系统在稳定性和可靠性上得到很大提升。相比前几代不带 ECC 的 i.MXRT10xx 型号,新一代 i.MXRT1170 在 ECC 上做了全面武装,从 eFuse 到 FlexRAM,从 OCRAM 到外部存储空间全都加上了 ECC 功能。如下表所示,不同类型的存储由不同的 ECC 控制器来守护:

今天痞子衡就先给大家简单介绍一下 i.MXRT1170 上 Cortex-M7 内核下的 FlexRAM ECC功能:

一、FlexRAM ECC 功能简介

1.1 FlexRAM v2 特点

i.MXRT1170 上的 FlexRAM 模块是 v2 版本,相比 i.MXRT10xx 上的 FlexRAM v1 版本,主要就是增加了 ECC 功能。关于 FlexRAM v1 基本功能,建议你先阅读痞子衡之前写过的文章 《恩智浦 i.MX RT1xxx 系列 MCU 外设那些事(2)- 百变星君 FlexRAM》,痞子衡今天主要聊 v2 新增的功能。

我们知道 i.MXRT1170 是 Cortex-M7 和 Cortex-M4 双核架构,我们看下它的 CM7 内核系统框图,FlexRAM 本质上是为 CM7 内核设计的,因为其管理的 TCM 空间仅能由 CM7 访问的,不过如果将 FlexRAM 也分配出一部分给 OCRAM,这部分 OCRAM(即文章开头 memory map 表里从 0x20360000 开始的空间)其实 CM4 也能正常访问。

在框图中你还会发现,FlexRAM 中物理 SRAM 总大小是 640KB,不是我们知道的可自由配置的 512KB,这是因为需要额外 128KB RAM 来存放 ECC 校验值,关于这个细节在下一节里展开聊。

1.2 关于 ECC 设计细节

关于 ECC,大家最早接触的应该是 ONFI Raw NAND 上的应用,NAND Flash 因为其物理特性的原因(允许坏块的存在),必须要包含 ECC 功能,痞子衡写过的一篇文章 《并行 NAND 接口标准(ONFI)及 SLC Raw NAND 简介》, 里面的 2.6 Raw NAND 坏块与 ECC 简单介绍了 ECC 在 Raw NAND 上的应用。

在 Raw NAND 上,通常是每写入 512bytes 数据计算出一个 ECC 校验值(4bytes),读取时也是读完全部 512bytes 数据后进行 ECC 校验,ECC 校验能力一般用 (n+1) bit 检错,n bit 纠错 来表达,即这 512bytes 数据里如果发生 n+1 bit 及以下的错误时能够检查出来,如果发生 n bit 及以下的错误时,能够自动纠正。比如典型的 Micron MT29F4G08 就是 5-bit 检错,4-bit 纠错。

但是 FlexRAM 本质上是 RAM,跟 Flash(尤其是 NAND)读写机制不一样,RAM 是随机地址按 Byte 读写,NAND 是以 Page 为单位顺序读写,所以 NAND 上 ECC 实现机制不适用于 RAM。那么 FlexRAM 到底采用的是什么样的 ECC 设计呢?

1.2.1 ECC 检验能力

好了,不卖关子了,公布答案。FlexRAM 中每 4ytes(针对 DTCM)或 8bytes(针对 ITCM/OCRAM)数据就会计算出一个 ECC 校验值(7/8bits),ECC 校验值都被放在了 ECC RAM里。因为校验数据块分割得很小,所以此时不需要提供多 bit 纠错能力,FlexRAM 采用的是最经典的 Single-bit Error Correction and Dual-bit Error Detection(SEC-DED,汉明校验码)。关于 SEC-DED,你可以去 Linux 内核里看其在 NAND 上应用的源码实现 nand_ecc.c,写得非常经典。

存储类型ECC 校验数据块大小ECC 校验值长度ECC 校验能力
Raw NAND512 bytes4 bytes5-bit 检错,4-bit 纠错
FlexRAM4/8 bytes7/8 bits2-bit 检错,1-bit 纠错

1.2.2 ECC RAM 分配

128KB ECC RAM 并不是只能用来存储 ECC 校验值的,其也可以当做普通 OCRAM 来使用,ECC RAM 具体功能是根据当前 FlexRAM 分配以及 ECC 是否开启而定的。eFuse 里默认的 512KB FlexRAM 配置是 256KB ITCM, 256KB DTCM, 没有 OCRAM。

在默认 FlexRAM 配置情况下,如果 TCM ECC 没有开启,那么 128KB ECC RAM 全部都是普通 OCRAM,其地址空间如下表所示:

在默认 FlexRAM 配置情况下,如果 TCM ECC 已经开启,那么 128KB ECC RAM 全部都用来存储 ECC 校验值,这个区域仅能由 FlexRAM 模块内部访问,用户无法访问这 128KB 区域(不在 memory map 空间里),毕竟 ECC 校验值不能被随便改。

如果我们在 eFuse 或者 IOMUXC_GPR 寄存器里将 FlexRAM 配置改掉,分配出一部分给 OCRAM(比如 256KB TCM, 256KB OCRAM),那这 128KB ECC RAM 功能分配就稍微复杂一些了。最简单的情况是 TCM 和 OCRAM ECC 都没有开启,那么这 128KB ECC RAM 还是普通 OCRAM,map 地址是紧跟在 FlexRAM OCRAM 后面的,如下表所示:

如果 TCM 和 OCRAM ECC 都开启了,那么这 128KB ECC RAM 就还是全部用来存储 ECC 校验值了,用户无法访问。

如果 OCRAM ECC 没有开启,不管 TCM ECC 是否开启,这 128KB ECC RAM 中本用于存储 OCRAM ECC 的区域都将被划分为普通 OCRAM,另一部分用于存储 TCM ECC 的区域(无论是否真的要存储 ECC 校验值)用户则无法访问。区域划分比例与 OCRAM 在总 FlexRAM 大小中占比保持一致,比如 512KB FlexRAM(一共 16 个 bank,每个 bank 32KB)划分出了 256KB OCRAM,那么 128KB ECC RAM(也是 16 个 bank,每个 bank 8KB)则划出了 64KB 作为普通 OCRAM,如下表所示:

1.2.3 ECC 错误触发处理

ECC 错误分两种,分别是 1-bit 错误和 2-bit 错误。从软件层面来看,1-bit 错误可以不用管,FlexRAM 模块会自动纠错。我们主要处理 2-bit 错误,由于 2-bit 错误仅能检错,无法纠错,所以发生了这个错误,就意味着读取的数据不可靠了,需要丢弃并重新写一次(丢弃之前可以再 retry read 一次看是否还是报错)。

关于 ECC 错误处理,可根据如下 FlexRAM 寄存器来操作,首先当然是在 INT_SIG_EN 寄存器中使能 multi-bit ECC Error,当有 2-bit 错误发生时,系统会触发 FLEXRAM_IRQn(中断号是 50),在中断处理程序里找到相应的 ECC_MULTI_ERROR_ADDR,对这个地址重新写一次初始化数据(按 ECC 校验块长度一次性写入),最后清除 INT_STATUS 寄存器里的相应状态位。

需要注意的是,上述处理流程仅对 FlexRAM 中存放的是普通业务数据且发生 ECC 错误时有效,如果 ECC 错误发生在关键代码段或变量段中,这个处理是不适用的,因为这种 ECC 错误可能会造成程序崩溃。

OffsetRegister
10hInterrupt Status Register (INT_STATUS)
14hInterrupt Status Enable Register (INT_STAT_EN)
18hInterrupt Enable Register (INT_SIG_EN)
30hOCRAM multi-bit ECC Error Address Register (OCRAM_ECC_MULTI_ERROR_ADDR)
50hITCM multi-bit ECC Error Address Register (ITCM_ECC_MULTI_ERROR_ADDR)
6ChD0TCM multi-bit ECC Error Address Register (D0TCM_ECC_MULTI_ERROR_ADDR)
84hD1TCM multi-bit ECC Error Address Register (D1TCM_ECC_MULTI_ERROR_ADDR)

二、开启 FlexRAM ECC 的步骤

FlexRAM ECC 需要按照标准步骤去开启,需要特别注意的是开启 ECC 操作的代码不能放在待开启 ECC 的 FlexRAM 空间里(比如 TCM ECC 要开启,那么开启 ECC 操作的代码不能使用任何 TCM 空间),因此不管是 XIP 还是 Non-XIP 应用程序,最好是用一个二级 loader(这个 loader 可以链接在固定 OCRAM1/2 空间里,或者 XIP)来完成 ECC 开启操作然后再加载应用程序执行。痞子衡给了如下示例 loader 代码工程,代码里主要有四个步骤:

参考代码:
https://github.com/JayHeng/cortex-m-apps/blob/master/apps/coremark_imxrt1176/loader/loader.c

2.1 使能 TCM 的 RMW(可选)

如果需要开启 TCM ECC,那么首先需要在 CM7 内核寄存器里开启 TCM RMW(Read-Modify-Write)功能,这是 ARM 的规定,可在 Cortex-M7 Technical RM 手册里找到相关信息如下。手册里明确写了 RMW 位同时也控制了外部逻辑(即 MCU 厂商的设计)来支持 ECC 功能。

操作函数代码如下:

void enable_cm7_tcm_rmw(void)
{
    SCB->ITCMCR |= SCB_ITCMCR_RMW_Msk;
    SCB->DTCMCR |= SCB_DTCMCR_RMW_Msk;
}

2.2 使能 FlexRAM 的 ECC

现在需要开启 FlexRAM ECC,在 i.MXRT1170 参考手册里的 FlexRAM 章节可以找到 FLEXRAM_CTRL 寄存器定义,其中 bit5 和 bit4 就是用来分别控制 TCM 和 OCRAM 的 ECC 开关。

操作函数代码如下:

void enable_flexram_tcm_ecc(void)
{
    *(uint32_t *)(FLEXRAM_BASE + 0x108) |= (1u << 5);
}

void enable_flexram_ocram_ecc(void)
{
    *(uint32_t *)(FLEXRAM_BASE + 0x108) |= (1u << 4);
}

2.3 初始化 FlexRAM 的 ECC 值

FlexRAM ECC 开启了之后,此时还不能随机访问 FlexRAM,因为初始 ECC 校验值还没有填充,如果这时候去读 FlexRAM 会产生错误。我们首先需要将会用到的 FlexRAM 空间全部初始化一遍(就是以 ECC 校验数据块大小对齐方式从头到尾写入一遍,写入内容不限,正常用全 0)。

操作函数代码如下:

#define ITCM_START   0x00000000
#define ITCM_SIZE    (256*1024U)  // 只是示例长度,根据实际情况修改
#define DTCM_START   0x20000000
#define DTCM_SIZE    (256*1024U)  // 只是示例长度,根据实际情况修改
#define OCRAM_START  0x20360000
#define OCRAM_SIZE   (256*1024U)  // 只是示例长度,根据实际情况修改

void init_flexram_itcm_ecc(void)
{
    for (uint32_t i = 0; i < ITCM_SIZE; i += sizeof(uint64_t))
    {
        *(uint64_t *)(ITCM_START + i) = 0;
    }
}

void init_flexram_dtcm_ecc(void)
{
    for (uint32_t i = 0; i < DTCM_SIZE; i += sizeof(uint32_t))
    {
        *(uint32_t *)(DTCM_START + i) = 0;
    }
}

void init_flexram_ocram_ecc(void)
{
    for (uint32_t i = 0; i < OCRAM_SIZE; i += sizeof(uint64_t))
    {
        *(uint64_t *)(OCRAM_START + i) = 0;
    }
}

2.4 加载应用程序执行

当 FlexRAM 初始 ECC 校验值已经被填充之后,此时便可以正常随机读写 FlexRAM 了。如果此时加载的是一个在 ITCM 里执行并且 data 段在 DTCM 里的应用程序,可以参考痞子衡前面给出的示例 loader 工程。

这是 loader 工程完整主函数代码,其中 memcpy 那一句代码里的 app_code 是应用程序 binary 数组(用 Python 脚本将应用程序工程生成的 .bin 文件转换成 C 语言数组放到 loader 工程源文件里)。

#define APP_START 0U

int main(void)
{
    enable_cm7_tcm_ecc;
    enable_flexram_tcm_ecc;
    init_flexram_itcm_ecc;
    init_flexram_dtcm_ecc;

    // Copy image to RAM.
    memcpy((void *)APP_START, app_code, APP_LEN);
    
    uint32_t appStack = *(uint32_t *)(APP_START);
    uint32_t appEntry = *(uint32_t *)(APP_START + 4);

    // Turn off interrupts.
    __disable_irq;

    // Set the VTOR to default.
    SCB->VTOR = APP_START;

    // Memory barriers for good measure.
    __ISB;
    __DSB;

    // Set main stack pointer and process stack pointer.
    __set_MSP(appStack);
    __set_PSP(appStack);

    // Jump to app entry point, does not return.
    void (*entry)(void) = (void (*)(void))appEntry;
    entry;
}

三、ECC 对内存访问性能的影响

FlexRAM 开了 ECC 后,访问性能会有一定降低,毕竟数据访问中插入了额外的 ECC 校验工作,不过这个影响非常小,因为一次 ECC 校验仅增加 1-2 个机器 cycle。下面是 FlexRAM 分配出的不同存储类型的基本情况,其中 OCRAM 可以被 L1 Cache 加速,所以从应用程序角度开 ECC 对其访问性能影响就更小了,我们主要讨论 ECC 对 TCM 性能的影响。

FlexRAM 分配类型ECC 校验数据块大小总线类型访问速度L1 Cache 加速
ITCM8 bytesITCM_ITF 64-bits与 CM7 同频
DTCM4 bytesDTCM_ITF 2x32-bit与 CM7 同频
OCRAM8 bytesAXI64与 CM7 频率的 1/4

为了简化测试,痞子衡就用经典的 benchmark 程序(Coremark 和 Dhrystone)来测试 ECC 对 TCM 的影响,测试工程如下:

Coremark 工程:
https://github.com/JayHeng/cortex-m-apps/tree/master/apps/coremark_imxrt1176/loader Dhrystone 工程:
https://github.com/JayHeng/cortex-m-apps/tree/master/apps/dhrystone_imxrt1176/loader

需要特别提醒的是,我们知道 i.MXRT1170 CM7 内核最高可以配置到 1GHz,但是开了 TCM ECC 后,为了保证访问可靠性,此时 CM7 内核最好是工作在 800MHz,下面的 benchmark 结果也是在 800MHz 主频下得到的:

Benchmark 类型TCM ECC 开关Benchmark 结果
coremark关闭Total ticks : 2023600
Total time (secs): 20.236000
Iterations/Sec : 3953.350465
Iterations : 80000
CoreMark 1.0 : 3953.350465
coremark开启Total ticks : 2023657
Total time (secs): 20.236570
Iterations/Sec : 3953.239111
Iterations : 80000
CoreMark 1.0 : 3953.239111
dhrystone关闭Dhrystones per Second: 3622138.51
DMIPS: 2061.5472
DMIPS/MHz: 2.0698
dhrystone开启Dhrystones per Second: 3621977.04
DMIPS: 2061.4553
DMIPS/MHz: 2.0697

从 benchmark 结果来看,ECC 是否开启对性能影响特别小,可以忽略,当然 benchmark 测试并不是特别精确地反映了性能影响,底下有空痞子衡会再专门用 memcpy 函数来测试性能影响。

至此,恩智浦 i.MXRT1170 上 Cortex-M7 内核的 FlexRAM ECC 功能痞子衡便介绍完毕了,掌声在哪里~~~

相关推荐

Django零基础速成指南:快速打造带用户系统的博客平台

#python##服务器##API##编程##学习#不是所有教程都值得你花时间!这篇实战指南将用5分钟带你解锁Django核心技能,手把手教你从零搭建一个具备用户注册登录、文章管理功能的完整...

iOS 17.0 Bootstrap 1.2.9 半越狱来啦!更新两点

这款Bootstrap半越狱工具终于更新,离上一次更新已相隔很久,现在推出1.2.9版本,主要为内置两点功能进行更新,也是提升半越狱的稳定性。如果你正在使用这款半越狱工具的,建议你更新。注意!...

iOS 16.x Bootstrap 1.2.3 发布,支持运行清理工具

本文主要讲Bootstrap半越狱工具更新相关内容。如果你是iOS16.0至16.6.1和17.0系统的,想体验半越狱的果粉,请继续往下看。--知识点科普--Bootstrap...

SpringBoot整合工作流引擎Acticiti系统,适用于ERP、OA系统

今日推荐:SpringBoot整合工作流引擎Acticiti的源码推荐理由:1、SpringBoot整合工作流引擎Acticiti系统2、实现了三级权限结构3、持久层使用了mybatis框架4、流程包...

SpringCloud自定义Bootstrap配置指南

在SpringCloud中自定义Bootstrap配置需要以下步骤,以确保在应用启动的早期阶段加载自定义配置:1.添加依赖(针对新版本SpringCloud)从SpringCloud2020...

Python使用Dash开发网页应用(三)(python网页开发教程)

PlotlyDash开发Web应用示例一个好的网页设计通常都需要编写css甚至js来定制前端内容,例如非常流行的bootstrap框架。我们既然想使用Dash来搭建web应用,很大的一个原因是不熟悉...

Oxygen XML Editor 27.1 中的新功能

OxygenXMLEditor27.1版是面向内容作者、开发者、合作者和出版商的行业领先工具包的增量版本。在27.1版本中,AIPositronAssistant得到了增强,包括用于...

【LLM-多模态】Mini-Gemini:挖掘多模态视觉语言模型的潜力

一、结论写在前面论文提出了Mini-Gemini,一个精简而强大的多模态VLM框架。Mini-Gemini的本质在于通过战略性框架设计、丰富的数据质量和扩展的功能范围,发掘VLM的潜在能力。其核心是补...

谐云课堂 | 一文详解分布式改造理论与实战

01微服务与分布式什么是分布式?首先,我们对上图提到的部分关键词进行讲解。单体,是指一个进程完成全部的后端处理;水平拆分,是同一个后端多环境部署,他们都处理相同的内容,使用反向代理来均衡负载,这种也叫...

基于Abaqus的手动挡换挡机构可靠性仿真

手动挡,也称手动变速器,英文全称为Manualtransmission,简称MT,即用手拨动换挡操纵总成才能改变变速器内的齿轮啮合位置,改变传动比,从而达到变速的目的。家用轿车主要采用软轴连接的换挡...

【pytorch】目标检测:彻底搞懂YOLOv5详解

YOLOv5是GlennJocher等人研发,它是Ultralytics公司的开源项目。YOLOv5根据参数量分为了n、s、m、l、x五种类型,其参数量依次上升,当然了其效果也是越来越好。从2020...

超实用!50个非常实用的PS快捷键命令大全分享

今天,给大家介绍50个非常实用的快捷键命令大全,大家伙都是设计师,关于软件使用那是越快越好啊。一、常用的热键组合1、图层混合模式快捷键:正常(Shift+Option+N),正片叠底(Shif...

Pohtoshop中深藏不露的小技巧(科目一考试技巧记忆口诀看完必过)

邢帅教育ps教程为大家总结了一些Pohtoshop中深藏不露的小技巧,可以帮助到大家在设计时减少不必要的麻烦,提高工作效率哦~~~1.设置网格线保持像素完美不在1:1分辨率下也能保持像素完美,可以...

Ganglia监控安装总结(监控安装工作总结)

一、ganglia简介:Ganglia是一个跨平台可扩展的,高性能计算系统下的分布式监控系统,如集群和网格。它是基于分层设计,它使用广泛的技术,如XML数据代表,便携数据传输,RRDtool用于数据...

谁说Adobe XD做不出好看的设计?那是你没搞懂这些功能

AdobeXD的美化栏具有将设计视图美化的功能,它能使界面设计和原型设计更漂亮、更吸引眼球。美化栏的7个功能包括竖线布局设计、横线布局设计、重复网格、图形大小和位置设置、响应式调整大小、文字美化以及...