|

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是i.MXRT1170 XECC开启及Data Swap功能对于外部RAM的访问性能影响。
文接上篇 《i.MXRT1170 XECC功能特点及其保护串行NOR Flash和SDRAM之道》,这篇文章里痞子衡给大家介绍了 XECC 原理及在其使能下操作 NOR Flash 步骤(尤其涉及对 Flash 的 AHB 方式写),但文章里并没有涉及性能方面的评估。我们知道 RT1170 上内部 FlexRAM ECC 模块使能后对 TCM 访问性能几乎无影响,那么 XECC 使能后对于挂在 FlexSPI/Semc 接口上的外部 PSRAM/SDRAM 访问性能是否有影响呢?今天我们就来聊聊这个话题:
Note:本文以 MIMXRT1170-EVKB (Rev.B) 板卡上挂在 SEMC 接口的 16bit SDRAM - W9825G6KH-5I 读写测试为例,PSRAM 测试过程类似。一、XECC功能测试测试 XECC 对于 SDRAM 访问保护功能我们可以直接使用如下两个官方例程,其中 xecc_single_error 示例了单 bit 纠错(4bits数据单元而言),xecc_multi_error 示例了双 bit 报错(4bits数据单元而言),这两个例程都借助了 XECC 本身的 Error injection 特性人为制造数据 bit 错误来做测试(可以指定 32bits 数据块中任意位置和个数的 bit 出错)。
\SDK_2_16_000_MIMXRT1170-EVKB\boards\evkbmimxrt1170\driver_examplesìc\semcìc_single_error\cm7
\SDK_2_16_000_MIMXRT1170-EVKB\boards\evkbmimxrt1170\driver_examplesìc\semcìc_multi_error\cm7
痞子衡简单整合了上述两个例程代码到一个工程里,这样可以同时测单/双/多 bit 错误情况,其中主要代码摘录如下。此外为了方便观察不同的错误注入导致的结果,我们将待写入值 sdram_writeBuffer[0] 设为 0x00000000,这样发生无法纠错情况时读回的数据 sdram_readBuffer[0] 就应该等于错误注入值 errorData。
#include "fsl_xecc.h"
volatile uint32_t sdram_writeBuffer[0x1000];
volatile uint32_t sdram_readBuffer[0x1000];
int main(void)
{
// 系统与 SDRAM 初始化代码省略...
// 初始化 XECC_SEMC 模块,设置 SDRAM [0x80000000, 0x8007FFFF] 为 ECC 使能区域,其中前 256KB 是用户数据访问空间
XECC_Deinit(XECC_SEMC);
xecc_config_t config;
XECC_GetDefaultConfig(&config);
config.enableXECC = true;
config.enableWriteECC = true;
config.enableReadECC = true;
//config.enableSwap = true;
config.Region0BaseAddress = 0x80000000U;
config.Region0EndAddress = 0x80080000U; // 256KB * 2
XECC_Init(XECC_SEMC, &config);
(void)EnableIRQ(XECC_SEMC_INT_IRQn);
(void)EnableIRQ(XECC_SEMC_FATAL_INT_IRQn);
SCB->SHCSR |= SCB_SHCSR_BUSFAULTENA_Msk;
XECC_EnableInterrupts(XECC_SEMC, kXECC_AllInterruptsEnable);
// 对 32bits 数据块进行错误注入(这里设定得是错误 bit 位置)
uint32_t errorData = 0x00000001;
XECC_ErrorInjection(XECC_SEMC, errorData, 0);
sdram_writeBuffer[0] = 0x00000000U;
// AHB 方式写数据进 SDRAM
*(uint32_t *)0x80000000U = sdram_writeBuffer[0];
// 关闭 DCache 代码省略...
// AHB 方式从 SDRAM 读回数据
sdram_readBuffer[0] = *(uint32_t *)0x80000000U;
while ((!s_xecc_single_error) && (!s_xecc_multi_error))
{
}
// 代码省略...
}
在放测试结果之前,我们先回顾一下 XECC 错误检测机制。在默认不开启 Data Swap 特性情况下,对于 32bits 数据块,XECC 可以纠正其中发生的 8bits 错误,但前提是按序分割开的每 4bits 数据单元仅能有 1bit 错误(即分散 bit 错误)。如果这 4bits 数据单元里有 2bit 错误,那 XECC 会检测出位置并报告;如果有 3/4bit 错误,那已经超出 XECC 处理能力,结果不可预期了。
但如果现场实际环境发生连续 bit 错误概率高于分散 bit 错误,这时候可以考虑开启 XECC Data Swap 功能,这时候 XECC 处理能力变成可以纠正连续 bit 错误,但对于分散 bit 错误就无法处理了(如下图所示,实际上 Swap 是将图左边 32bits 原数据打乱再重新组合成图右边 32bits 新数据)。 |
|