在STM32F411 Discovery上实现HD44780 LCD的同时调试HardFault

时间:2018-10-04 08:50:59

标签: c eclipse arm stm32 stm32f4discovery

使用此库在STM32F411 Discovery上对LCD HD44780进行编程时遇到问题:https://stm32f4-discovery.net/2015/07/hal-library-15-hd44780-for-stm32fxxx/问题是,在实现该库并运行代码后,我通常会陷入HardFault_Handler函数中。我通读了互联网上有关调试硬故障的几篇文章,并从以下站点实现了HardFault_HandlerC功能:https://community.nxp.com/thread/389002该程序现在陷入了该功能,这使我对寄存器中的内容有更深入的了解,但是现在我真的不知道下一步该怎么做,因为这些值绝对告诉我什么。

这些是提到的寄存器的值:

stacked_r0  volatile unsigned long  0   
stacked_r1  volatile unsigned long  0   
stacked_r2  volatile unsigned long  0   
stacked_r3  volatile unsigned long  1   
stacked_r12 volatile unsigned long  45000000    
stacked_lr  volatile unsigned long  11018266    
stacked_pc  volatile unsigned long  553682714   
stacked_psr volatile unsigned long  8192    
_CFSR   volatile unsigned long  256 
_HFSR   volatile unsigned long  1073741824  
_DFSR   volatile unsigned long  11  
_AFSR   volatile unsigned long  0   
_BFAR   volatile unsigned long  3758157112  
_MMAR   volatile unsigned long  3758157108  

请问我下一步该怎么做才能进一步检查问题?

我的随机程序也陷入了这段代码中(而不是HardFault):

/* Wait till LSE is ready */
      while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
      {
        if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
        {
          return HAL_TIMEOUT;
        }
      }

这似乎与统一LSE有关,但我认为我应该首先专注于调试硬故障。

1 个答案:

答案 0 :(得分:0)

调试硬故障非常困难。您很有可能进入了硬故障处理程序,因为发生了一个异常,而该异常没有可用的处理程序,尽管可能是因为处理程序本身已经生成了一个异常。

正如Lundin在评论中所说,如果您有一个不错的调试器,则可以在硬故障处理程序中放置一个断点,并使调试器向您显示完整的调用堆栈。但是,如果没有,您将不得不采取艰苦的方式。

当CPU进入处理程序模式以处理异常时,硬件会将各种寄存器压入活动堆栈,并且您实现的处理程序会将这些寄存器从堆栈中取出来进行检查。首先要看的是堆栈式程序计数器(PC)的内容。尝试以十六进制获取其值;然后,您应该可以使用调试器将其与生成错误的指令的地址相关联。

如果堆叠的PC地址与合理的代码地址不对应,则很可能另一行代码试图跳转到该废话地址,这就是引发故障的原因。在这种情况下,您可以通过查看堆栈的链接寄存器(LR)地址来获取一些信息-该地址应包含自CPU上次遇到调用指令以来的程序计数器值。这可能与生成流氓分支的那行不完全对应,但是它应该使您足够接近以放置另一个断点并逐步执行,直到发生异常为止。

如果这些建议仍不能使您找到罪魁祸首,我很乐意编辑此答案并提供进一步的建议-请发表评论,我会尽快与您联系。