FreeRTOS - 硬故障分析 - 失败

FreeRTOS - Hardfault Analysis - Failure

在可以在这里找到的教程之后,我尝试查看哪个线程以及堆栈中的硬故障起源于何处,但没有成功。

与教程不同,我的 HardFault_Handler() 函数不是直接的裸函数,而是转发到一个函数 (prepareRegistersFromStack())。在调试器中,我可以看到跳转到函数 prepareRegistersFromStack()。

这个函数 prepareRegistersFromStack() 然后应该跳转到 getRegistersFromStack() 函数,尽管这从来没有发生过。

我也像示例状态一样直接尝试,所以使 HardFault_Handler() 成为一个应该跳转到 getRegistersFromStack() 的裸函数,但不幸的是同样适用,没有跳转。

有人可以帮我吗?为什么 getRegistersFromStack() 没有被调用?

谢谢

extern "C" __attribute__((naked)) void HardFault_Handler()
{
  __disable_fault_irq();
  __disable_irq();
  prepareRegistersFromStack();
}

extern "C" void prepareRegistersFromStack()
{
  __asm volatile
  (
      " tst lr, #4                                                \n"
      " ite eq                                                    \n"
      " mrseq r0, msp                                             \n"
      " mrsne r0, psp                                             \n"
      " ldr r1, [r0, #24]                                         \n"
      " ldr r2, handler2_address_const                            \n"
      " bx r2                                                     \n"
      " handler2_address_const: .word getRegistersFromStack       \n"
  );
}

extern "C" void getRegistersFromStack( uint32_t *pulFaultStackAddress )
{
  uint32_t dummy;
  /* These are volatile to try and prevent the compiler/linker optimising them
     away as the variables never actually get used.  If the debugger won't show the
     values of the variables, make them global my moving their declaration outside
     of this function. */
  volatile uint32_t r0;
  volatile uint32_t r1;
  volatile uint32_t r2;
  volatile uint32_t r3;
  volatile uint32_t r12;
  volatile uint32_t lr; /* Link register. */
  volatile uint32_t pc; /* Program counter. */
  volatile uint32_t psr;/* Program status register. */

  r0 = pulFaultStackAddress[ 0 ];
  r1 = pulFaultStackAddress[ 1 ];
  r2 = pulFaultStackAddress[ 2 ];
  r3 = pulFaultStackAddress[ 3 ];

  r12 = pulFaultStackAddress[ 4 ];
  lr  = pulFaultStackAddress[ 5 ];
  pc  = pulFaultStackAddress[ 6 ];
  psr = pulFaultStackAddress[ 7 ];

  /* When the following line is hit, the variables contain the register values. */
  for(;;);

  /* remove warnings */
  dummy = r0;
  dummy = r1;
  dummy = r2;
  dummy = r3;
  dummy = r12;
  dummy = lr;
  dummy = pc;
  dummy = psr;
  dummy = dummy;
}

在您修改后的方法中,您更改了堆栈帧(当您调用 prepareRegistersFromStack() 时),因此它不会像写的那样工作。恢复到原始样本。我之前使用过以下示例,我相信这是您的代码片段所基于的: https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html

但是,我现在更喜欢使用 IDE 内置的功能或以下 "C" 可以利用串行端口或 IDE 的方法: https://blog.feabhas.com/2013/02/developing-a-generic-hard-fault-handler-for-arm-cortex-m3cortex-m4/