ucos-ii系统的timer(timer out)机制设计不知道是否合理,与rtk实时操作系统的比较感觉ucos-ii timer处理并不是很合理。
ucos-ii的timer队列并不是有专门的定时器来递减,而是每个task都有一个timer队列,而每个个task的timer 队列只有当自己所属的task空闲的时候,才会去处理。
ucos-ii 的timer添加,想其它的实时内核一样,要添加一个timer的时候,会先判断当前task的timer队列里是否为空,为空就直接添加,不为空:
如果要添加的timer比队列里的第一个timer大,就减去第一个后再比较,直到找到自己的位置,这个时候当前添加的timer值,加上队列前面的所有timer值的和,为要添加的timer的初始值。小的过程按同理来处理。
添加完了timer之后ucos-ii并没有专门的函数来处理这个队列,而是在当前task等待消息(信号量,mailbox之类)的时候,会将timer队列里的成员从前到后,一个一个的timer值,写入到当前task的TCB->OSTCBDly里面,而这个值是直接被system tick终端来递减的。TCB->OSTCBDly值有两个作用,直接delay task, 或者等待事件发生。timer用在后者中。
当task回复运行的时候有两种可能:
1. task等到evnet了,这个时候timer的时间还没有到,然后就直接用timer值减去等待的时间,再写入timer中。
2. 时间到了但是没有等到event事件,这个时候timer值为零了,因为当task TCB->OSTCBDly为零时会发生调度。 这个时候timer列表的第一个值到了,然后调用timer回调函数。但是event事件我们还是要等到的,不然就被timer值给扰乱了,所以这个时候又会回去,用timer列表的原来的第二个(原来的第一个已经用掉了),并且继续等待event事件的发生。
ucos-ii这样的timer机制其实会导致误差的,并且一旦task down掉,依赖于task的timer就无法继续了,如果这个timer是定时必须要做的,那么可能整个系统都会挂了。不知道这么理解的对不对?
ucos-ii系统的信号量机制:
信号量,event,资源计数其实都是可以用event来实现的:
typedef struct os_event {} OS_EVENT;
后两个变量就是与对应的任务调度表对应的。
第一个记录的是这个结构体记录的消息类型,有可能是flag,mailbox,mutex,queue,sem。
第二个一般为传递的消息。
第三个,是根据不同的类型的消息设置不同,比如mutex(互斥信号量)设置为1,用的时候+1,不用减1。 记录公共资源的使用数,这个可以为>0的数。 设置为0,一般是表示某个事件放生了。
最后一个变量记录的是等待当前event事件发生的tasks,当事件发生的时候(OSSemPost()),会先将当前event等待task里找到优先级最高的放入系统的任务就绪表里面,然后从evnet的这个变量中删除等待的task。 其它的等待task 怎么办??????
信号量使用的函数如下:
分配的时候用OSSemCreate(),
等待用OSSemPend(), 发生调度。--------将当前task从任务就绪表中取出来,然后将其放入evnet结构体的最后一个变量中,也就是放入等待这个event事件发生的队列当中。
通知用OSSemPost(),发生调度