都说软件定时器的有点很多,网上流传了很多,尤其是github上面的,公众号上面也有推荐。比较多的是multitimer和smarttimer,安富莱也模板,和文档说明,详细可以去参考他的文档。
这里就深入分析下软件定时器的运行机制,深入理解下。
普通的裸机程序中,基本上是硬件定时器里面计时,设标志位,主程序根据标志位来执行子程序,基本上没有死等的延时。如果处理的任务比较的情况下,就需要很多的标志位。管理起来稍稍有点复杂,就需要设计比较好、可维护性高的数据结构。
而软件定时器是定义一个软件定时器的结构体,结构体里有回调函数,定时时间到,且可以运行,则调用回调函数来执行,维护性相对比较高的。这也是他的优点。
但是软件定时器也有其局限性吧。
首先理一理他的原理,项目中注册了3个软件定时器,在systick中断中会每隔1ms递减每个软件定时器的计时tick,主程序就是不断的轮训检查各个软件定时器定时是否到,是否可以执行,如果可以执行,就执行回调函数。其实挺像上面的定时标志位的模式。
注意systick的中断每1ms都会来,rtos中的systick也是如此,那么主程序每隔1ms都会被中断一次,中断的频率还是比较高的,因此在没写时序性比较高的驱动当中,就不太适合使用软件定时器的框架,因为即使快进快出,中断的处理还是需要时间的。
其实本质上来讲,这中软件定就是封装了一层数据结构,框架和普通的定时器+标志位是一模一样的,只不过普通的是计数器往上加,到了就执行任务,软件定时器是计数值减到0,就执行任务。因此区别在于定时器的频率大小。
两者都属于裸机的框架,另外就是回调函数的执行时间必须小于执行周期的50%,执行时间10ms,定时时长最好是20ms执行一次,不然其他任务会出行卡顿的现象。也就是说子程序如果执行时间比较长,那么有必要把定时周期加长,前提是项目的实时性不是很高。像按键扫描,仅仅是判断高低电平,那么执行速度相当快了,20ms完全没问题,而PID执行涉及到浮点数,可以1s执行一次,恰好1s的时间间隔是完全能接受的,不会影响温控效果,如果是飞控的pid,那么需要加快计算频率。
最后,本质上讲,软件定时器和定时器+标志位的方式没有任何区别,只是数据结构上包装了一层,易于维护而已,定时器频率有区别而已,达不到多任务的效果,真正的实时性还是需要上rtos的。