发生特定硬故障后如何执行 MCU 重置?

问题描述 投票:0回答:1

由于我在 stackoverflow 或 google 上没有找到现有问题,请查找下面的上下文。 我正在调查导致 ARM Cortex-M33 上出现 2 个不同硬故障的问题。

几乎每次都会出现第一个。 第二种情况很少发生(在两天的密集测试中只发生过几次)。

这两个硬故障具有不同的签名,我的意思是第一个硬故障在 90% 的情况下是 BFAR 有效的精确数据访问错误(因此 CFSR PRECISERR 和 CFSR BFARVALID 设置为 1,因此 CFSR 值为 0x00008200)。

但是,由于第一个硬故障无处不在,因此我很难重现我想研究的第二个硬故障。

问题: 一旦发生硬故障,有什么方法可以通过软件重置 MCU 吗?

我尝试根据 CFSR 值对硬故障签名进行排序,如下面的代码所示,但我无法重置系统,因为 MCU 显然不再能够执行指令。

void HardFault_Handler(void)
{
  /* First hardfault */
  if (SCB->CFSR == 0x00008200)
  {
    APP_DEBUG_SIGNAL_SET(APP_HARD_FAULT);
    
    while(1) {} // Comment this line if NVIC_SystemReset works or there is a way to reset the MCU
//    NVIC_SystemReset(); // Does not work because MCU is in space and cannot execute this anymore
    
  }
  /* The hardfault I'd like to catch */
  else
  {  
    APP_DEBUG_SIGNAL_SET(APP_HARD_FAULT);

    while (1)
    {
    }
  }
}

谢谢您的建议

debugging arm embedded cortex-m hardfault
1个回答
0
投票

您可以使用内联汇编手动重置硬故障处理程序中的堆栈指针,只需几行代码。

我建议将堆栈指针重置为堆栈指针启动值,该值位于闪存的第一个字(地址0x08000000)。所以我会做这样的事情,所有这些都在 asm 易失性(“”)中,我将用伪代码编写:

MOV 0x08000000 到 R0,R0 包含 flash 第一个字的地址
LDR [R0] 到 R1 将闪存的第一个字加载到 R1
MRS R1 进入 MSP 将该值加载到堆栈指针中

此时,堆栈应该可以在硬故障处理程序中再次使用,您甚至应该能够从中调用其他函数。您将重用原始程序堆栈的内存,但如果您在硬故障处理程序中不使用太多堆栈,您甚至可以尝试在程序崩溃时检查程序堆栈,并可能从中学习一些东西。

© www.soinside.com 2019 - 2024. All rights reserved.