nRF52832 定时器REPEATED模式,导致异常重启的问题排查全过程

一、遇到问题

  • nRF52832项目增加一个功能,自测没问题就发出去了。
  • 结果300台机器,有7台出现异常,无法正常使用。
  • 细看了一遍提价上去的git代码,没发现问题点在哪。
  • 再自测了一遍,手边的机器,依旧没问题。

二、JLink连接时,无法复现

  • 提了一台有问题的机器拿回工位,发现了很有意思的现象。
  • 插上JLink,打开JLinkRTTViewer就正常使用,无异常。
  • 一旦,断开JLinkRTTViewer连接,或者物理拔掉JLink连接。机器不出10秒,就异常重启。

三、查看日志

  • 最后想了个办法,出现重启之后,马上打开JLinkRTTViewer连接。
  • 会把最近的日志吐出来,然后得到如下日志。
  • 但是,日志没有有效信息。增加了更多日志后细细debug后,还是无果,没有规律,莫名其妙就重启了。
  • keil在线调试也无法复现问题。

在这里插入图片描述

四、回退改动

  • 只能一点一点回退改动,这次改的还比较多,折腾了周末一整天时间。
  • 终于在最不可能的地方,发现了问题。
  • 定时器创建,APP_TIMER_MODE_REPEATED,导致系统异常重启。
app_timer_create(&m_sleep_timer_id,APP_TIMER_MODE_REPEATED,m_sleep_timeout);
app_timer_start(m_sleep_timer_id,APP_TIMER_TICKS(10000,0), NULL);

五、解决问题

原本改动:

  • APP_TIMER_MODE_REPEATED重复模式创建timer,然后马上就启动。
  • 新功能则在m_sleep_timeout定时器回调函数中执行。
  • 这个改动就导致2.3%的机器异常重启,且打开JLink连接不会重启。
  • 简直离谱!!!

我的修改:

  • APP_TIMER_MODE_REPEATED改成APP_TIMER_MODE_SINGLE_SHOT单次模式。
  • m_sleep_timeout函数中,先stop再start定时器。
  • 问题解决!!!简直离谱!!!
void m_sleep_timeout(void * p_context)
{
    
    
	app_timer_stop(m_sleep_timer_id);
	app_timer_start(m_sleep_timer_id,APP_TIMER_TICKS(10000,0), NULL);

	// xxxx 功能代码
}

六、问题剖析

  • 这个真的是奇葩问题,应该是nRF SDK的bug。
  • 也许可能是定时器不断回调中某个数值溢出了,导致重启。
  • 至于为何JLink连接的时候,就不会重启,就搞不懂了。

觉得好,就一键三连呗(点赞+收藏+关注)

猜你喜欢

转载自blog.csdn.net/kangweijian/article/details/130798809