Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1644965
  • 博文数量: 245
  • 博客积分: 10378
  • 博客等级: 上将
  • 技术积分: 2571
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-27 08:19
文章分类

全部博文(245)

文章存档

2013年(4)

2012年(8)

2011年(13)

2010年(68)

2009年(152)

分类: C/C++

2009-09-16 15:05:33

 

uc/os的任务管理

        uc/os每个任务被赋予不同的优先级等级,从0级到最低优先级OS_LOWEST_PRIO,包括0OS_LOWEST_PRIO在内, uc/os总是在已经就绪的任务中选择一个任务来运行,为了了解那些任务出于就绪状态,uc/os在系统初始化的时候创建了一个供就绪任务登记的表,即就绪任务表。就绪任务表实际上为一个类型为INT8U的数组OSRdyTbl[],由 于每个任务在此数组中只占一位,所以数组的每一个元素可以表达8个任务的就绪状态。为了便于对就绪表的查找,uc/os又定义了一个数组类型为INT8的 OSRdyGrp,并使该数组的每一位都对应OSRdyTbl[]的一个任务组。在OSRdyGrp中,任务按优先级分组,8个任务为一组。OSRdyGrp中的每一位表示8组任务中每一组中是否有进入就绪态的任务。例如OSRdyGrp=1100101,哪么意味着OSRdyTbl[0],OSRdyTbl[2],OSRdyTbl[6],OSRdyTbl[7]任务组中有任务就绪。

       由于优先级是一个单字节的数字,且其最大值不超过63,因此可以把优先级看做是一个6位的二进制数,这样子可以用高三位表示OSRdyGrp的具体数据位,用低三位表示数组元素OSRdyTcl的具体数据位。

     对于任务就绪表的操作主要有两项:添加,删除。

在任务就绪表中登记就绪任务的代码为:

OSRdyGrp |= OSMapTbl[prio >> 3];

OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07];

从任务就绪表中删除任务的代码为:

if ((OSRdyTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0)

OSRdyGrp &= ~OSMapTbl[prio >> 3];

T3.1 OSMapTbl[]的值

Index

Bit Mask (Binary)

0

00000001

1

00000010

2

00000100

3

00001000

4

00010000

5

00100000

6

01000000

7

10000000

从就绪表中获得任务优先级最高的任务的方法为:

y    = OSUnMapTbl[OSRdyGrp];

x    = OSUnMapTbl[OSRdyTbl[y]];

prio = (y << 3) + x;  

具 体使用时需要查找一个16*16的OSUnMapTbl[]数组,OSUnMapTbl的设计思想为:表示人物的OSRdyGrp为一个8位的二进制数, 从这个数的最低位到最高位查找,碰到第一个为1的位所对应的任务就绪组一定是最高优先级任务所在的组,所以它的组号一定是优先级最高的就绪任务的级别。

2.任务的创建:

1 OSTaskCreate()
   
建立一个新任务。任务的建立可以在多任务环境启动之前,也可以在正在运行的任务中建立。中断处理程序中不能建立任务。一个任务可以为无限循环的结构。
函数原型:INT8U OSTaskCreate(void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio);
参数说明:task 是指向任务代码首地址的指针。
         pdata
指向一个数据结构,该结构用来在建立任务时向任务传递参数。
         ptos
指向堆栈顶端的指针

          Prio 任务的优先级

返回值:
OSTaskCreate()
的返回值为下述之一:
* OS_NO_ERR
:函数调用成功。
* OS_PRIO_EXIST
:具有该优先级的任务已经存在。
* OS_PRIO_INVALID
:参数指定的优先级大于OS_LOWEST_PRIO
* OS_NO_MORE_TCB
:系统中没有OS_TCB可以分配给任务了。

2 OSTaskSuspend()
   
无条件挂起一个任务。调用此函数的任务也可以传递参数 OS_PRIO_SELF,挂起调用任务本身。当前任务挂起后,只有其他任务才能唤醒被挂起的任务。任务挂起后,系统会重新进行任务调度,运行下一个优先级最高的就绪任务。唤醒挂起任务需要调用函数OSTaskResume()
   
任务的挂起是可以叠加到其他操作上的。例如,任务被挂起时正在进行延时操作,那么任务的唤醒就需要两个条件:延时的结束以及其他任务的唤醒操作。又如,任务被挂起时正在等待信号量,当任务从信号量的等待对列中清除后也不能立即运行,而必须等到被唤醒后。
函数原型:INT8U OSTaskSuspend(INT8U prio);
参数说明:prio为指定要获取挂起的任务优先级,也可以指定参数 OS_PRIO_SELF,挂起任务本身。此时,下一个优先级最高的就绪任务将运行。
返回值:
OSTaskSuspend()
的返回值为下述之一:
* OS_NO_ERR
:函数调用成功。
* OS_TASK_SUSPEND_IDLE
:试图挂起μC/OS-II中的空闲任务(Idle task)。
* OS_PRIO_INVALID
:参数指定的优先级大于 OS_LOWEST_PRIO 或没有设定 OS_PRIO_SELF 的值。
* OS_TASK_SUSPEND_PRIO
:要挂起的任务不存在。

3 OSTaskResume()
   
唤醒一个用 OSTaskSuspend() 函数挂起的任务。OSTaskResume() 也是唯一能解挂挂起任务的函数。
函数原型:INT8U OSTaskResume(INT8U prio);
参数说明:prio指定要唤醒任务的优先级。
返回值:
OSTaskResume()
的返回值为下述之一:
* OS_NO_ERR
:函数调用成功。
* OS_TASK_RESUME_PRIO
:要唤醒的任务不存在。
* OS_TASK_NOT_SUSPENDED
:要唤醒的任务不在挂起状态。
* OS_PRIO_INVALID
:参数指定的优先级大于或等于OS_LOWEST_PRIO

4.任务的优先级修改:

INT8U OSTaskChangePrio(INT8 oldprio,INT8 newprio);

5.任务查询:

INT8U OSTaskQuery(INT8U prio,OS_TCB *pdata);

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