加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

发现FreeRTOS的Tickless模式隐含Bug(2018.5.22)

(2018-05-23 12:24:29)
标签:

it

分类: 日常开发记录
    近日开发NRF52832的项目时,发现FreeRTOS使用Tickless模式存在一个隐含问题,即在线程中调用vTaskDelay时候存在一定概率延时到达时也不能从其中返回。

    具体调试过程如下:

    该问题直接体现:
    NRF52832通过串口打印调试信息,当调试信息输出频率很高,运行一段时间之后会出现停止打印的情况。但是程序总体运行没有其他异常。
    
    对该问题进行如下分析和调试:
    (1)怀疑串口模块出现溢出之类错误:
    通过在各种报错回调位置设置断点,并未在出现异常时候停下。

    (2)怀疑专门用于打印错误信息的Debug_out线程出现逻辑问题导致死循环,或者卡死在某个等待操作系统事件位置:
    出现异常后,在线程各部分尝试打断点,皆未停下,且没有继续调用串口发送函数。可认定并未在线程内发生死循环,并非串口发送引起的Bug,卡死或者挂起位置应该在所调用函数内。

    (3)用全局变量作为记录,在线程各地方打入不同的值,通过卡死时候该变量的值,确定最终卡死位置。
    经过实际操作,得到卡死位置在HW_UART_Open函数,如图。http://s3/mw690/002VF2gAzy7kGwFrhyac2&690

    而该函数内部比较简单,没有复杂逻辑,调用的官方库的函数也非常简单基本不存在卡死可能。唯一可能只有vTaskDelay。但感觉概率极低。故再用全局变量方式进行一次调试。如图。
    最终确定了卡死的位置就在于vTaskDelay(10)这个函数上。但这个应该是系统一个非常基础功能,直接出问题可能性应该很低。故继续进行如下推测:

http://s10/mw690/002VF2gAzy7kGwFwHHP59&690

    (4)怀疑是CPU负荷过大,该线程优先级太低导致
    用内部自己编写的模块查看了实时CPU使用情况(即cpu_usage,0.1%分辨率),CPU使用率基本在1%。不过该线程优先级仅为2(最大为8),确实较低。但如此CPU负荷下应该不存在该问题。
    调高优先级到6之后,问题依然存在,故基本可认为是操作系统自身存在问题。有可能是移植和配置上的,也可能是其本身问题。

http://s12/mw690/002VF2gAzy7kGwFMOP9bb&690

    (5)怀疑是启用了Tickless模式导致
    Tickless模式是通过预先计算下一次唤醒的任务唤醒时间而在idle的时候直接定时到下一次任务唤醒才唤醒CPU进行处理,故不需要像通常操作系统每固定事件就唤醒并进行一次检查,非常适合用于控制功耗。但该模式也导致了调度控制算法的复杂性。
    这里尝试将Tickless模式关掉。
http://s1/mw690/002VF2gAzy7kGwFCj1Sa0&690
    
    重新编译下载程序后进行测试,该问题得到解决,运行30min未出现异常(之前大概2-5min)。
    由此可以知道Tickless模式存在该项问题,但具体是移植,配置,内核本身bug或者是用法问题还不清楚,暂时没有时间深入调试。
    但该问题确实比较坑,这里只是相对比较显著一次暴露。最可怕就是其隐含导致出现其他地方奇怪的问题就很难调试了。故在低功耗要求不太高的场景下,建议暂时先不使用该模式进行具体的开发。
   

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有