ucOS任务管理总结

任务管理数据结构:


 

任务管理的数据结构包括任务控制块,任务空闲链表和任务就绪链表,任务优先级指针表,任务堆栈等,是μC/OS-II内核的核心部分之一。 

任务控制块实体的声明如下:

   OS_TCB  OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS]

    OS_MAX_TASKS为最多的用户任务数,OS_N_SYS_TASKS为系统任务数,一般情况下为2 

任务优先级指针表

OS_TCB   *OSTCBPrioTbl[OS_LOWEST_PRIO + 1]

OS_LOWEST_PRIO为最低优先级的任务的优先级,因为低优先级的任务数值最大,而任务优先级是从0开始的,所以其实OS_LOWEST_PRIO + 1就是任务的数量。

数组OSTCBPrioTbl就具有最多任务数个元素,它的类型是指向任务控制块的指针

任务堆栈的定义:

#define  TASK_STK_SIZE                 512          

typedef unsigned int   OS_STK; 

OS_STK  TaskStk[OS_MAX_TASKS][TASK_STK_SIZE];

TASK_STK_SIZE是每个任务堆栈的大小,这里设置为512,根据具体的情况做移植时,可修改这个值。OS_MAX_TASKS是用户任务的数量。 


 任务控制块初始化 

 


         prio         被创建的任务的优先级

        ptos         任务堆栈栈顶的地址

        pbos         任务堆栈栈底的地址,如果是用OSTaskCreate()来创建的任务,那么是没有扩展功能的,不能进行堆栈检查,就不主要适用这个参数,这个参数可以传递为NULL

        id           任务的ID16位,取值范围是065535

stk_size     堆栈的大小

pext         任务控制块的扩展块的地址

        opt          其他的选项

返回值 : OS_ERR_NONE        成功调用

OS_ERR_TASK_NO_MORE_TCB     如果没有空闲的任务控制块

 

任务删除:

    当以其他任务的优先级作为参数的时候,OsTaskDel粗暴地删除了任务,这在某些情况下是有效的,但是却不是必须这么做。通知对方任务,告诉它要删除你了,请任务自己删除自己是一种更好的做法。因为这么做,任务可以在删除自己之前先放弃自己使用的资源,如缓冲区、信号量、邮箱、队列等。如果总是用OsTaskDel删除一个任务,这个任务占用的资源不能得到释放,系统就会产生内存泄漏,在内存泄漏累积到比较大的时候最后,系统就会因为没有可用的内存崩溃。

    OsTaskDelReq名称虽然是请求,却是集请求和响应于一段代码的。该代码的功能是:

  1.请求删除某任务         2.查看是否有任务要删除自己

任务调度器:


 

μC/OS-II是基于优先级调度的实时操作系统,因此在启动多任务以后,每个时钟中断,都要执行任务的调度。如果时间片是20毫秒,那么在每20毫秒,执行一次任务调度。这个任务调度的函数就是OSTimeTick.

 

空闲任务:

 空闲任务是μC/OS-II 的系统任务,因为它占据了最低优先级63,所以只有在其他的任务都因为等待事件的发生而被阻塞的时候才能得到运行 

从空闲任务的代码可见,空闲任务除了不停地将空闲计数器OSIdleCtr的值加1之外,几乎什么都没有做。当没有任何其他任务能够运行的时候,操作系统就会执行这段代码。而OSTaskIdleHook默认的情况下也只是一个空函数,没有特殊需要我们也不需要去填写它,该函数的另一作用就是占据一点时间,给系统足够的时间响应中断。接下来我们来研究一下比空闲任务优先级仅仅高于空闲任务的另一重要系统任务,统计任务。


μC/OS-II规定,一个用户应用程序必须使用这个空闲任务,而且这个任务是不能用软件来删除的 

 

统计任务

OS_TaskStat是μC/OS-II的另一个重要的系统任务,我们可以通过宏设置取消统计任务,但一般情况下我们不会这么做,因为统计任务执行的统计工作是比较重要的。统计任务的主要功能就是计算CPU的利用率。如果没有统计任务,我们就不可知道多任务环境下系统的运行情况是否良好。

μC/OS-II提供的另一个系统任务是统计任务OSTaskStat( )。这个统计任务每秒计算一次CPU在单位时间内被使用的时间,并把计算结果以百分比的形式存放在变量OSCPUsage中,以便应用程序通过访问它来了解CPU的利用率,所以这个系统任务OSTaskStat( )叫做统计任务 

 

用户任务:    


 

固定地,系统总是把最低优先级别OS_LOWEST_PRIO自动赋给空闲任务。如果应用程序中还使用了统计任务,系统则会把优先级别OS_LOWEST_PRIO-1自动赋给统计任务,因此用户任务可以使用的优先级别是:0,1,2…OS_LOWEST_PRIO-2,共OS_LOWEST_PRIO-1个 

 

任务创建:

void main(void)

{ ……

OSInit( ); //对μC/OS-II进行初始化

……

OSTaskCreate (TaskStart,……);//创建任务TaskStart

OSStart( ); //开始多任务调度

void TaskStart(void*pdata)

{

……//在这个位置安装并启动μC/OS-II的时钟

OSStatInit( ); //初始化统计任务

……//在这个位置创建其他任务

for(;;)

{

起始任务TaskStart的代码

}


 

任务切换:

处理器通过两个指针寄存器(PC和SP)来与任务代码和任务堆栈建立联系并运行它。

系统是通过把待运行程序的地址赋予程序计数器PC来实现程序的切换的

其实,程序切换的关键是把程序的私有堆栈指针赋予处理器的堆栈指针SP。 

实质上系统是通过SP的切换来实现程序的切换的。

要建立一个概念:具有控制块的程序才是一个可以被系统所运行的任务。程序代码、私有堆栈、任务控制块是任务的三要件。任务控制块提供了运行环 境的存储位置。

    多任务操作系统的核心工作就是任务调度。

    所谓调度,就是通过一个算法在多个任务中确定该运行的任务,做这项工作的函数就叫做调度器。

    μC/OS_II进行任务调度的思想是 近似地每时每刻总是让优先级最高的就绪任务处于运行状态” 。为了保证这一点,它在系统或用户任务调用系统函数及执行中断服务程序结束时总是调用调度器,来确定应该运行的任务并运行它 。

任务调度的依据就是任务就绪表,

 

不要企图用PUSH和POP指令来使程序计数器PC压栈和出栈,因为没有这样的指令。只好变通一下了。中断动作和过程调用指令可以使PC压栈;中断返回指令可以使PC出栈。

因此任务切换OSCtxSw( )必定是一个中断服务程序。

    需要由宏OS_TASK_SW( ) 来引发一次中断或者一次调用来使 OSCtxSw( ) 执行任务切换工作

 


优先级继承机制:

优先级继承机制对优先级升级的机制以优化系统的调度。例如当前的任务的优先级是比较低的,如优先级为50。优先级为3的任务请求互斥信号量的时候因为信号量已被占有所以只有阻塞。这时有优先级为20的任务就绪,而不请求该互斥信号量。因此优先级为20的任务会先运行。如果又有优先级为30、40的任务运行,那么优先级为50的任务总也得不到运行也就不能释放信号量,更可怕的是优先级为3的任务还在苦苦等待信号量。这样,就发生了优先级反转。代码中的解决办法为将占有信号量的任务的优先级提高,例如提高为2,这样保证他对互斥资源处理完成,释放资源后又恢复他本来的优先级50,优先级为3的任务就不需要等待优先为20、30、40的那些中等优先级任务的运行了,纠正了优先级反转! 

 

移植ucOS需要满足的条件:



 详细内容: http://note.youdao.com/share/?id=5552e547025dfa2953ce22d244fec058&type=note


转载于:https://www.cnblogs.com/markmin214/archive/2013/03/25/2987976.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值