痞子衡嵌入式:简析i.MXRT1170 XECC敞开及Data Swap功用关于外部RAM的拜访功能影响
咱们好,我是痞子衡,是正派搞技能的痞子。今日痞子衡给咱们共享的是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\xecc\semc\xecc_single_error\cm7
\SDK_2_16_000_MIMXRT1170-EVKB\boards\evkbmimxrt1170\driver_examples\xecc\semc\xecc_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 新数据)。
依据上面的理论,咱们现在再来看测验成果,那就十分合理了,有些状况下敞开 Data Swap 增强了纠检错才能,有些状况下敞开 Data Swap 却削弱了本来的纠检错才能。(留意,Error injection 设定的 errorData 是针对 swap 之后的数据 bit 序而言)
- Note:单 32bits 数据块写读测验时,改动 L1 D-Cache 操作代码方位(前移到 main 开端),会影响测验成果,这儿留一个伏笔,今后具体分析。
config.enableSwap | errorData | sdram_writeBuffer[0] | sdram_readBuffer[0] | 测验成果 |
---|---|---|---|---|
false/true | 0x00000001 | 0x00000000 | 0x00000000 | bit0过错被纠正 |
false/true | 0x11111111 | 0x00000000 | 0x00000000 | bit0,4,8,12,16,20,24,28过错被纠正 |
false | 0x08040201 | 0x00000000 | 0x00000000 | bit0,9,18,27过错被纠正 |
ture | 0x08040201 | 0x00000000 | 0x00000000 | (原功用增强)bit0,2,17,19过错被纠正 |
false | 0x02040801 | 0x00000000 | 0x00000000 | bit0,11,18,25过错被纠正 |
ture | 0x02040801 | 0x00000000 | 0x00000000 | (原功用增强)bit0,1,2,3过错被纠正 |
false | 0x00000003 | 0x00000000 | 0x00000003 | bit0,1过错被检测 |
true | 0x00000003 | 0x00000000 | 0x00000201 | (原功用削弱)bit0,9过错被检测 |
false | 0x00000007 | 0x00000000 | 0x00000007 | 触发单bit纠错中止,犯错bit0,1,2方位辨认禁绝 |
true | 0x00000007 | 0x00000000 | 0x00040201 | 触发单bit纠错中止,(原功用削弱)犯错bit0,9,18方位辨认禁绝 |
false | 0x0000000F | 0x00000000 | 0x0000000F | 触发双bit检错中止,犯错bit0,1,2,3方位辨认禁绝 |
true | 0x0000000F | 0x00000000 | 0x08040201 | 触发双bit检错中止,(原功用削弱)犯错bit0,9,18,27方位辨认禁绝 |
二、XECC功用测验
现在咱们简略测验一下内核对 SDRAM 读写功用是否受 XECC 影响,就在 \semc\xecc_multi_error 例程根底之上,规划了如下代码,便于测验不同的数据块巨细(比方 64KB,128KB,256KB),并且能够一次性比照没有 XECC 维护,加 XECC 维护,以及敞开 XECC Data Swap 三种状况(半途需求 Deinit 再 Init XECC 模块)。
uint32_t readErrorCnt = 0;
uint32_t get_sdram_rw_block_time(uint32_t start, uint32_t size)
{
uint64_t tickStart = life_timer_clock();
readErrorCnt = 0;
for (uint32_t idx = 0; idx < size; idx += 4)
{
*((uint32_t*)(start + idx)) = idx;
}
for (uint32_t idx = 0; idx < size; idx += 4)
{
uint32_t temp = *((uint32_t*)(start + idx));
if (temp != idx)
{
readErrorCnt++;
}
}
uint64_t tickEnd = life_timer_clock();
return ((tickEnd - tickStart) / (CLOCK_GetRootClockFreq(kCLOCK_Root_Bus) / 1000000));
}
void test_xecc_sdram_perf(uint32_t size)
{
xecc_config_t config;
XECC_GetDefaultConfig(&config);
config.enableXECC = true;
config.enableWriteECC = true;
config.enableReadECC = true;
config.Region0BaseAddress = 0x80040000;
config.Region0EndAddress = 0x800C0000;
XECC_Deinit(EXAMPLE_XECC);
// 写读 SDRAM 非 XECC 维护区域
uint32_t normalTimeInUs = get_sdram_rw_block_time(0x80000000, size);
// 写读 SDRAM XECC 维护区域(不使能 Data Swap)
config.enableSwap = false;
XECC_Init(XECC_SEMC, &config);
uint32_t xeccNoSwapTimeInUs = get_sdram_rw_block_time(0x80040000, size);
// 写读 SDRAM XECC 维护区域(使能 Data Swap)
XECC_Deinit(XECC_SEMC);
config.enableSwap = true;
XECC_Init(XECC_SEMC, &config);
uint32_t xeccSwapTimeInUs = get_sdram_rw_block_time(0x80040000, size);
PRINTF("---------------------------------------\r\n");
PRINTF("Write/Read/Compare data size: %d\r\n", size);
PRINTF("Write/Read/Compare time in SDRAM region XECC disable : %d us\r\n", normalTimeInUs);
PRINTF("Write/Read/Compare time in SDRAM region XECC enable without data swap : %d us\r\n", xeccNoSwapTimeInUs);
PRINTF("Write/Read/Compare time in SDRAM region XECC enable with data swap : %d us\r\n", xeccSwapTimeInUs);
}
get_sdram_rw_block_time() 函数里实践上也计算了数据犯错状况,可用于辅佐判别写读是否正常,在恩智浦开发板测验环境下应该无 ECC 过错,所以这儿成果就省略不表了。
咱们现在来看 800MHz 内核主频下对 200MHz SDRAM 拜访功用状况(代码跑在 ITCM 上),为了成果牢靠,本次测验内核频率没有设到最高。依据代码打印成果,咱们能得到如下定论:
- 定论1:在无 XECC 维护状况下,敞开 D-Cache 能将 SDRAM 读写全体拜访速度提升到 4 倍。
- 定论2:XECC 使能状况下,是否敞开 Data Swap 功用简直不带来功用改变(在 XECC 外设里 Swap 操作一拍时钟就能完结,时延能够疏忽)。
- 定论3:XECC 使能状况下,会下降 SDRAM 读写全体拜访功用,降幅在 28% (敞开 D-Cache) 或 11%(不敞开 D-Cache)。
- 定论4:XECC 使能状况下,关于读写拜访相同巨细数据块,是否敞开 D-Cache,不影响 XECC 校验处理的时刻(即 D-Cache 不加快 XECC)。
至此,i.MXRT1170 XECC敞开及Data Swap功用关于外部RAM的拜访功用影响痞子衡便介绍结束了,掌声在哪里~~~
欢迎订阅
文章会一起发布到我的 博客园主页、CSDN主页、知乎主页、微信大众号 平台上。
微信查找"痞子衡嵌入式"或许扫描下面二维码,就能够在手机上第一时刻看了哦。