硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3347|回复: 2
收起左侧

[μCOS-III] uCOSIII3.08动态tick进入HardFault问题解决

[复制链接]

76

主题

237

回帖

465

积分

高级会员

积分
465
发表于 2021-6-7 12:19:43 | 显示全部楼层 |阅读模式
本帖最后由 kokoromi 于 2021-6-9 09:48 编辑

经过多次测试,发现使用传统定时器作为动态tick定时器,无论串口通讯速度多快,都没有任何问题,CPU占用率也正常;
但是,使用LPTIM低功耗定时器作为动态tick定时器,串口通讯频率提高后,频繁进入HardFault异常,CPU占用率比正常高20%左右(实际没这么高,统计任务统计有误,原因不明),经过几天的查找,没找到原因,不想因为这个占用太久时间,所以放弃该方案,使用传统定时器解决。如果有哪位大佬用到了LPTIM,可以关注一下这个问题。

---------------------------------------------------------------------------------------------------------------------

经过N轮调试,终于找到问题所在,我之前用的是HAL库函数,而停止定时器的库函数HAL_LPTIM_Counter_Stop()里面用了定时器禁止语句__HAL_LPTIM_DISABLE(hlptim)。问题就出在这一句。把这句话删除,问题就解决了。我查看了STM32L010C6的勘误手册,并没有说明LPTIM的相关内容。为什么频繁调用__HAL_LPTIM_DISABLE(hlptim)会进入HardFault异常不得而知。
  1. OS_TICK OS_DynTickSet(OS_TICK ticks)
  2. {
  3.   CPU_INT32U tmrcnt;

  4.   tmrcnt = OSTICK_TO_TIMER(ticks);

  5.   if((tmrcnt >= TIMER_COUNT_MAX) || (tmrcnt == 0u))  //如果延迟超过计数器的容量,或者内核需要无限延迟
  6.   {
  7.     tmrcnt = TIMER_COUNT_MAX;                        //尽可能多地记录节拍(最大计数值)
  8.   }

  9.   TickDelta = TIMER_TO_OSTICK(tmrcnt);               //将计数器计数转换为节拍

  10.   HAL_LPTIM_Counter_Stop(&hTIM);                     //停止计数(删除其中的__HAL_LPTIM_DISABLE(hlptim),否则会进入HardFault异常)
  11.   HAL_LPTIM_Counter_Start(&hTIM, tmrcnt);            //重新计数(其中的__HAL_LPTIM_ENABLE(hlptim)是否删除无影响)

  12.   return (TickDelta);                                //返回下次中断之前经过的节拍数
  13. }
复制代码



仔细观察了HAL库函数HAL_LPTIM_Counter_Start()和HAL_LPTIM_Counter_Stop(),里面开启和关闭定时器都用了__HAL_LPTIM_ENABLE(hlptim)和__HAL_LPTIM_DISABLE(hlptim),其实没有必要,因为LPTIM的启动是需要额外的语句来实现的(__HAL_LPTIM_START_CONTINUOUS(hlptim)或__HAL_LPTIM_START_SINGLE(hlptim)),所以,只需要在系统节拍初始化(void OS_SysTickInit())或者系统节拍启动(void OS_SysTickEnable())中使用一次__HAL_LPTIM_ENABLE(hlptim)开启定时器即可,后续通过__HAL_LPTIM_START_SINGLE(hlptim)来启动计数,计数完毕自动停止。

另外想吐槽下这个LPTIM,既然主打低功耗,为什么LSI是个37k这种不伦不类的频率,毕竟这个定时器不能像其他通用定时器那样可以设置任意分频数。个人感觉应该是32k,如果32k的频率,再进行32分频,正好是1000的频率,和系统Tick一致,这样最长可实现1分多钟的延迟,减少了因为溢出唤醒造成的功耗损失,再一个,LPTIM为什么不搞成32位的,这样可以让这个定时器每隔49天从停止模式唤醒一次,不是更香嘛,现在这样不伦不类的,不像一个低功耗定时器该有的样子。



回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2021-6-7 16:09:08 | 显示全部楼层
当前uCOS的统计都是基于DWT时钟周期计数器,应该是这个没有正常工作。
回复

使用道具 举报

76

主题

237

回帖

465

积分

高级会员

积分
465
 楼主| 发表于 2021-6-7 19:49:13 | 显示全部楼层
eric2013 发表于 2021-6-7 16:09
当前uCOS的统计都是基于DWT时钟周期计数器,应该是这个没有正常工作。

我看了下,每个任务的CPU占用确实用DWT,但是总的CPU占用用的是空闲任务里的那个计数值,那个统计任务做了三项工作,第一个是计算总的CPU占用,第二是计算每个任务的CPU占用和任务栈使用率,最后是计算中断(ISR)的栈使用率。
我上周把程序简化到连空闲任务都删除了,只留了一个串口接收中断函数,里面只是读了下DR。然后用串口助手快速发送数据时,还是会进入硬错误异常,确定是LPTIM的问题(普通定时器没问题),等我腾出时间找到原因了再来发帖说明
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-15 17:38 , Processed in 0.149439 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表