如何在ARM Cortex-M7 MCU上触发各类故障(含非精确总线故障)
ARM Cortex-M7 故障触发测试函数扩展方案
针对你在Cortex-M7项目中需要扩展故障自检测试的需求,以下是新增各类故障的实现方法,重点解决非精确总线故障的触发问题:
一、现有测试函数的小补充
你已实现的测试中,test_1的NULL指针访问在不同配置下可能触发MemFault而非UsageFault,需确保SCB->CCR的UNALIGN_TRP、DIV_0_TRP等位已正确配置,同时MPU未对0地址区域开放访问权限,才能稳定触发UsageFault。
二、新增故障测试函数
1. 非精确总线故障(Imprecise Bus Fault)
非精确总线故障的核心是延迟触发:总线写操作通常是流水线执行的,不会立即报错,当后续指令执行时,总线事务的错误才被上报,此时无法精准定位故障地址。实现代码如下:
/* 非精确总线故障:无效地址写操作+后续指令延迟触发 */ void test_5(void) { volatile uint32_t *invalid_write_addr = (volatile uint32_t *)0xDEADBEEF; *invalid_write_addr = 0x12345678; // 发起无效总线写,事务挂起 __NOP(); // 后续指令,此时总线错误才被触发 __NOP(); }
验证要点:在Fault Handler中检查
SCB->CFSR的BUSFAULTSR字段,IMPRECISERR位会置1;同时SCB->BFARVALID位为0,说明故障地址寄存器(BFAR)中的值无效。
配置要求:确保SCB->SHCSR的BUSFAULTENA置1,且MPU未对0xDEADBEEF地址开放访问权限。
2. 非对齐访问故障(Usage Fault)
需先开启非对齐触发故障的配置,再执行非对齐内存操作:
/* Usage Fault - 非对齐内存访问 */ void test_6(void) { // 开启非对齐访问触发故障 SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; uint32_t test_buf[2] = {0x11223344, 0x55667788}; // 生成非对齐指针(偏移1字节) uint32_t *unaligned_ptr = (uint32_t *)((uint8_t *)test_buf + 1); uint32_t dummy_val = *unaligned_ptr; // 触发非对齐访问故障 (void)dummy_val; }
3. 整数除零故障(Usage Fault)
开启除零触发故障的配置后执行除零操作:
/* Usage Fault - 整数除零错误 */ void test_7(void) { // 开启除零触发故障 SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk; int32_t num = 100; int32_t zero = 0; int32_t result = num / zero; // 触发除零故障 (void)result; }
4. 栈溢出故障(HardFault/MemFault)
通过修改栈指针到无效区域,再执行函数调用触发栈访问错误:
/* 栈溢出故障:修改栈指针到无效区域后调用函数 */ void test_8(void) { // 假设主栈起始地址为0x20008000,将栈指针设置到栈下界之外 __set_MSP(0x20000000 - 4); LogErr("Stack overflow test"); // 函数调用会使用非法栈指针,触发故障 }
5. 用户模式协处理器访问故障(MemFault)
若MCU配置为禁止用户模式访问协处理器,切换到用户模式后访问协处理器即可触发:
/* MemFault - 用户模式下访问特权协处理器 */ __attribute__((naked)) void test_9(void) { __asm volatile( "MOV R0, #0x10\n" // 切换到用户模式(CONTROL寄存器:SPSEL=0,MODE=0b10000) "MSR CONTROL, R0\n" "ISB\n" "VMOV S0, R0\n" // 尝试访问FPU协处理器(需配置为特权访问) "BX LR\n" ); }
三、通用配置注意事项
- 确保
SCB->SHCSR中的USGFAULTENA、BUSFAULTENA、MEMFAULTENA全部置1,开启各类故障的响应。 - MPU配置:所有用于触发故障的地址区域,需通过MPU配置为禁止访问(权限、执行属性等),否则可能无法触发预期故障。
- 故障Handler中需正确解析
SCB->CFSR、SCB->BFAR、SCB->MMFAR等寄存器,才能准确识别故障类型和信息。
内容的提问来源于stack exchange,提问作者TKKS
相关产品推荐
相关产品推荐

