ucos ii学习笔记(1):任务Task

1 综述

在ucos ii中我们使用task来管理任务,非常的方便,这篇文章是用来介绍任务Task的函数、使用、举例和注意事项。

2 创建任务的函数OSTaskCreate()

/*
*********************************************************************************************************
*                                            创建一个任务
*
* 描述:        这个函数用来管理uC/OS-II的任务执行。任务可以在多任务处理之前创建或一个正在运行的任务创建。
*              任务不能被一个ISR(中断)创建。
*
* 参数:        task     指向任务代码的指针
*
*              p_arg    指向一个可选数据区域的指针,这个数据区可以在任务开始执行的时候将参数传到该任务。
*                              就任务而言,它认为它调用和传递通过如下方式传输‘p_arg’
*                           void Task (void *p_arg)
*                           {
*                               for (;;) {
*                                   Task code;
*                               }
*                           }
*
*              ptos     指向任务堆栈顶部的指针。如果配置常量OS_STK_GROWTH设置为1,堆栈被认为向下变化(例
*                       如:从高内存到低内存),‘pstk’将因此指向堆栈的最高(有效)内存地址。如果配置常量
*                       OS_STK_GROWTH设置为0,将指向堆栈的最高内存地址。随着内存地址堆栈将增长。
*
*              prio     任务优先级。一个独立的优先级必须被指定给每一个任务并且数字越小优先级越高
*
* 返回值:      OS_ERR_NONE             函数成功时返回
*              OS_PRIO_EXIT            如果任务优先级已经存在(每一个任务必须有一个独立的优先级)
*              OS_ERR_PRIO_INVALID     若你指定的优先级更高那么最大值允许(i.e. >= OS_LOWEST_PRIO)
*              OS_ERR_TASK_CREATE_ISR  如果你尝试从ISR创建一个任务
*********************************************************************************************************
*/

#if OS_TASK_CREATE_EN > 0
INT8U  OSTaskCreate(void (*task)(void *p_arg),void *p_arg,OS_STK *ptos,INT8U prio)
{
    OS_STK    *psp;
    INT8U      err;

#if OS_CRITICAL_METHOD == 3                  /* CPU状态寄存器分配存储 */
    OS_CPU_SR  cpu_sr = 0;
#endif



#if OS_ARG_CHK_EN > 0
    if(prio > OS_LOWEST_PRIO)               /* 确保优优先级是在允许的范围内 */
	  {            
        return (OS_ERR_PRIO_INVALID);
      }
#endif

    OS_ENTER_CRITICAL();                   //保存全局中断标志,关中断

    if(OSIntNesting>0)                     /* 确保我们不会在ISR中创建任务  */
    {                  
        OS_EXIT_CRITICAL();	           //恢复全局中断标志
        return (OS_ERR_TASK_CREATE_ISR);
    }

    if(OSTCBPrioTbl[prio]==(OS_TCB *)0)            /* 确保在这个优先级下任务不存在 */
    { 
        OSTCBPrioTbl[prio]=OS_TCB_RESERVED;        /* 保留优先以防止其他人在做同样的事情直到创建任务 */
        OS_EXIT_CRITICAL();	                   //恢复全局中断标志
        psp = OSTaskStkInit(task,p_arg,ptos,0);    /* 初始化任务堆栈 */
        err = OS_TCBInit(prio,psp,(OS_STK *)0,0,0,(void *)0,0);
        if(err == OS_ERR_NONE) 
	{
            if(OSRunning==OS_TRUE) 
	    {                                     /* 如果任务已经开始,找到优先级最高的任务 */
                OS_Sched();
            }
        } 
	else
	{
            OS_ENTER_CRITICAL();                 //保存全局中断标志,关中断
            OSTCBPrioTbl[prio] = (OS_TCB *)0;    /*将这一优先级提供给他人 */
            OS_EXIT_CRITICAL();	                 //恢复全局中断标志
        }
        return (err);
    }

    OS_EXIT_CRITICAL();	                        //恢复全局中断标志
    return (OS_ERR_PRIO_EXIST);
}

3 用法举例

在不同的场合中可能相关的函数不一样,但是方法背后的思路是一样的,有些场合,比如我们进行模块开发(常用的有wifi模块等)的时候,由于厂家已经根据自己的情况会对ucos ii进行一些封装,我们使用的函数名可能有区别,但是用法一样。

4 用法注意事项积累

在使用过程中有很多注意事项,下面我将举例说明。

4.1 需要有while 或信号等待

在某次工程中,我为了保证某个任务是循环进行的,于是我新建了一个task但是发现始终只能执行一次,代码如下:

void task(void *p_arg)
{
    (void) p_arg;
}


4.2 需要有延时或信号等待

你可能感兴趣的:(uC/OS-II)