Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1896240
  • 博文数量: 152
  • 博客积分: 3730
  • 博客等级: 上尉
  • 技术积分: 3710
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-02 14:36
个人简介

减肥,运动,学习,进步...

文章分类

全部博文(152)

文章存档

2016年(14)

2015年(17)

2014年(16)

2013年(4)

2012年(66)

2011年(35)

分类: LINUX

2012-05-08 10:56:15

最近对实时操作系统比较感兴趣,然后就仔细阅读了一番uC/OS-II的代码,之前也初略的阅读过,但是这次阅读确实有不少的收获。

uC/OS-II是经典的实时操作系统,开源的优点就是可以使用者自己去分析和裁剪。我就简单的说明一下uC/OS-II中的任务挂起以及任务唤醒操作。

在uC/OS-II中任务之间的切换比较简单,就是运行态-就绪态-挂起态(等待态)-中断服务态-睡眠态,其中睡眠态主要是指没有被创建的任务,也就是我们可以定义很多的任务,但是不一定全部创建,当然也可以是被删除以后的任务,我们也可以称之为睡眠态,这也是我们不经常使用的任务。其他的中断服务态实际上就是在中断服务中,他的运行级别是最高的。就绪态就是已经做好运行准备的状态,运行态永远只有一个任务处于运行态。而挂起态或者称等待态是最复杂的过程,其中牵涉到很多中不同的挂起状态。

几种典型的挂起态我做一下总结:

1、任务的挂起操作,一般都是采用OSTaskSuspend()将任务挂起,这种挂起的操作一般都是比较简单的将就绪表中优先级对应的位和组分别清除即可,而这种挂起的方式被唤醒的方式有且只有一种,即采用OSTaskResume()函数将就绪表中优先级对应的位和组就绪即可。这也应该说是最准确的挂起,而不是所谓的等待态。

2、任务中调用时间延迟函数的挂起方式,准确的说这种挂起就是等待态,我们所谓的延迟等待,基本的实现原理就是通过节拍服务函数OSTimeTick()减小延迟等待时间,这个实际上就是对任务控制块OS_TCB中的变量OSTCBDly操作而实现的。在OSTCBDly>0期间将任务在就绪表中的位和组分别清除,是任务处于挂起操作,这种挂起实质和任务的挂起方式相同。但是OSTimeTick()的实现过程会检测任务是否是被OSTaskSuspend()挂起,也就是真正的挂起态,只有当任务不是被OSTaskSuspend()挂起时才能被唤醒,这是需要注意的。

3、关于通信机制、同步过程中的任务挂起,这种任务挂起实质上是任务等待状态,实现的过程中会涉及到两个续表,其中一个就是任务就绪表,另一个是任务等待续表,另外为了实现等待超时等问题,将OSTCBDly也考虑了进来,这样也就使得这种任务的等待比之前的两种挂起方式要复杂。但是等待超时与等待延迟有一定的相似之处,但不同的地方就是需要将等待续表中对应的优先级位置清除,再设置就绪表中的位置位1,返回超时错误,这样就能实现超时的挂起操作,而一般的事件等待机制,都是涉及到中断、任务与任务之间的通信或者同步问题,挂起操作首先将任务在就绪表中的就绪标志位清除,同时设置任务的状态为某种形式的挂起,然后设置等待续表中的相关位置,最后实现任务的调度。任务的唤醒操作是另一个任务发出信号,然后从等待续表中清除最高优先级的任务,然后设置该任务在就绪表中的位置,并设置任务的状态,最后实现任务的调度操作。一行就能实现任务的挂起操作。

综合上面的总结可以知道uC/OS-II的任务挂起操作主要是3种,其中前两种相比而言比较简单,只是简单的依靠就绪表或者时间延迟变量即可实现。而当涉及到任务的同步等机制时就会依靠就绪表,等待续表,以及时间延迟变量。但是任务的挂起和睡眠本质上也是存在差别的,并不是同一种概念,因此我们在学下uC/OS-II的过程中需要特别注意。

阅读(3565) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~