STM32F4 错误处理程序和允许的操作

STM32F4 Error Handler and allowed operations

总结:遇到hard fault,debug信息放哪里?

详情:

我的问题是错误处理程序偶尔会被触发一次,而且无法重现。我怀疑这是一个硬故障,因为 Error_Handler() 我确实向 USB 端口打印了一些东西,但没有收到任何东西。

公开硬故障信息的标准方法是将printf 打印到调试端口。但由于这种情况发生在移动设备上,并且在几个小时内只发生一次,所以我无法一直连接调试器。 我假设在硬故障中只能做这么多,例如USB 不再工作,UART 不工作,通过 SPI 写入 EEPROM 也不工作。那是对的吗?如果是,你会怎么做?

硬故障处理程序正在执行代码,您可以在那里随心所欲地执行操作,但请注意,当您在那里时,出现了错误。如果您使用的是 USB,则可能是您的堆栈处于错误状态,因此,您可能需要完全重新初始化它和外围设备。您可能已经溢出了堆栈,因此可以对其进行清理。

没有什么能阻止您 运行 异常处理程序中的复杂代码。然而,处理程序确实具有 -1 的固定优先级,因此您将无法处理任何中断,因为它们不会中断异常处理程序。这很可能是您的外围设备无法正常工作的原因,请尝试轮询它们。

如果你不能让它们运行,一个解决方案是在你的链接描述文件中定义一块内存,它在重置时未初始化,存储你在那里拥有的任何相关信息,重置,并在你的主代码中重置检查该内存区域并输出您存储在任何媒体上的任何内容。如果数据不多而且你还没有使用它们,STM32 中的 RTC 外设有一些寄存器可以自由用于任意数据,并且不受重置影响。

您当然应该假设系统内存和外围设备处于不可预测的状态,并且re-initialize处理程序中将要使用的所有内容。

  • 堆栈可能已损坏,或者堆栈指针无效。保存所有寄存器并将堆栈重新定位到内部 SRAM 中已知的安全位置,作为故障处理程序中的第一件事,而不调用 any 函数。在汇编中更好地实现。
  • 抚摸看门狗。
  • 使用 RCC 复位寄存器复位所有内部外围设备。
  • 将内部时钟设置为已知的安全频率。
  • 重置外围设备和总线(如果适用),例如如果外部存储器有复位线,脉冲它。如果要写入 I2C EEPROM,请脉冲 SCL 10 次以重置总线。
  • printf()stdio 基础设施有太多的内部状态,例如输出缓冲区和工作区分配 malloc(),因此最好不要使用它们,但使用简单的文本和十六进制数字输出函数。