说到嵌入式系统一般能想到的都些是RTOS,比如特别出名的FreeRTOS,ucOs,Keil自带的RTX,ARM的mbed OS,如果是硬件资源比较少,又想获得多线程解耦的便利,还有一些协作式系统可以选择,如Contiki OS(protothread),阿圆在此推荐一种设计也非常精致小巧的OS,就是今天要说的时间触发系统。
时间触发系统的优点在哪里呢?
可预测性,所有任务在启动后都按时间片进行执行,不像抢占式系统,任务在启动后何时运行,不可预知
可移植性,时间触发系统只需要一个定时器,其它数据结构均是系统无关,相比抢占系统必须使用汇编来说,自己实现一个也是丰常容易的
可靠性,源自于其简单的实现,线程间几乎没有竟态的产生
足够强大,阿圆见到过的时间触发系统在加入消息队列,链接等系统常用的资源后,也非常好用。
这里有一点需要注意,大家可能认为抢占时系统在对应中断时会更加容易保证中断的处理,而时间触发系统则做不到。事实不然,如果一个系统有多个中断时,不论抢占式系统还是时间触发系统都有可能丢失中断(比如串口实现,即使使用较大内存并以DMA进行接收,仍然有可能有以太网驱动占用过多中断,而导致串口数据的丢失),就这一点时间触发系统和抢占式系统并无二致。如果是数据发送的情况下,同样使用中断发送或DMA发送,时间触发系统和抢占式系统也并无太大区别。
一个可能的区别点就是任务的优先级实现,在时间触发系统里,其实可以通过高优先级定时器来轮询高优先级任务,当然做起来没有抢占式那么优秀。
当然,时间触发系统一个很大的问题就是任务漂移,可能导致任务执行的效率变低。
好的,大概了解了时间触发系统,那么时间触发系统是怎么一回事?
首先来看下Task的定义
稍微解释一下,
TaskCtrl在时间触发系统里是一个全局的数组,因为任务可以添加或删除,所以会有一个isUsed标记,
任务是否在运行也有一个isRun标记,
isReady标记指示超时时间是否己经到达,是否需要执行
isPeriod是否是一次性的任务,还是需要周期性执行
taskProc则是需要任务的主体函数
一个简单的任务就定义好了~ 那么接下来就需要有一个调度器(scheduler)
说到调度器,其实就是一个定时器中断,在定时器中断里不断地检测是否有任务达到需要运行的时间点,没有的话就给任务的定时计数加上定时器时间。
而任务的最终执行则是在main的while(1)中实现的,示例如下
这样一个基本的时间触发系统的内核就有了,不过这样还不够好用,因为我们还没有实现任务间的通信,所以要加入比如MessageQueue或者MailBox这样的数据结构用以任务和任务之间的通信。
不过呢,这是属于数据结构的应用,阿圆今天就不多讲。
对于任务的管理,相应的也要实现CreateTas,StartTask,StopTask,DeleteTask等一系列的函数就可以了,大家可以自己动手试试。
这里需要注意的几点
上面的TaskCtrl需要加一个delay参数,如果都在同一时间启动任务的话,可能在执行第二个任务时第一个任务又要执行了,这样就产生了任务漂移,设计时就需要将任务错开,需要精心设计
每个Task都是不能阻塞的,事实上其于状态面的任务设计很有必要
如果需要系统稳定,可以加入看门狗任务,如果一个任务阻塞超时可以对系统进行复位
关于时间触发系统,推荐大家继续阅读《时间触发嵌入式系统设计模式》一书。
今天就简单分享这么多吧~
PS:阿圆的电脑显卡挂了,分辨率只有640*480,图片有点问题,体谅下啦~
本文暂时没有评论,来添加一个吧(●'◡'●)