简体   繁体   English

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

[英]Debugging HardFault while implementing HD44780 LCD on STM32F411 Discovery

I have problem while programming LCD HD44780 on STM32F411 Discovery using this library: https://stm32f4-discovery.net/2015/07/hal-library-15-hd44780-for-stm32fxxx/ The problem is that after implementing the library and running the code I am usually get stuck in HardFault_Handler function. 使用此库在STM32F411 Discovery上对LCD HD44780进行编程时遇到问题: https ://stm32f4-discovery.net/2015/07/hal-library-15-hd44780-for-stm32fxxx/问题是在实现该库并运行后我通常被困在HardFault_Handler函数中的代码。 I read through a few articles on the internet about debuging hard faults and I implemented HardFault_HandlerC function from this site: https://community.nxp.com/thread/389002 The program now gets stuck in this function, which gives me insight about what is in the registers, but now I have really no idea what I should do next, because these values tell me absolutely nothing. 我通读了互联网上有关调试硬故障的几篇文章,并从此站点实现了HardFault_HandlerC函数: https : HardFault_HandlerC该程序现在陷入了该函数的困境,这使我了解了什么是在寄存器中,但是现在我真的不知道下一步该怎么做,因为这些值绝对告诉我什么。

These are the values of mentioned registers: 这些是提到的寄存器的值:

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  

Can somebody please tell me what should I do next to inspect the problem further? 有人可以告诉我下一步该怎么做才能进一步检查问题吗?

Also my program on random runs also gets stuck in this block of code (instead of HardFault): 另外,我的随机运行程序也卡在此代码块中(而不是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;
        }
      }

Which seems to be related to unitialized LSE, but I think I should focus on debugging hard fault first. 这似乎与统一的LSE有关,但我认为我应该首先关注调试硬故障。

Debugging hard faults is notoriously difficult. 调试硬故障非常困难。 You have most likely entered the hard fault handler because an exception has occurred for which no handler is available, though it could possibly be because a handler has itself generated an exception. 您很有可能进入了硬故障处理程序,因为发生了一个异常,而该异常没有可用的处理程序,尽管可能是因为处理程序本身已经生成了异常。

As Lundin said in a comment, if you have a decent debugger you may be able to place a breakpoint inside the hard fault handler and have the debugger show you a complete call stack. 正如Lundin在评论中所说,如果您有一个不错的调试器,则可以在硬故障处理程序中放置一个断点,并使调试器向您显示完整的调用堆栈。 But if not, you'll have to do it the hard way. 但是,如果没有,您将不得不采取艰难的方式。

When the CPU enters handler mode to service the exception, various registers are pushed to the active stack by the hardware, and the handler you've implemented fetches these out of the stack for you to inspect. 当CPU进入处理程序模式以服务于异常时,硬件会将各种寄存器压入活动堆栈,并且您已实现的处理程序会将这些寄存器从堆栈中取出来进行检查。 The first thing to look at is the contents of the stacked program counter (PC). 首先要看的是堆栈式程序计数器(PC)的内容。 Try to get its value in hexadecimal; 尝试以十六进制获取其值; you should then be able to relate this to the address of the instruction that generated the fault, by using the debugger. 然后,您应该能够使用调试器将其与生成故障的指令的地址相关联。

If the stacked PC address doesn't correspond to a sensible code address, then it's possible that another line of code attempted to branch to this nonsense address and that's what triggered the fault. 如果堆叠的PC地址与合理的代码地址不对应,则可能另一行代码试图分支到该无用地址,这就是引发故障的原因。 In this case you can get some information by looking at the stacked link register (LR) address - this should contain the value of the program counter from the last time the CPU encountered a call instruction. 在这种情况下,您可以通过查看堆栈的链接寄存器(LR)地址来获取一些信息-该地址应包含自CPU上次遇到调用指令以来的程序计数器值。 This might not correspond exactly to the line that generated the rogue branch, but it should get you close enough to place another breakpoint and step through until the exception occurs. 这可能与生成流氓分支的行不完全对应,但是它应该使您足够接近以放置另一个断点并逐步执行,直到发生异常为止。

I am happy to edit this answer with further suggestions if these don't get you to the point of finding the culprit - just leave a comment and I'll get back to you. 如果您无法找到问题的根源,我很乐意编辑此答案并提供其他建议-留下评论,我会尽快回复您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM