IF-SAFE-05 MTU内存测试
【IF-SAFE-05】MTU内存测试:启动与运行时的自检
英飞凌AURIX™ TC3xx功能安全专题第五篇。本文深入解析Memory Test Unit(MTU)的工作原理,涵盖MBIST非破坏性测试算法、Gang分组机制、SRAM初始化与ECC配置、以及SMU联动的安全响应流程,为构建符合ISO 26262要求的存储系统提供完整指南。
系列导航
| 序号 | 文章 | 状态 |
| IF-SAFE-01 | 功能安全入门:ISO 26262与TC3xx安全架构 | 已发布 |
| IF-SAFE-02 | 基础设施安全:电源/时钟/SCU的守护 | 已发布 |
| IF-SAFE-03 | Lockstep双核锁步:ASIL-D核心保障 | 已发布 |
| IF-SAFE-04 | ECC全覆盖:从CPU到外设的数据完整性 | 已发布 |
| **IF-SAFE-05** | **MTU内存测试:启动与运行时的自检** | **本文** |
| IF-SAFE-06 | 安全IO:采集/执行/通信保护链 | 规划中 |
|---|
一、MTU概述与工作原理
1.1 为什么需要MTU
在汽车MCU应用中,SRAM(Static RAM)是数据存储的核心载体。不同于ROM的永久存储特性,SRAM是易失性存储器,对制造缺陷和运行老化高度敏感:
-
**制造缺陷**:晶体管或互连线的微小缺陷可能导致存储单元失效
-
**工艺波动**:先进制程的工艺波动可能引入软错误
-
**老化效应**:长期使用后,氧化层退化导致数据保持能力下降
-
**辐射干扰**:空间辐射(尤其是汽车环境)可能引发单粒子翻转(SEU)
-
根据ISO 26262对硬件架构指标的要求,存储单元的失效率必须被纳入FMEDA计算。而MTU(Memory Test Unit)正是TC3xx提供的内置测试机制,用于:
-
启动时自检:确保上电瞬间存储系统处于健康状态
-
运行时监控:检测运行过程中的位翻转和ECC错误
-
诊断覆盖率提升:满足ASIL等级对诊断机制的要求
1.2 MTU模块功能定位
MTU是TC3xx芯片内部的一个专用硬件模块,其核心职责是控制和监控各种内部存储器的测试、初始化和数据完整性检查功能。
┌─────────────────────────────────────────────────────────────┐ │ AURIX™ TC3xx │ │ │ │ ┌─────────────┐ │ │ │ MTU │◄──── 控制与状态接口 │ │ │ Memory │ │ │ │ Test Unit │ │ │ └──────┬──────┘ │ │ │ │ │ ┌────┴────┬────────┬────────┬────────┐ │ │ ▼ ▼ ▼ ▼ ▼ │ │ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │ │ │SSH │ │SSH │ │SSH │ │SSH │ │SSH │ ... │ │ │ │ │ │ │ │ │ │ │ │ │ │ └──┬─┘ └──┬─┘ └──┬─┘ └──┬─┘ └──┬─┘ │ │ │ │ │ │ │ │ │ ┌──┴──┐ ┌──┴──┐ ┌──┴──┐ ┌──┴──┐ ┌──┴──┐ │ │ │SRAM │ │SRAM │ │SRAM │ │SRAM │ │SRAM │ ... │ │ │DSPR │ │PSPR │ │LMU │ │DMA │ │GTM │ │ │ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │ └─────────────────────────────────────────────────────────────┘MTU的三大核心功能:
| 功能 | 描述 | 使用场景 |
| **SRAM初始化** | 使用预设值填充SRAM内容,同时生成ECC校验码 | 启动时确保干净初始状态 |
| **MBIST测试** | 执行存储阵列的自检,检测制造缺陷和老化 | 启动自检、周期性自检 |**ECC管理** 配合SSH模块,完成错误检测与纠正 运行时数据保护 1.3 SSH SRAM支持硬件
每个SRAM模块周围都环绕着一圈数字逻辑,称为SRAM Support Hardware(SSH)。SSH是连接MTU与物理存储阵列的桥梁,其核心功能包括:
ECC控制:
-
-
生成写入数据的ECC校验码
-
读取时校验并纠正单比特错误
-
报告不可纠正的多比特错误
-
BIST控制:
-
接收MTU的测试命令
-
控制测试序列的执行
-
报告测试结果
-
地址解码:
-
提供CPU/DMA访问接口
-
支持直接内存访问模式
-
实现地址映射和保护
c
// SSH关键寄存器
typedef struct {
volatile uint32 CONFIG0; // 测试模式配置
volatile uint32 CONFIG1; // 测试参数配置
volatile uint32 MCONTROL; // 测试控制
volatile uint32 MSTATUS; // 测试状态
volatile uint32 MADDR; // 测试地址
volatile uint32 MDATA; // 测试数据
} SSH_Registers;
二、MBIST技术详解
2.1 Non-Destructive Test(NDT)原理
MBIST(Memory Built-In Self-Test)是一种结构性测试方法,用于验证存储阵列的完整性。TC3xx提供**非破坏性测试(NDT)**模式,其核心原理是:
-
保存原数据:先将SRAM当前内容读出保存
-
执行测试:使用已知Pattern测试存储单元
-
恢复数据:测试完成后恢复原始内容
-
报告结果:通过状态寄存器报告测试结果
c
// MBIST NDT测试伪代码
void MBIST_NDT_Test(IfxMtu_MbistSel memory)
{
// Step 1: 保存原数据(MTU自动处理)
// Step 2: 执行非破坏性测试
IfxMtu_enableModule();
IfxMtu_runNonDestructiveInversionTest(memory);
// Step 3: 检查结果
if (MTU_ERROR_DETECTED) {
// 报告错误到SMU
SMU_Report_Error(MTU_ALARM_GROUP, MTU_ALARM_INDEX);
}
// Step 4: 数据自动恢复
}
测试算法:MTU采用March算法族进行测试,这是一种地址遍历式的存储阵列测试方法:
| 算法 | 特点 | 覆盖能力 |
| **March C-** | 经典算法 | 耦合故障、地址 decoder故障 |
| **MATS+** | 链接故障优化 | 链接故障、地址decoder故障 |
| **Inversion** | 数据反转测试 | 保持故障、跃迁故障 |
|---|
2.2 Gang分组机制
TC3xx的SRAM数量众多(TC39xB有100+个SRAM块),如果同时测试所有SRAM,瞬时电流冲击会超过芯片的供电能力。为此,MTU采用Gang分组机制:
- **同Gang内SRAM并行测试**:共享测试时钟和数据总线
- **Gang间顺序测试**:避免电流叠加
- **可配置分组**:用户可自定义Gang配置
Gang 0: [EMEM0] [M_CAN10]
Gang 1: [EMEM1] [ERAY_MBF0] [M_CAN20] [M_CAN21]
Gang 2: [EMEM2] [ERAY_MBF1]
...
Gang 4: [CPU0_DMEM] [CPU1_DMEM] [GTM_DPLL2]
Gang 5: [CPU0_DMEM1] [CPU1_DMEM1] [HSPDM_RAM] [SCR_XRAM]
| Gang | 包含SRAM | 用途 |
| 0 | EMEM0, M_CAN10 | 外部存储+CAN |
| 4 | CPU0/1 DMEM | CPU数据缓存 |
| 5 | CPU0/1 DMEM1, HSPDM | 扩展缓存 |
| 6 | LMU, DLMU_STBY | 本地存储 |
| 7 | CPU2 DMEM, GIGETH | 网络+CPU |
|---|
2.3 MBIST执行流程
完整的MBIST执行流程如下:
c
// MBIST测试完整流程
void MBIST_Test_Complete(void)
{
// 1. 使能MTU模块
IfxMtu_enableModule();
// 2. 检查是否有未清除的不可纠正错误
if (get_MTU_MBIST_Errors() != 0) {
// 清除UCERR告警状态
clear_MTU_MBIST_Errors();
// 此状态在系统复位后自动设置
}
// 3. 初始化待测SRAM(可选,用于干净测试环境)
IfxMtu_clearSram(IfxMtu_MbistSel_dma); // 例如:DMA RAM
// 4. (可选)注入错误用于测试验证
if (g_errorInjection == TRUE) {
inject_single_bit_error(0x1F);
}
// 5. 执行非破坏性测试
IfxMtu_runNonDestructiveInversionTest(IfxMtu_MbistSel_dma);
// 6. 返回结果
// - TRUE: RAM内容正确
// - FALSE: 检测到错误
}
// 错误注入实现(仅用于测试验证)
void inject_single_bit_error(uint32 address)
{
// 安全Endinit保护必须先清除
IfxScuWdt_clearSafetyEndinit();
// 使能MBIST控制器
IfxMtu_enableMbistShell();
// 等待SRAM初始化完成(如为自动初始化类型)
while (IfxMtu_isAutoInitRunning());
// 读取目标地址数据
uint32 data = IfxMtu_readSramAddress(address);
// 仅修改1位注入可纠正错误(SECDED)
data ^= 0x00000001; // 翻转bit0
// 写回数据
IfxMtu_writeSramAddress(address, data);
// 禁用MBIST控制器
IfxMtu_disableMbistShell();
// 恢复安全Endinit
IfxScuWdt_setSafetyEndinit();
}
2.4 结果评估与报告
MTU测试完成后,通过以下机制报告结果:
| 结果类型 | 含义 | 处理方式 |
| **无错误** | 所有存储单元通过测试 | 继续正常启动/运行 |
| **可纠正错误(SED)** | 单比特翻转,ECC已自动纠正 | 记录日志,增加自检频率 |
| **不可纠正错误(CED/UCE)** | 多比特错误,ECC无法纠正 | 触发SMU告警,进入安全状态 |
|---|
c
// 结果判断
bool MBIST_Result = IfxMtu_runNonDestructiveInversionTest(memory);
if (MBIST_Result == TRUE) {
// 测试通过
LED_SetState(LED_PASS, ON); // 点亮PASS LED
} else {
// 测试失败
LED_SetState(LED_FAIL, ON); // 点亮FAIL LED
// SMU告警已在内部触发
}
三、SRAM初始化与ECC配置
3.1 自动初始化机制
TC3xx支持SRAM自动初始化功能,在上电后自动执行,无需CPU干预:
配置方式:通过UCB(User Configuration Block)配置
c
// UCB配置项
typedef struct {
uint32 INIT0; // 初始化Pattern 0
uint32 INIT1; // 初始化Pattern 1
uint32 MEM_DONE; // 初始化完成标志
uint32 MBIST_SEL; // 测试选择
} UCB_MTUSREntry;
初始化Pattern:
-
INIT0和INIT1定义初始化值(可设为不同Pattern以检测互联故障)
-
典型值:`0x00000000`(全0)或`0xFFFFFFFF`(全1)
-
自动初始化执行流程:
-
系统复位后,硬件自动开始初始化
-
SSH模块控制数据写入和ECC生成
-
初始化完成后置位
MEM_DONE -
CPU可通过寄存器查询初始化状态
3.2 手动初始化流程
对于需要更精细控制的场景,MTU提供手动初始化API:
c// 手动SRAM初始化 void Manual_SRAM_Init(IfxMtu_MbistSel memory, uint32 pattern) { // 1. 使能MTU IfxMtu_enableModule(); // 2. 清除SRAM内容 IfxMtu_clearSram(memory); // 函数内部: // - 写入pattern到所有地址 // - 自动生成ECC码 // - 等待完成 // 3. 验证初始化 // (可选)执行MBIST确认初始化成功 }3.3 ECC配置与校验
TC3xx的SRAM均配备SECDED(Single Error Correction, Double Error Detection)ECC:
-
-
**单比特错误**:自动纠正,不触发中断
-
**双比特错误**:触发不可纠正错误(UCE)告警
c
// ECC配置示例
void ECC_Configuration(void)
{
// 安全Endinit保护
IfxScuWdt_clearSafetyEndinit();
// 配置ECC模式(通过SSH寄存器)
// CONFIG0[7:6] = ECC模式选择
SSH->CONFIG0 &= ~0x00C0; // 清除
SSH->CONFIG0 |= 0x0040; // SECDED模式
// 使能ECC纠错报告
// MCONTROL[0] = ECC纠错使能
SSH->MCONTROL |= 0x0001;
IfxScuWdt_setSafetyEndinit();
}
// ECC错误处理
void ECC_Error_Handler(void)
{
// 读取ECC状态寄存器
uint32 ecc_status = SSH->MSTATUS;
if (ecc_status & 0x01) {
// 单比特错误(可纠正)
uint32 addr = SSH->MADDR;
uint32 data = SSH->MDATA;
// 记录日志(不进入安全状态)
Log_AddEntry(LOG_ECC_CORRECTABLE, addr, data);
}
if (ecc_status & 0x02) {
// 双比特错误(不可纠正)
// 触发SMU告警
SMU_Trigger_Alarm(SMU_ALARM_MTU_UCE);
}
}
四、运行时内存自检
4.1 启动阶段自检策略
根据ISO 26262要求,安全相关ECU必须在启动阶段执行存储系统自检(LBIST/MBIST)。TC3xx的标准启动序列:
Cold Power On Reset
│
▼
┌───────────────────┐
│ 1. 基础初始化 │ EVR、时钟、SCU基本配置
└─────────┬─────────┘
│
▼
┌───────────────────┐
│ 2. PMS初始化 │ 电源管理(为LBIST准备)
└─────────┬─────────┘
│
▼
┌───────────────────┐
│ 3. LBIST执行 │ Logic BIST(CPU核心逻辑)
│ (可选) │ 失败→系统复位
└─────────┬─────────┘
│
▼
┌───────────────────┐
│ 4. SRAM初始化 │ 清除所有SRAM + 生成ECC
│ (自动/手动) │ 等待完成
└─────────┬─────────┘
│
▼
┌───────────────────┐
│ 5. MBIST执行 │ MTU执行内存自检
│ (关键!) │ 失败→SMU告警→安全状态
└─────────┬─────────┘
│
▼
┌───────────────────┐
│ 6. CPU启动 │ 开始执行用户代码
└───────────────────┘
MBIST启动测试代码示例:
c
// 启动阶段MBIST测试
void Startup_MBIST(void)
{
printf("Starting MTU MBIST...\n");
bool all_pass = TRUE;
// 按优先级测试关键SRAM
IfxMtu_MbistSel critical_memories[] = {
IfxMtu_MbistSel_cpu0_dspr, // CPU0数据缓存
IfxMtu_MbistSel_cpu0_pspr, // CPU0程序缓存
IfxMtu_MbistSel_cpu1_dspr, // CPU1数据缓存
IfxMtu_MbistSel_lmu, // 本地存储单元
IfxMtu_MbistSel_dma, // DMA缓存
};
for (int i = 0; i < sizeof(critical_memories)/sizeof(IfxMtu_MbistSel); i++) {
printf("Testing memory %d...\n", i);
if (!IfxMtu_runNonDestructiveInversionTest(critical_memories[i])) {
printf("FAIL: Memory %d\n", i);
all_pass = FALSE;
// 触发SMU告警
SMU_Report_Error(MTU_ALARM_GROUP, critical_memories[i]);
}
}
if (!all_pass) {
// 进入安全状态(不启动应用)
while(1); // 或触发系统复位
}
printf("MBIST All PASS\n");
}
4.2 运行阶段周期自检
对于ASIL-D应用,除了启动自检,还需要在运行时执行周期性自检:
c
// 运行时MBIST任务
void MBIST_Periodic_Task(void)
{
static uint8 current_gang = 0;
static bool testing = FALSE;
// 一个测试周期内只测一个Gang
if (!testing) {
// 启动新测试
testing = TRUE;
IfxMtu_enableModule();
IfxMtu_runNonDestructiveInversionTest(gang_to_memory[current_gang]);
}
// 检查测试完成
if (IfxMtu_isTestComplete()) {
bool result = IfxMtu_getTestResult();
if (!result) {
// 测试失败
SMU_Report_Error(MTU_ALARM_GROUP, current_gang);
}
// 切换到下一Gang
current_gang = (current_gang + 1) % NUM_GANGS;
testing = FALSE;
}
}
// 100ms周期任务(OS调度)
void MBIST_100ms_Task(void)
{
static uint32 cycle_counter = 0;
// 每秒执行一次完整测试循环
if (++cycle_counter >= 10) {
cycle_counter = 0;
MBIST_Periodic_Task();
}
}
4.3 软件触发机制
MTU提供丰富的软件接口用于触发测试:
| API | 功能 |
| `IfxMtu_enableModule()` | 使能MTU模块 |
| `IfxMtu_clearSram()` | 清除SRAM |
| `IfxMtu_runNonDestructiveInversionTest()` | 执行NDT |
| `IfxMtu_isTestComplete()` | 查询测试完成状态 |
| `IfxMtu_getTestResult()` | 获取测试结果 |
| `IfxMtu_enableMbistShell()` | 使能MBIST控制器 |
| `IfxMtu_disableMbistShell()` | 禁用MBIST控制器 |
|---|
4.4 性能影响评估
MBIST测试会占用一定的CPU时间和内存带宽,需要评估其对实时性能的影响:
| 测试方式 | 耗时 | CPU占用 | 内存可用性 |
| **启动全测** | 100-500ms | 0%(硬件执行) | 暂停访问 |
| **周期Gang轮测** | 1-5ms/Gang | 极低 | 其他Gang可用 |
| **按需测试** | 即时响应 | 按需 | 按需 |
|---|
优化策略:
-
Gang轮测:将测试分散到多个周期,避免长时阻塞
-
DMA配合:使用DMA执行测试,减少CPU干预
-
优先级调度:在系统空闲时(如IDLE任务)执行
五、故障检测与安全响应
5.1 错误分类
MTU相关的错误可分为两类:
| 错误类型 | 代码 | 检测机制 | 处理要求 |
| **SED**(可纠正) | 0x01 | ECC自动检测+纠正 | 记录,可选响应 |
| **UCE**(不可纠正) | 0x02 | ECC检测 | 必须触发SMU告警 |
|---|
c
// 错误状态寄存器
typedef struct {
uint32 CEIF : 1; // 可纠正错误中断标志
uint32 UCEIF : 1; // 不可纠正错误中断标志
uint32 MTTIF : 1; // 测试完成中断标志
uint32 MTFIF : 1; // 测试失败中断标志
// ... 更多状态位
} MTU_IS_FLAGS;
5.2 SMU告警响应
当MTU检测到UCE错误时,会自动触发SMU(Safety Management Unit)告警:
c
// SMU告警配置
void SMU_MTU_Configuration(void)
{
// 配置SMU告警响应
SMU_Set_Response(SMU_ALARM_MTU_UCE, SMU_RESPONSE_RESET);
// 或更安全的方式:立即进入安全状态
SMU_Set_Response(SMU_ALARM_MTU_UCE, SMU_RESPONSE_SAFE_STATE);
}
// SMU响应定义
typedef enum {
SMU_RESPONSE_NONE = 0, // 无响应
SMU_RESPONSE_NMI = 1, // 不可屏蔽中断
SMU_RESPONSE_RESET = 2, // 系统复位
SMU_RESPONSE_SAFE_STATE = 3 // 进入安全状态
} SMU_Response;
5.3 安全状态转换
根据ISO 26262要求,当检测到不可纠正的存储错误时,系统必须进入安全状态:
正常状态 ──检测到UCE错误──► SMU告警 ──► 安全状态
│
├── 复位(快速恢复)
│
└── 安全模式运行(降级功能)
安全状态设计原则:
-
数据保护:避免使用故障存储区的数据
-
功能降级:禁用依赖故障区域的功能
-
诊断记录:保存错误上下文供后续分析
-
冗余切换:切换到备份数据路径(如有)
c
// 安全状态处理
void Safe_State_Handler(void)
{
// 1. 禁用故障区域访问
Disable_Memory_Region(FAULTY_RAM);
// 2. 切换到安全数据备份
Switch_To_Safe_Data_Region();
// 3. 记录诊断信息
Dem_ReportErrorStatus(DEM_EVENT_ID_MTU_UCE, DEM_EVENT_STATUS_FAILED);
// 4. 通知上层应用
Appl_SafeStateIndication(SAFE_STATE_RAM_FAULT);
// 5. 进入安全循环
while (1) {
Watchdog_Feed();
Safe_State_Idle();
}
}
5.4 与ISO 26262的对应关系
MTU机制满足ISO 26262对存储系统诊断的多项要求:
| ISO 26262条款 | MTU满足方式 |
| **硬件架构指标** | MTU提供高诊断覆盖率(DC),提升SPFM/LFM |
| **启动测试** | MBIST NDT作为上电自检(POST)的一部分 |
| **运行测试** | 周期性MBIST支持现场诊断 |
| **安全状态** | UCE触发SMU响应,确保进入安全状态 |
| **FTTI满足** | MTU响应时间 < 1ms,满足大多数FTTI要求 |
|---|
六、架构图与总结

图1:AURIX TC3xx MTU内存测试架构图,展示MTU与SSH、SRAM、SMU的协作关系

图2:本文核心知识点思维导图
七、代码实战:完整MBIST示例
c
/**
* MTU_MBIST.c - AURIX TC3xx MBIST完整示例
* 适用于: TC37x, TC38x, TC39x等
*/
#include "IfxMtu.h"
#include "IfxScuWdt.h"
#include "IfxPort.h"
// LED定义(KIT_A2G_TC375_LITE板)
#define LED_PASS IfxPort_P00_5
#define LED_FAIL IfxPort_P00_6
// 错误注入开关(仅用于测试)
volatile boolean g_errorInjection = FALSE;
/**
* 初始化LED
*/
void LED_Init(void)
{
IfxPort_setPinMode(LED_PASS, IfxPort_Mode_outputPushPullGeneral);
IfxPort_setPinMode(LED_FAIL, IfxPort_Mode_outputPushPullGeneral);
IfxPort_setPinHigh(LED_PASS);
IfxPort_setPinHigh(LED_FAIL);
}
/**
* LED控制
*/
void LED_SetState(IfxPort_Pin pin, boolean on)
{
if (on) {
IfxPort_setPinLow(pin); // LED低电平点亮
} else {
IfxPort_setPinHigh(pin);
}
}
/**
* 获取MBIST错误状态
*/
uint32 get_MTU_MBIST_Errors(void)
{
// 检查SMU ECCD.UCERR或FAULTSTS.OPERR
// 注意:系统复位后这些位会被设置
return 0; // 简化实现
}
/**
* 清除MBIST错误状态
*/
void clear_MTU_MBIST_Errors(void)
{
// 清除SMU告警和错误标志
// 实现依赖于具体芯片
}
/**
* MBIST测试函数
*/
boolean test_MTU_MBIST(IfxMtu_MbistSel memory)
{
boolean test_pass = TRUE;
// 使能MTU模块
IfxMtu_enableModule();
// 检查并清除未清除的错误
if (get_MTU_MBIST_Errors() != 0) {
clear_MTU_MBIST_Errors();
}
// 使用MTU清除SRAM内容
IfxMtu_clearSram(memory);
// (可选)注入错误用于测试
if (g_errorInjection == TRUE) {
// 此处实现错误注入逻辑
}
// 执行非破坏性测试
boolean result = IfxMtu_runNonDestructiveInversionTest(memory);
if (result == FALSE) {
test_pass = FALSE;
}
return test_pass;
}
/**
* 主测试循环
*/
int core0_main(void)
{
// 初始化
LED_Init();
printf("MTU MBIST Test Starting...\n");
// 测试DMARAM
boolean dmaram_result = test_MTU_MBIST(IfxMtu_MbistSel_dma);
if (dmaram_result == TRUE) {
printf("DMARAM Test: PASS\n");
LED_SetState(LED_PASS, TRUE);
} else {
printf("DMARAM Test: FAIL\n");
LED_SetState(LED_FAIL, TRUE);
}
while (1) {
// 主循环
}
return 0;
}
八、附录:MTU寄存器速查
| 寄存器 | 偏移 | 功能 |
| MTU_ACCEN0 | 0x00 | 访问使能0 |
| MTU_ACCEN1 | 0x04 | 访问使能1 |
| MTU_MC | 0x08 | MTU控制 |
| MTU_MSTAT | 0x0C | MTU状态 |
| MTU_MCOUNT | 0x10 | 内存计数 |
| MTU_MAD | 0x14 | 内存地址 |
| MTU_MD | 0x18 | 内存数据 |
|---|
下期预告:IF-SAFE-06将详解安全IO设计,涵盖采集通道保护、执行输出保护、以及通信端口的完整性验证,构建完整的功能安全保护链。