如何灵活运用keil工具进行问题分析(1)— 解决日常程序卡死问题

前言

(1)如果有嵌入式企业需要招聘湖南区域日常实习生,任何区域的暑假Linux驱动实习岗位,可C站直接私聊,或者邮件:zhangyixu02@gmail.com,此消息至2025年1月1日前均有效
(2)最近看到很多网友询问一个问题,在开发程序的时候,遇到一些bug就卡死了,然后就不知所措了。反复看到他们问类似的问题,而我最近又学习了韦东山老师的栈回溯相关的知识,因此做一个分享。
(3)这里需要注意一点,韦东山老师的方法个人认为太原始,门槛太高了。Keil其实已经集成了相关的操作,但是韦东山老师却硬要手动回溯代码。为了让debug更加的方便和入门,我在此将会结合keil工具来进行讲解。

keil配置

(1)TARMSTM.DLL
pSTM32F103C8这里选择你的芯片型号

在这里插入图片描述

(2)然后是Debug的一些窗口,按照这个教程打开如下四个窗口:
C站:KEIL5中Debug调试

在这里插入图片描述

debug过程

查看当前卡死位置

(1)首先程序全速跑,复现一次bug,然后停止调试。之后在上方的Disassembly中右键,点击图中所示信息。

在这里插入图片描述

(2)看一下左侧的RegistersPC指针,看一下当前是卡死在哪个位置。

在这里插入图片描述

(3)最终发现是卡死在portmacro.h文件中的vPortRaiseBASEPRI()函数,portmacro.h不是我们编写的程序,所以似乎这并不是有效的信息。

在这里插入图片描述

查看调用卡死函数的位置

(1)一般程序卡死,大概率不是卡死位置出现故障,很可能是函数A在调用卡死函数B时候,存在错误操作。因此,此时我们就需要看LR寄存器。LR寄存器存放程序的返回地址,用通俗一点的话来说,就是我们C语言调用return的时候,就会根据LR寄存器进行跳转。
(2)通过LR寄存器我们可以发现,我们似乎是调用了xQueueGenericSend()函数,然后才导致的程序卡死。
(3)熟悉FreeRTOS的朋友应该很快就能够意识到问题所在,xQueueGenericSend()不就是一个队列函数吗?那么,我们是不是可以推断出,是哪个函数调用了队列函数,那么这个很可能就是问题所在。

在这里插入图片描述

栈回溯

(1)既然有了思路,那么我们就需要找到当前卡死时候,函数的调用关系,然后知道被调用函数中,哪个任务会调用和队列相关的函数。那个就说问题所在。
(2)这个时候就需要涉及到栈回溯的相关知识了,因为这部分知识有一定的门槛,所以我不会进行介绍。
(如果想要学习了解的,可以看看韦东山老师的90天RTOS双架构双系统项目实战班的5-1-8栈回溯原理
(3)程序卡死的时候,我们可以通过栈知道程序的调用关系。在KeilDebug工具中,有一个Call Stack的工具能够看到被调用过的函数。
(4)通过上面分析,我们知道程序vPortRaiseBASEPRI()xQueueGenericSend()这两个函数大概率不是问题所在,因为这两个是FreeRTOS官方源码,出错概率微乎其微。
(5)然后我们就可以看看HAL_GPIO_EXTI_Callback()函数,大概率是这个函数导致的bug。按照下图方式可以快速定位到HAL_GPIO_EXTI_Callback()函数位置。
(6)如果status = xQueueSendToFront(KeilQueueHandle, &Buf, 0);被顺利执行,那么就会跳转到if (status == pdTRUE)中,此时我们利用FreeRTOS的知识可以知道,中断中必须使用FromISR后缀的函数。因此,我们可以推断出问题是在这里了。

在这里插入图片描述

总结

(1)栈回溯的一个很好的技巧,我们应当了解和掌握.在一些大型项目中,很少使用keil开发,所以掌握栈回溯的原理非常重要。
(2)可是,因为他的门槛过高,所以我个人建议先从keil开始,熟悉栈回溯的使用,饭要一口一口的吃,步要一步一步的走。

参考

(1)C站:STM32 触发HardFault_Handler如何查找原因
(2)C站:hardfault问题分析解决及记一次ucosIII环境下的hardfault解决
(3)C站:KEIL5中Debug调试
(4)CM3权威指南

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风正豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值