UCOSIIIAPI函数接口OSTaskCreate();函数

来源:互联网 发布:win7怎么自动连接网络 编辑:程序博客网 时间:2024/06/08 06:45

任务的创建和删除实验
uCOSIII是多任务系统,那么肯定要创建任务,创建任务就是将任务控制块、任务堆栈、任务代码等联系在一起,并且初始化任务控制块的相应字段。在UCOSIII中我们通过函数OSTaskCreate ();来创建任务,OSTaskCreate();函数原型如下(在os_task.c中有定义)。电泳OSTaskCreate ();创建一个任务之后,刚创建的任务就会进入就绪状态,注意!不能够在中断服务程序中调用OSTaskCreate ();函数创建任务。

void  OSTaskCreate (OS_TCB        *p_tcb,                    CPU_CHAR      *p_name,                    OS_TASK_PTR    p_task,                    void          *p_arg,                    OS_PRIO        prio,                    CPU_STK       *p_stk_base,                    CPU_STK_SIZE   stk_limit,                    CPU_STK_SIZE   stk_size,                    OS_MSG_QTY     q_size,                    OS_TICK        time_quanta,                    void          *p_ext,                    OS_OPT         opt,                    OS_ERR        *p_err){    CPU_STK_SIZE   i;#if OS_CFG_TASK_REG_TBL_SIZE > 0u    OS_REG_ID      reg_nbr;#endif#if defined(OS_CFG_TLS_TBL_SIZE) && (OS_CFG_TLS_TBL_SIZE > 0u)    OS_TLS_ID      id;#endif    CPU_STK       *p_sp;    CPU_STK       *p_stk_limit;    CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICAL    if (p_err == (OS_ERR *)0) {        OS_SAFETY_CRITICAL_EXCEPTION();        return;    }#endif#ifdef OS_SAFETY_CRITICAL_IEC61508    if (OSSafetyCriticalStartFlag == DEF_TRUE) {       *p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;        return;    }#endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u    if (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* ---------- CANNOT CREATE A TASK FROM AN ISR ---------- */       *p_err = OS_ERR_TASK_CREATE_ISR;        return;    }#endif#if OS_CFG_ARG_CHK_EN > 0u                                  /* ---------------- VALIDATE ARGUMENTS ------------------ */    if (p_tcb == (OS_TCB *)0) {                             /* User must supply a valid OS_TCB                        */       *p_err = OS_ERR_TCB_INVALID;        return;    }    if (p_task == (OS_TASK_PTR)0) {                         /* User must supply a valid task                          */       *p_err = OS_ERR_TASK_INVALID;        return;    }    if (p_stk_base == (CPU_STK *)0) {                       /* User must supply a valid stack base address            */       *p_err = OS_ERR_STK_INVALID;        return;    }    if (stk_size < OSCfg_StkSizeMin) {                      /* User must supply a valid minimum stack size            */       *p_err = OS_ERR_STK_SIZE_INVALID;        return;    }    if (stk_limit >= stk_size) {                            /* User must supply a valid stack limit                   */       *p_err = OS_ERR_STK_LIMIT_INVALID;        return;    }    if (prio >= OS_CFG_PRIO_MAX) {                          /* Priority must be within 0 and OS_CFG_PRIO_MAX-1        */       *p_err = OS_ERR_PRIO_INVALID;        return;    }#endif#if OS_CFG_ISR_POST_DEFERRED_EN > 0u    if (prio == (OS_PRIO)0) {        if (p_tcb != &OSIntQTaskTCB) {           *p_err = OS_ERR_PRIO_INVALID;                    /* Not allowed to use priority 0                          */            return;        }    }#endif    if (prio == (OS_CFG_PRIO_MAX - 1u)) {        if (p_tcb != &OSIdleTaskTCB) {           *p_err = OS_ERR_PRIO_INVALID;                    /* Not allowed to use same priority as idle task          */            return;        }    }    OS_TaskInitTCB(p_tcb);                                  /* Initialize the TCB to default values                   */   *p_err = OS_ERR_NONE;                                                            /* --------------- CLEAR THE TASK'S STACK --------------- */    if ((opt & OS_OPT_TASK_STK_CHK) != (OS_OPT)0) {         /* See if stack checking has been enabled                 */        if ((opt & OS_OPT_TASK_STK_CLR) != (OS_OPT)0) {     /* See if stack needs to be cleared                       */            p_sp = p_stk_base;            for (i = 0u; i < stk_size; i++) {               /* Stack grows from HIGH to LOW memory                    */               *p_sp = (CPU_STK)0;                          /* Clear from bottom of stack and up!                     */                p_sp++;            }        }    }                                                            /* ------- INITIALIZE THE STACK FRAME OF THE TASK ------- */#if (CPU_CFG_STK_GROWTH == CPU_STK_GROWTH_HI_TO_LO)    p_stk_limit = p_stk_base + stk_limit;#else    p_stk_limit = p_stk_base + (stk_size - 1u) - stk_limit;#endif    p_sp = OSTaskStkInit(p_task,                         p_arg,                         p_stk_base,                         p_stk_limit,                         stk_size,                         opt);                                                            /* -------------- INITIALIZE THE TCB FIELDS ------------- */    p_tcb->TaskEntryAddr = p_task;                          /* Save task entry point address                          */    p_tcb->TaskEntryArg  = p_arg;                           /* Save task entry argument                               */    p_tcb->NamePtr       = p_name;                          /* Save task name                                         */    p_tcb->Prio          = prio;                            /* Save the task's priority                               */    p_tcb->StkPtr        = p_sp;                            /* Save the new top-of-stack pointer                      */    p_tcb->StkLimitPtr   = p_stk_limit;                     /* Save the stack limit pointer                           */    p_tcb->TimeQuanta    = time_quanta;                     /* Save the #ticks for time slice (0 means not sliced)    */#if OS_CFG_SCHED_ROUND_ROBIN_EN > 0u    if (time_quanta == (OS_TICK)0) {        p_tcb->TimeQuantaCtr = OSSchedRoundRobinDfltTimeQuanta;    } else {        p_tcb->TimeQuantaCtr = time_quanta;    }#endif    p_tcb->ExtPtr        = p_ext;                           /* Save pointer to TCB extension                          */    p_tcb->StkBasePtr    = p_stk_base;                      /* Save pointer to the base address of the stack          */    p_tcb->StkSize       = stk_size;                        /* Save the stack size (in number of CPU_STK elements)    */    p_tcb->Opt           = opt;                             /* Save task options                                      */#if OS_CFG_TASK_REG_TBL_SIZE > 0u    for (reg_nbr = 0u; reg_nbr < OS_CFG_TASK_REG_TBL_SIZE; reg_nbr++) {        p_tcb->RegTbl[reg_nbr] = (OS_REG)0;    }#endif#if OS_CFG_TASK_Q_EN > 0u    OS_MsgQInit(&p_tcb->MsgQ,                               /* Initialize the task's message queue                    */                q_size);#else    (void)&q_size;#endif    OSTaskCreateHook(p_tcb);                                /* Call user defined hook                                 */#if defined(OS_CFG_TLS_TBL_SIZE) && (OS_CFG_TLS_TBL_SIZE > 0u)    for (id = 0u; id < OS_CFG_TLS_TBL_SIZE; id++) {        p_tcb->TLS_Tbl[id] = (OS_TLS)0;    }    OS_TLS_TaskCreate(p_tcb);                               /* Call TLS hook                                          */#endif                                                            /* --------------- ADD TASK TO READY LIST --------------- */    OS_CRITICAL_ENTER();    OS_PrioInsert(p_tcb->Prio);    OS_RdyListInsertTail(p_tcb);#if OS_CFG_DBG_EN > 0u    OS_TaskDbgListAdd(p_tcb);#endif    OSTaskQty++;                                            /* Increment the #tasks counter                           */    if (OSRunning != OS_STATE_OS_RUNNING) {                 /* Return if multitasking has not started                 */        OS_CRITICAL_EXIT();        return;    }    OS_CRITICAL_EXIT_NO_SCHED();    OSSched();}

**void  OSTaskCreate (OS_TCB        *p_tcb,                    CPU_CHAR      *p_name,                    OS_TASK_PTR    p_task,                    void          *p_arg,                    OS_PRIO        prio,                    CPU_STK       *p_stk_base,                    CPU_STK_SIZE   stk_limit,                    CPU_STK_SIZE   stk_size,                    OS_MSG_QTY     q_size,                    OS_TICK        time_quanta,                    void          *p_ext,                    OS_OPT         opt,                    OS_ERR        *p_err)**

*p_tcb 指向任务的控制块OS_TCB
*p_name 指向任务的名字,我们可以为每一个任务取一个名字
p_task 执行任务代码,也就是任务函数的名字
*p_arg 传递给任务的参数
prio 任务优先级,数值越低优先级越高,用户不能够使用系统任务使用的那些优先级!
*p_stk_base 指向任务堆栈的基地址
stk_limit 任务堆栈深度,用来检测和确保堆栈不溢出
stk_size 任务堆栈大小
q_size COSIII中每个任务都有一个可选的内部消息队列,我们要定义OS_CFG_TASK_Q_EN>0,这时才能使用这个内部 消息队列
time_quanta 在使能时间片轮转调用时用来设置时间片长度,默认节拍为时钟节拍除以10.
*p_ext 指向用户补充的存储区。
opt 包含任务的特定选项,有如下选项可以设置。
OS_OPT_TASK_NONE 表示没有任何选项
OS_OPT_TASK_STK_CHK 指定是否允许检测该任务的堆栈
OS_OPT_TASK_STK_CLR 指定是否清除该任务的堆栈
OS_OPT_TASK_SAVE_FP 指定是否存浮点寄存器,CPU需要浮点运算硬件并且有专用代码保护浮点 寄存器
*p_err 用来保存调用该函数后返回的错误代码。

原创粉丝点击