跳到主要内容

Rockchip Developer Guide HAL DDR ECC

:::info 文档信息

文档标识:RK-KF-YF-169 · 发布版本:V1.0.0 · 发布日期:2021-03-29 · 页数:7 · 语言:英文

原始文档:Rockchip_Developer_Guide_HAL_DDR_ECC_CN.pdf

:::

章节大纲​

  • Rockchip Developer Guide HAL DDR ECC(P1)
    • 名词解释(P5)
    • 简介(P5)
    • 开启DDR ECC(P5)
    • HAL里获取DDR ECC信息(P5)
      • 配置(P6)
      • 代码和API(P6)
      • 使用范例(P6)

在线预览​

若预览无法显示,请直接下载 PDF 后用本地阅读器打开。


1. 名词解释​

本文档的简写本文档内释义
ECCError Correcting Code
SEC ECCSingle Bit Single Error Correction Code
DED ECCDouble Error Detection Error Correction Code
DDRDouble Data Rate SDRAM
CECorrectable Error,指单bit可检测可纠正性错误
UEUncorrectable Error,指双bit可检测不可纠正性错误
cschip select
Row特指 DDR row 地址
Chip ID特指 DDR chip id,未激活功能,请忽略
BankGroup特指 DDR4 Bank Group 地址,其他DDR类型请忽略
Bank特指 DDR bank 地址
Col特指 DDR column 地址
Bit position特指 CE 纠正的bit位

2. 简介​

ECC 指 Error Correcting Code ,而DDR ECC 是对DDR数据进行错误检查和纠正的。RK3568只支持SEC/DED ECC。目前仅支持SideBand ECC,即在DDR数据通道旁增加一个专门存放ECC数据的DDR通道。32bit位宽的DDR至少需要7bit位宽的ECC,16bit位宽的DDR至少需要6bit位宽的ECC,8bit位宽的DDR至少需要5bit位宽的ECC。PCB设计请参考带DDR ECC的设计,如RK_EVB6_RK3568_DDR3P416_ECCP216_DD6_V10。

3. 开启DDR ECC​

对于满足SideBand ECC要求的DDR通道,loader会识别出这种设计,并自动使能DDR ECC。

4. HAL里获取DDR ECC信息​

DDR ECC 具体的错误检查与纠正行为是硬件算法完成,软件可以获取相关信息。

4.1 配置​

在相应工程的 hal_conf.h 下使能DDR ECC模块。如rk3568,在project/rk3568/src/hal_conf.h添加如下代码:

#define HAL_DDR_ECC_MODULE_ENABLED

4.2 代码和API​

lib/hal/src/hal_ddr_ecc.c lib/hal/inc/hal_ddr_ecc.h

/* 初始化DDR ECC相关信息 */

HAL_Status HAL_DDR_ECC_Init(struct DDR_ECC_CNT *p);

/* 获取DDR ECC累计的统计信息,包括单bit可纠正错误的数量和双bit可检测不可纠正错误的数量 */

HAL_Status HAL_DDR_ECC_GetInfo(struct DDR_ECC_CNT *p);

4.3 使用范例​

上层软件可以用两种方式获取DDR ECC信息:软件轮询和硬件中断。

软件轮询方式

示例如下:

struct DDR_ECC_CNT eccInfo;
void HAL_DDR_ECC_TEST_POLL(void)
{
uint32_t cpuID;
cpuID = HAL_CPU_TOPOLOGY_GetCurrentCpuId();
if (cpuID == 0) { /* 使用一个cpu、线程或其他方式,初始化

并轮询DDR ECC状态 */

HAL_DDR_ECC_Init(&eccInfo);
while (1) { /* 初始化DDR ECC信息之后,轮询获取DDR
ECC信息 */
HAL_DDR_ECC_GetInfo(&eccInfo); /* 累计的CE和UE数量存放在结构体
eccInfo中 */
HAL_DelayMs(50); /* 轮询间隔时间,可用其他让cpu空闲的
API */
}
}
}

硬件中断方式示例如下:

struct DDR_ECC_CNT eccInfo;
void HAL_DDR_ECC_IRQHandler(uint32_t irq)
{
HAL_DDR_ECC_GetInfo(&eccInfo);
}
void HAL_DDR_ECC_TEST_INT(void)
{
uint32_t cpuID;
cpuID = HAL_CPU_TOPOLOGY_GetCurrentCpuId();
if (cpuID == 0) { /* 使用

一个cpu、线程或其他方式,初始化DDR ECC相关 */

HAL_DDR_ECC_Init(&eccInfo);
HAL_GIC_SetHandler(DDR_ECC_CE_IRQn, HAL_DDR_ECC_IRQHandler); /* 挂载

CE中断服务子程序 */

HAL_GIC_SetHandler(DDR_ECC_UE_IRQn, HAL_DDR_ECC_IRQHandler); /* 挂载

UE中断服务子程序 */

HAL_GIC_Enable(DDR_ECC_CE_IRQn); /* 使能

CE中断服务 */

HAL_GIC_Enable(DDR_ECC_UE_IRQn); /* 使能

UE中断服务 */

}
}

若检测到ECC出错,则打印获取的ECC信息。

# 检测到CE(可纠正错误)2个

[HAL WARNING] DDR ECC error: CE, 2 errors, the last is in DDR cs 0, Row 0xa0,
ChipID 0x0, BankGroup 0x0, Bank 0x5, Col 0x318, Bit position 0x10000000

# 检测到UE(不可纠正错误)1个

[HAL ERROR] DDR ECC error: UE, 1 errors, the last is in DDR cs 0, Row 0xa0,
ChipID 0x0, bankGroup 0x0, Bank 0x5, Col 0x354