uC/OS-II系统学习笔记(6)—— 任务管理

前言
已经写了5篇了,最大的感触还是啃源码太累了,以及很多无用无脑的话太多了。想想自己也不至于一些过于无脑的东西都需要看笔记才能理解。而且现在主要任务还是学会用ucos,所以在以后的笔记里还是先写系统的使用方法以及一些必要性的可能会忘的知识。至于源码解析,其实大部分还是能看懂八九分,在以后有时间会挑一些比较有意思有意义的源码看。另外就是有些篇幅过于冗长,但是毕竟前5章是打基础,所以写的还是比较仔细。以后的内容很多是为了回顾忘掉的东西,所以每一个知识点会进行碎片化来写。方便以后查阅。


1 建立任务

建立任务有两个函数。之前说过的,一个是OSTaskCreate(),一个是OSTaskCreateExt()。

INT8U OSTaskCreate (void    (*task)(void *pd), //任务函数指针
                    void    *pdata,            //任务传入的参数
                    OS_STK  *ptos              //指向任务堆栈栈顶的指针
                    INT8U   prio)              //任务优先级

以上为OSTaskCreate函数需要传入的参数。具体含义已经标明。比较重要的是第三个参数,任务堆栈指针。以下做详细介绍。

INT8U OSTaskCreateExt (void    (*task)(void *pd),
                       void    *pdata,
                       OS_STK  *ptos,
                       INT8U   prio,
                       INT16U  id,                 //一个特殊的标识符,在uC/OS-II里还没用处
                       OS_STK  *pbos,              //指向任务堆栈栈底的指针
                       INT32U  stk_size,           //任务栈的大小,注意单位是指针元数目,不是字节
                       void    *pext,              //指向用户附加的数据域指针,用来扩展OS_TCB
                       INT16U  opt)                //用来设定这个函数的一些选项

这个函数我目前也没用上过,比较值得注意的是*pext和opt两个参数。它们的作用一般都是起增强性的。比如*pext,使用户可以为每个任务增加一个名字之类的。而参数opt,是用于设定OSTaskCreateExt的选项的,在UCOS_II.H文件中有一个所有可能选项的常数表。每一个选项占有opt的一位,用户可以根据对应位的置位来完成这些操作。如下图即为opt的一些选项。

/*
***********************************************************************************************
*                            TASK OPTIONS (see OSTaskCreateExt())
***********************************************************************************************
*/
#define  OS_TASK_OPT_NONE          0x0000u  /* NO option selected                                      */
#define  OS_TASK_OPT_STK_CHK       0x0001u  /* Enable stack checking for the task                      */
#define  OS_TASK_OPT_STK_CLR       0x0002u  /* Clear the stack when the task is create                 */
#define  OS_TASK_OPT_SAVE_FP       0x0004u  /* Save the contents of any floating-point registers       */

2 任务堆栈

堆栈空间是可以在OSTaskCreate()申请的,比如:

OS_STK MyTaskStack[stack_size];
static OS_STK MyTaskStack[stack_size];

以上两种方式都是申请任务堆栈,区别在于一个是动态的,一个是静态的。在动态分配中,需要注意的是内存碎片的问题。当用户反复的建立或删除任务时,内存堆中可能会出现大量的内存碎片,导致没有足够大的一块连续区域用作任务堆栈。

所谓的内存碎片,如下图所示。有一个3K内存的存储空间,现在创建了任务A,B,C。之后删去用户A和C,虽然有2K的内存,但是若此时有一个任务需要2K的空间建立任务堆栈时,就不能够实现了。

这里写图片描述

另外,需要考虑堆栈的增长方向,是由下往上递增,还是由上往下递减。

OS_STK TaskStack[TASK_STACK_SIZE];

#if OS_STK_GROWTH == 0
OSTaskCreate(task, pdata, &TaskStack[0], prio);                   //递增
#else
OSTaskCreate(task, pdata, &TaskStack[TASK_STACK_SIZE-1], prio);   //递减
#endif

如上所示,OS_STK_GROWTH为0时,是由下往上递增,否则则为从上往下递减。

3 堆栈检验

用来检验堆栈的使用情况,可以大致的检查用了多少堆栈,有多少是多余的。个人感觉现阶段这个函数用处不算太多,因为这个需要用OSTaskCreateExt()来创立任务。通过调用函数OSTaskStkChk()可以完成堆栈的检验。

如果堆栈是递增的,那么检验就是从下往上查,直到查到剩余区域都是空的,那么那部分就是多余的堆栈。同理,堆栈递减的就是从上往下查。

4 删除任务

所谓的删除任务,即减少μCOS-Ⅱ的任务计数器。简单地将指向被删除的任务的OS_TCB的指针指向NULL,从而达到将OS_TCB从优先级表中移除的目的。因为任务管理都是通过OS_TCB任务控制块结构来控制的,这个结构体的指针指向0,这个任务就不再被系统理会了,达到了删除任务的目的。

注意一点,在任务删除之后,对应的任务堆栈也会被收回。但是等下一次想开启这个任务的时候不一定还有空间。这也是因为之前说的,多次的删除任务和重启任务可能会造成大量的内存碎片。所以,一般情况下任务堆栈还是采取静态声明。一个任务的堆栈空间就在那放着就好,不用的时候就空在那里。

5 改变任务的优先级

改变任务的优先级用的函数是OSTaskChangePrio()。uC/OS-II允许用户进行动态优先级的处理。函数的入口参数如下所示:

INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio)

可以看出传入的分别是旧的优先级以及需要改变到的优先级。因为uC/OS-II是不允许同优先级任务的,所以优先级可以定位到某一个任务,通过这两个参数就可以完成一个任务优先级的改变。

6 挂起任务

挂起任务用到的函数是OSTaskSuspend()。传入的参数只有一个任务优先级。任务可以挂起自己或者挂起其他任务。

任务挂起是一个附加功能,也就是说如果任务在挂起的同时也在等待延时的期满,那么挂起操作就会被取消。等到任务延时结束后,会进入就绪状态。

目前还不是很清楚,挂起任务的目的和意义是什么。

7 恢复任务

任务的挂起和恢复肯定是要成对使用的,不能把任务挂起来就挂着了。总要把任务恢复的。使用的是OSTaskResume()函数。

8 获得有关任务的信息

函数的入口参数是:

INT8U OSTaskQuery (INT8U prio, OS_TCB *pdata)

传入一个优先级以及指向任务控制块结构体的指针。

这个函数会返回一个INT8U类型的返回值。如果任务无错,会返回OS_NO_ERR,如果传入的优先级非法,即优先级比最低优先级还要低,就会返回OS_PRIO_INVALID,如果传入的优先级对应任务在任务表,也就是OSTCBPrioTbl[prio]是一个空指针,那么就返回OS_PRIO_ERR。如果都是合法正确的,除了返回OS_NO_ERR之外,传入的指针pdata也会指向这个优先级的任务控制块结构体。这就获得了其任务信息。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值