嵌入式开发-如何快速定位到系统卡死的位置

     “靠,死机了”,在周遭满是噼噼啪啪的键盘声中,一声突兀的嚎叫响起。然后便是一阵手忙脚乱的各种log添加、代码查看、问题复现。这场景想想都觉得小心脏慌慌的。那么有什么办法能让我们遇到这种情况能稍微优雅一点,不至于发出杀猪般的嚎叫呢?这就是接下来要介绍的一个小方法。

    实际项目开发过程系统卡死某个位置情况分为两种一种系统访问到非法地址一种系统卡死某个while循环中

系统访问到非法地址:

系统访问非法地址一般都会执行HardFault()硬件错误处理函数芯片厂家都会提供相应读取寄存器方法然后根据寄存器就能知道系统哪个位置访问到了非法地址然而位置不一定导致死机真正位置针对问题查看文章嵌入式开发-死机位置在第三方库的问题原因定位

系统卡死在某个while循环中:

当系统出现内存地址非法访问时,系统通常会执行HardFault()函数以记录内存非法访问前相关的变量。那么当系统在while循环中卡死时,我们是否也可以记录系统卡死前的位置及相关变量信息呢?答案是肯定的。当系统在while循环中卡死时,系统的RAM、定时器、中断等部件仍然正常工作。因此,我们可以定义全局变量并在需要的地方将代码行号、变量记录到定义的全局变量中,以便在系统出现卡死时读取。所以,我们需要解决两个问题:一是在何处监听代码,二是在系统卡死时如何获取记录的信息。

在何处监听代码

何处监听代码主要颗粒度问题理想情况肯定所有while循环出现地方添加,但是明显加重我们开发负担因此我们可以考虑每个模块执行函数入口出口添加具体实现方式如下

DEBUG_CHK_LINE()实现方式如下

代码监听我们主要记录文件行号如果需要也可以记录需要监听变量

系统卡死时如何获取监听信息

鉴于系统持续记录代码执行位置及相关变量信息,我们的主要挑战在于判断系统是否陷入死循环。因此,我们可以通过设定一个定时器周期中断并累加时间,当累加时间超过预设阈值TIME_OUT时,将所记录信息打印出来。接口实现方式如下

为了实现时间累加DEBUG_CHK_LINE_TIMER_INT(TIME_OUT) 需要定时器中断回调函数执行并在代码监听接口DEBUG_CHK_LINE()内实现累加时间清除

通过上述方式添加监听接口后,当系统在while循环中出现卡死现象时,系统将定期打印相关信息。我们可以通过这些信息迅速定位导致卡死的模块。若无法直接通过查看卡死函数func()来确定具体位置,可以在func()函数内部继续添加监听接口DEBUG_CHK_LINE()并复现问题。

然而,在某些情况下,系统可能会在while循环中卡死,但这并不是while循环本身代码的问题,而是由于外部模块发生了内存越界访问,从而篡改了while循环代码导致的。在这种情况下,可以结合文章嵌入式开发-死机位置在第三方库的问题原因定位的方法来定位问题。

期望本方法能帮助大家在遭遇系统卡死状况时,不必发出无助的哀嚎。

  • 43
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值