UCOSIII os_task函数

article/2025/11/8 1:38:23

认识任务管理的函数

  1. 建立任务:OSTaskCreate()
  2. 堆栈检验:OSTaskStkChk()
  3. 删除任务:OSTaskDel()
  4. 改变任务优先级:OSTaskChangePrio()
  5. 挂起任务:OSTaskSuspend()
  6. 恢复任务:OSTaskResume()

任务可以是一个无线的循环,也可以是在一次执行完毕后被删除掉。

注意:任务代码并非真正被删除了,而是操作系统不会再理会该任务代码,所以该任务代码不会再运行

任务从来不会返回,所以任务的类型都是Void型

一、建立任务

任务可以在多任务开始前被建立,即OSStart()函数执行前。也可以在其他任务的执行过程中被创建

但在多任务调度开始前必须建立至少一个任务,但千万不要再中断服务函数中建立任务

我们可以使用OSTaskCreate与OSTaskCreateExt这两个函数来建立任务

void  OSTaskCreate (OS_TCB        *p_tcb,指向任务的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 > 0uOS_REG_ID      reg_nbr;
#endif
#if defined(OS_CFG_TLS_TBL_SIZE) && (OS_CFG_TLS_TBL_SIZE > 0u)OS_TLS_ID      id;
#endifCPU_STK       *p_sp;CPU_STK       *p_stk_limit;CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return;}
#endif#ifdef OS_SAFETY_CRITICAL_IEC61508if (OSSafetyCriticalStartFlag == DEF_TRUE) {*p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;return;}
#endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0uif (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 > 0uif (prio == (OS_PRIO)0) {if (p_tcb != &OSIntQTaskTCB) {*p_err = OS_ERR_PRIO_INVALID;                    /* Not allowed to use priority 0                          */return;}}
#endifif (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;
#elsep_stk_limit = p_stk_base + (stk_size - 1u) - stk_limit;
#endifp_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 > 0uif (time_quanta == (OS_TICK)0) {p_tcb->TimeQuantaCtr = OSSchedRoundRobinDfltTimeQuanta;} else {p_tcb->TimeQuantaCtr = time_quanta;}
#endifp_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 > 0ufor (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 > 0uOS_MsgQInit(&p_tcb->MsgQ,                               /* Initialize the task's message queue                    */q_size);
#else(void)&q_size;
#endifOSTaskCreateHook(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 > 0uOS_TaskDbgListAdd(p_tcb);
#endifOSTaskQty++;                                            /* 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();
}

OSTaskCreate函数的大致流程为:

  1. 是否可以创建任务

    创建失败的原因:

    • 在中断中创建 ERR:OS_ERR_TASK_CREATE_ISR
    • 用户没有为任务传输相关参数
      • 缺少指向任务的TCB指针 ERR:OS_ERR_TCB_INVALID
      • 缺少指向任务的代码 ERR:OS_ERR_TASK_INVALID
      • 缺少指向任务的堆栈基址指针 ERR:OS_ERR_STK_INVALID
      • 缺少堆栈大小 ERR:OS_ERR_STK_SIZE_INVALID
      • 限制堆栈元素数大于堆栈大小 ERR:OS_ERR_STK_LIMIT_INVALID
      • pero>max or pero == 0 ERR:OS_ERR_PRIO_INVALID
    • 占用已使用特定任务的优先级 ERR:OS_ERR_PRIO_INVALID
  2. 进行TCB的初始化,调用OSTaskStkInit进行堆栈初始化

  3. 判断是否打开了轮询调度

  4. 确定任务的时间片大小

  5. 将TCB的初始为传入的参数

  6. 初始化任务的消息队列

  7. 设置任务的钩子函数,呼叫钩子函数

  8. 进入临界区后将任务插入就绪队列,任务数变量自加一

如果轮询调度开启退出临界区进行任务调度,创建好的任务在内存形式如下:

img

二、删除任务

**OSTaskDel(OS_TCB p_tcb,OS_ERR p_err)

该函数可以通过指定NULL来删除自己

​ 删除一个任务。根据任务状态,将p_tcb从RDyList,TickList,PendList中删除,释放Queue中的所有OS_MSG,调用钩子函数,清空TCB, p_tcb->TaskState = (OS_STATE)OS_TASK_STATE_DEL,启动调度

void  OSTaskDel (OS_TCB  *p_tcb,OS_ERR  *p_err)
{CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return;}
#endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0uif (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* See if trying to delete from ISR     */*p_err = OS_ERR_TASK_DEL_ISR;return;}
#endifif (p_tcb == &OSIdleTaskTCB) {                          /* Not allowed to delete the idle task  */*p_err = OS_ERR_TASK_DEL_IDLE;return;}#if OS_CFG_ISR_POST_DEFERRED_EN > 0uif (p_tcb == &OSIntQTaskTCB) {                          /* Cannot delete the ISR handler task   */*p_err = OS_ERR_TASK_DEL_INVALID;return;}
#endifif (p_tcb == (OS_TCB *)0) {                             /* Delete 'Self'?       */CPU_CRITICAL_ENTER();p_tcb  = OSTCBCurPtr;                               /* Yes.                */CPU_CRITICAL_EXIT();}OS_CRITICAL_ENTER();switch (p_tcb->TaskState) {case OS_TASK_STATE_RDY:OS_RdyListRemove(p_tcb);break;case OS_TASK_STATE_SUSPENDED:break;case OS_TASK_STATE_DLY:                             /* Task is only delayed, not on any wait list */case OS_TASK_STATE_DLY_SUSPENDED:OS_TickListRemove(p_tcb);break;case OS_TASK_STATE_PEND:case OS_TASK_STATE_PEND_SUSPENDED:case OS_TASK_STATE_PEND_TIMEOUT:case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:OS_TickListRemove(p_tcb);switch (p_tcb->PendOn) {                       /* See what we are pending on     */case OS_TASK_PEND_ON_NOTHING:case OS_TASK_PEND_ON_TASK_Q:               /* There is no wait list for these two   */case OS_TASK_PEND_ON_TASK_SEM:break;case OS_TASK_PEND_ON_FLAG:                 /* Remove from wait list          */case OS_TASK_PEND_ON_MULTI:case OS_TASK_PEND_ON_MUTEX:case OS_TASK_PEND_ON_Q:case OS_TASK_PEND_ON_SEM:OS_PendListRemove(p_tcb);break;default:break;}break;default:OS_CRITICAL_EXIT();*p_err = OS_ERR_STATE_INVALID;return;}#if OS_CFG_TASK_Q_EN > 0u(void)OS_MsgQFreeAll(&p_tcb->MsgQ);                     /* Free task's message queue messages  */
#endifOSTaskDelHook(p_tcb);                                   /* Call user defined hook       */#if defined(OS_CFG_TLS_TBL_SIZE) && (OS_CFG_TLS_TBL_SIZE > 0u)OS_TLS_TaskDel(p_tcb);                                  /* Call TLS hook                */
#endif#if OS_CFG_DBG_EN > 0uOS_TaskDbgListRemove(p_tcb);
#endifOSTaskQty--;                                            /* One less task being managed        */OS_TaskInitTCB(p_tcb);                                  /* Initialize the TCB to default values   */p_tcb->TaskState = (OS_STATE)OS_TASK_STATE_DEL;         /* Indicate that the task was deleted      */OS_CRITICAL_EXIT_NO_SCHED();*p_err = OS_ERR_NONE;                                    /* See Note #1.                         */OSSched();                                              /* Find new highest priority task       */
}

三、暂停任务

**OSTaskSuspend(OS_TCB p_tcb,OS_ERR p_err)

调用该函数可以暂停任务,p_tcb为NULL时可以暂停自己,最前面的是安全认证相关不用理会。中断中不可调用、不可暂停空闲函数、不可暂停中断服务函数、转到函数OS_TaskSuspend 中。

void   OSTaskSuspend (OS_TCB  *p_tcb,OS_ERR  *p_err)
{
#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return;}
#endif#if (OS_CFG_ISR_POST_DEFERRED_EN   == 0u) && \(OS_CFG_CALLED_FROM_ISR_CHK_EN >  0u)if (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* Not allowed to call from an ISR                        */*p_err = OS_ERR_TASK_SUSPEND_ISR;return;}
#endifif (p_tcb == &OSIdleTaskTCB) {                          /* Make sure not suspending the idle task                 */*p_err = OS_ERR_TASK_SUSPEND_IDLE;return;}#if OS_CFG_ISR_POST_DEFERRED_EN > 0uif (p_tcb == &OSIntQTaskTCB) {                          /* Not allowed to suspend the ISR handler task            */*p_err = OS_ERR_TASK_SUSPEND_INT_HANDLER;return;}if (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* See if called from an ISR                              */OS_IntQPost((OS_OBJ_TYPE)OS_OBJ_TYPE_TASK_SUSPEND,  /* Post to ISR queue                                      */(void      *)p_tcb,(void      *)0,(OS_MSG_SIZE)0,(OS_FLAGS   )0,(OS_OPT     )0,(CPU_TS     )0,(OS_ERR    *)p_err);return;}
#endifOS_TaskSuspend(p_tcb, p_err);
}

进入临界区,如果传入指针为NULL则将指针指向当前任务TCB指针,如果调度器上锁了不可以调度,根据任务所处的状态处理任务。开启调度。如果成功挂起任务,任务状态会变为暂停态,把他从就绪队列中移除,并设置暂停计数器为1,挂起一次累加一次。

void   OS_TaskSuspend (OS_TCB  *p_tcb,OS_ERR  *p_err)
{CPU_SR_ALLOC();CPU_CRITICAL_ENTER();if (p_tcb == (OS_TCB *)0) {                             /* See if specified to suspend self                       */p_tcb = OSTCBCurPtr;}if (p_tcb == OSTCBCurPtr) {if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) {    /* Can't suspend when the scheduler is locked             */CPU_CRITICAL_EXIT();*p_err = OS_ERR_SCHED_LOCKED;return;}}*p_err = OS_ERR_NONE;switch (p_tcb->TaskState) {case OS_TASK_STATE_RDY:OS_CRITICAL_ENTER_CPU_EXIT();p_tcb->TaskState  =  OS_TASK_STATE_SUSPENDED;p_tcb->SuspendCtr = (OS_NESTING_CTR)1;OS_RdyListRemove(p_tcb);OS_CRITICAL_EXIT_NO_SCHED();break;case OS_TASK_STATE_DLY:p_tcb->TaskState  = OS_TASK_STATE_DLY_SUSPENDED;p_tcb->SuspendCtr = (OS_NESTING_CTR)1;CPU_CRITICAL_EXIT();break;case OS_TASK_STATE_PEND:p_tcb->TaskState  = OS_TASK_STATE_PEND_SUSPENDED;p_tcb->SuspendCtr = (OS_NESTING_CTR)1;CPU_CRITICAL_EXIT();break;case OS_TASK_STATE_PEND_TIMEOUT:p_tcb->TaskState  = OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED;p_tcb->SuspendCtr = (OS_NESTING_CTR)1;CPU_CRITICAL_EXIT();break;case OS_TASK_STATE_SUSPENDED:case OS_TASK_STATE_DLY_SUSPENDED:case OS_TASK_STATE_PEND_SUSPENDED:case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:p_tcb->SuspendCtr++;CPU_CRITICAL_EXIT();break;default:CPU_CRITICAL_EXIT();*p_err = OS_ERR_STATE_INVALID;return;}OSSched();
}

四、恢复任务

**OSTaskResume (OS_TCB p_tcb, OS_ERR p_err)

调用函数可以恢复暂停的,函数首先判断是否在中断中、是否是自己调用。执行函数 OS_TaskResume(p_tcb, p_err);我们看这个函数足以。首先进入临界区、根据恢复暂停的任务状态来执行操作。状态为OS_TASK_STATE_SUSPENDED时暂停计数器减一,如果计数器减为0才可以将状态改为就绪态,将其放入就绪队列中。执行任务调度

void  OS_TaskResume (OS_TCB  *p_tcb,OS_ERR  *p_err)
{CPU_SR_ALLOC();CPU_CRITICAL_ENTER();*p_err  = OS_ERR_NONE;switch (p_tcb->TaskState) {case OS_TASK_STATE_RDY:case OS_TASK_STATE_DLY:case OS_TASK_STATE_PEND:case OS_TASK_STATE_PEND_TIMEOUT:CPU_CRITICAL_EXIT();*p_err = OS_ERR_TASK_NOT_SUSPENDED;break;case OS_TASK_STATE_SUSPENDED:OS_CRITICAL_ENTER_CPU_EXIT();p_tcb->SuspendCtr--;if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {p_tcb->TaskState = OS_TASK_STATE_RDY;OS_TaskRdy(p_tcb);}OS_CRITICAL_EXIT_NO_SCHED();break;case OS_TASK_STATE_DLY_SUSPENDED:p_tcb->SuspendCtr--;if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {p_tcb->TaskState = OS_TASK_STATE_DLY;}CPU_CRITICAL_EXIT();break;case OS_TASK_STATE_PEND_SUSPENDED:p_tcb->SuspendCtr--;if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {p_tcb->TaskState = OS_TASK_STATE_PEND;}CPU_CRITICAL_EXIT();break;case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:p_tcb->SuspendCtr--;if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {p_tcb->TaskState = OS_TASK_STATE_PEND_TIMEOUT;}CPU_CRITICAL_EXIT();break;default:CPU_CRITICAL_EXIT();*p_err = OS_ERR_STATE_INVALID;return;}OSSched();
}

五、查看任务堆栈使用量和剩余量

OSTaskStkChk()

检查p_tcb堆栈的使用量和剩余量,为了适应系统以后的升级和扩展,用户应该多分配10%-100%的堆栈空间。在堆栈检验中,用户所得到的只是一个大致的堆栈使用情况,并不能说明堆栈使用的全部实际情况。函数主要功能是不能在中断中检测、判断地址是否可用,进入临界区,p_tcb==NULL则为查询自身的,查看传入任务是否存在,查看堆栈的选项是否开启,判断完后退出临界区。根据栈的生长方式计算出空闲区域的大小,用栈的总量减去刚得出空闲区域的大小为已使用区域的大小。具体示意如图所示
img

void  OSTaskStkChk (OS_TCB        *p_tcb,CPU_STK_SIZE  *p_free,CPU_STK_SIZE  *p_used,OS_ERR        *p_err)
{CPU_STK_SIZE  free_stk;CPU_STK      *p_stk;CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return;}
#endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0uif (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* See if trying to check stack from ISR                  */*p_err = OS_ERR_TASK_STK_CHK_ISR;return;}
#endif#if OS_CFG_ARG_CHK_EN > 0uif (p_free == (CPU_STK_SIZE*)0) {                       /* User must specify valid destinations for the sizes*/*p_err  = OS_ERR_PTR_INVALID;return;}if (p_used == (CPU_STK_SIZE*)0) {*p_err  = OS_ERR_PTR_INVALID;return;}
#endifCPU_CRITICAL_ENTER();if (p_tcb == (OS_TCB *)0) {                             /* Check the stack of the current task?                   */p_tcb = OSTCBCurPtr;                                /* Yes                                                    */}if (p_tcb->StkPtr == (CPU_STK*)0) {                     /* Make sure task exist                                   */CPU_CRITICAL_EXIT();*p_free = (CPU_STK_SIZE)0;*p_used = (CPU_STK_SIZE)0;*p_err  =  OS_ERR_TASK_NOT_EXIST;return;}if ((p_tcb->Opt & OS_OPT_TASK_STK_CHK) == (OS_OPT)0) {  /* Make sure stack checking option is set                 */CPU_CRITICAL_EXIT();*p_free = (CPU_STK_SIZE)0;*p_used = (CPU_STK_SIZE)0;*p_err  =  OS_ERR_TASK_OPT;return;}CPU_CRITICAL_EXIT();free_stk  = 0u;
#if CPU_CFG_STK_GROWTH == CPU_STK_GROWTH_HI_TO_LOp_stk = p_tcb->StkBasePtr;                              /* Start at the lowest memory and go up                   */while (*p_stk == (CPU_STK)0) {                          /* Compute the number of zero entries on the stk          */p_stk++;free_stk++;}
#elsep_stk = p_tcb->StkBasePtr + p_tcb->StkSize - 1u;        /* Start at the highest memory and go down                */while (*p_stk == (CPU_STK)0) {free_stk++;p_stk--;}
#endif*p_free = free_stk;*p_used = (p_tcb->StkSize - free_stk);                   /* Compute number of entries used on the stack            */*p_err  = OS_ERR_NONE;
}

六、改变任务优先级

OSTaskChangePrio()

使用该函数可以动态的设置任务的优先级,优先级必须可用。根据状态对任务进行处理,当任务处于就绪状态时,将任务从就绪列表上移除,改变其优先级,再将他插入回就绪队列。若为暂停状态则直接改变优先级。执行调度。

void  OSTaskChangePrio (OS_TCB   *p_tcb,OS_PRIO   prio_new,OS_ERR   *p_err)
{CPU_BOOLEAN   self;CPU_SR_ALLOC();#ifdef OS_SAFETY_CRITICALif (p_err == (OS_ERR *)0) {OS_SAFETY_CRITICAL_EXCEPTION();return;}
#endif#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0uif (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* ---------- CANNOT CREATE A TASK FROM AN ISR ---------- */*p_err = OS_ERR_TASK_CHANGE_PRIO_ISR;return;}
#endif#if OS_CFG_ISR_POST_DEFERRED_EN > 0uif (prio_new == 0) {                                    /* Cannot set to IntQueue Task priority                   */*p_err = OS_ERR_PRIO_INVALID;return;}
#endifif (prio_new >= (OS_CFG_PRIO_MAX - 1u)) {               /* Cannot set to Idle Task priority                       */*p_err = OS_ERR_PRIO_INVALID;return;}if (p_tcb == (OS_TCB *)0) {                             /* See if want to change priority of 'self'       */CPU_CRITICAL_ENTER();p_tcb = OSTCBCurPtr;CPU_CRITICAL_EXIT();self  = DEF_TRUE;} else {self  = DEF_FALSE;}OS_CRITICAL_ENTER();switch (p_tcb->TaskState) {case OS_TASK_STATE_RDY:OS_RdyListRemove(p_tcb);                       /* Remove from current priority             */p_tcb->Prio = prio_new;                        /* Set new task priority             */OS_PrioInsert(p_tcb->Prio);if (self == DEF_TRUE) {OS_RdyListInsertHead(p_tcb);} else {OS_RdyListInsertTail(p_tcb);}break;case OS_TASK_STATE_DLY:                             /* Nothing to do except change the priority in the OS_TCB */case OS_TASK_STATE_SUSPENDED:case OS_TASK_STATE_DLY_SUSPENDED:p_tcb->Prio = prio_new;                        /* Set new task priority                                  */break;case OS_TASK_STATE_PEND:case OS_TASK_STATE_PEND_TIMEOUT:case OS_TASK_STATE_PEND_SUSPENDED:case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:switch (p_tcb->PendOn) {                       /* What to do depends on what we are pending on           */case OS_TASK_PEND_ON_TASK_Q:               /* Nothing to do except change the priority in the OS_TCB */case OS_TASK_PEND_ON_TASK_SEM:case OS_TASK_PEND_ON_FLAG:p_tcb->Prio = prio_new;               /* Set new task priority                                  */break;case OS_TASK_PEND_ON_MUTEX:case OS_TASK_PEND_ON_MULTI:case OS_TASK_PEND_ON_Q:case OS_TASK_PEND_ON_SEM:OS_PendListChangePrio(p_tcb,prio_new);break;default:break;}break;default:OS_CRITICAL_EXIT();*p_err = OS_ERR_STATE_INVALID;return;}OS_CRITICAL_EXIT_NO_SCHED();OSSched();                                              /* Run highest priority task ready                        */*p_err = OS_ERR_NONE;
}

http://chatgpt.dhexx.cn/article/SPJartnA.shtml

相关文章

[uCOS/RTOS]uC/OS-II中的任务堆栈大小检测

在uC/OS-II系统中&#xff0c;创建任务的时候除了需要配置任务的优先级以外&#xff0c;还需要对任务堆栈大小进行分配。而对于单片机这种RAM并不是非常大的微控制器来说&#xff0c;RAM显得格外珍贵&#xff0c;如果任务堆栈分配大了&#xff0c;会导致RAM不够用&#xff0c;分…

FreeRTOS-Task

Task FreeRTOS中Task为调度单位&#xff0c;是独立的运行实例&#xff0c;具有自己的堆栈空 间。Task通常是无限循环执行&#xff0c;不允许以任何方式退出实现函数&#xff08;return 语句或者运行结束&#xff09;。如果Task真的不需要了&#xff0c;需要显式的调用delete 函…

AUTOSAR OS Introduction -- Part 2(Task Property)

Event Event 主要用于为Extended Task 提供多个同步点,每个Event 可以关联多个Task Event Trigger condition 显示调用SetEvent通过Alarm TriggerCallback & OS API WaitEvent 只要表达式中任意一个EVENT 被收到,Task state则切换至Ready, 等待调度表按照优先级进行…

UCOS-Ⅲ查看任务堆栈空间:OSTaskStkChk()函数

UCOS-Ⅲ查看任务堆栈空间&#xff1a;OSTaskStkChk()函数 文章目录 前言一、准备工作二、使用步骤1.创建堆栈检测任务2.在头文件os_cfg.h开启宏OS_CFG_STAT_TASK_STK_CHK_EN3.在堆栈检测任务使用OSTaskStkChk()函数 三、结果 前言 硬件的RAM资源有限&#xff0c;UCOSⅢ提供了一…

【UCOSIII操作系统】任务篇(1)创建任务

UCOSIII操作系统 UCOSIII操作系统——任务篇&#xff08;1&#xff09;创建任务一、UCOSIII——任务 简介二、创建任务流程1、定义任务栈2、定义任务控制块TCB3、定义任务主体函数4、创建任务 三、任务的状态 UCOSIII其他内容导航不迷路 UCOSIII操作系统-简介 【UCOSIII操作系统…

FreeRTOS中taskENTER_CRITICAL()和taskEXIT_CRITICAL()函数运用

以下转载自安富莱电子&#xff1a; http://forum.armfly.com/forum.php 临界段 代码的临界段也称为临界区&#xff0c;一旦这部分代码开始执行&#xff0c;则不允许任何中断打断。为确保临界段代码 的执行不被中断&#xff0c;在进入临界段之前须关中断&#xff0c;而临界段代…

OSTaskCreateExt()建立任务

ucosII创建任务的硬性要求&#xff1a; 1.任务必须被创建在多任务启动前或运行的任务中 2.任务不能在ISR&#xff08;中断&#xff09;中创建 3.任务必须在死循环中&#xff0c;且不能有返回 OSTaskCreateExt()建立任务 NT8U OSTaskCreateExt (void (*task)(void *pd), …

赢在微点答案专区英语_英语u校园读写2答案unit3,u校园新标准大学英语视听说3单元测试答案搜题公众号...

英语u校园读写2答案unit3,u校园新标准大学英语视听说3单元测试答案搜题公众号,u校园大学英语读写4第一单元答案查题APP更多相关问题A&#xff0e;婴儿期 B&#xff0e;幼儿期 C&#xff0e;学龄前期 D&#xff0e;学龄期 E&#xff0e;青春期关于自我&#xff0c;正确的说法是(…

新视野大学英语视听说第三版答案

Unit 1 Unit 2 Unit 3 Unit 4 Unit 5 Unit 6 Unit 7 Unit 8

视听说教程(第三版)4 quiz 1

视听说教程&#xff08;第三版&#xff09;4 quiz 1 Reading Comprehension Section A Passage One Questions 1 to 5 are based on the following passage. We all want to raise kids who are happy and successful, but we often mistakenly think that money is the key …

welearn 视听说1-4

词汇题&#xff08;55道&#xff09; 1. You should carefully think over_____ the manager said at the meeting. A. that B. which C. what D. whose 1.选C,考察宾语从句连接词&#xff0c;主句谓语动词think over后面缺宾语&#xff0c;后面的宾语从句谓语动…

使用RemObjects Pascal Script

摘自RemObjects Wiki 本文提供RemObjects Pascal Script的整体概要并演示如何创建一些简单的脚本. Pascal Script包括两个不同部分: 编译器 (uPSCompiler.pas)运行时 (uPSRuntime.pas) 两部分彼此独立.可以分开使用,或通过TPSScript 控件使用他们,这个控件定义在uPSComponent.p…

搭建一个简单的Pascal脚本开发环境

使用innosetup进行打包&#xff0c;涉及到需要编写一些Pascal脚本&#xff0c;所以了解了下Pascal的相关语法。 这里主要介绍如何搭建一个简单的Pascal开发环境。 一、Free Pascal Free Pascal&#xff08;全称 FPK Pascal&#xff09;是一个32位和64位专业Pascal编译器。它…

pascal编程语言介绍

Pascal是一种过程式编程语言&#xff0c;由Niklaus Wirth于1968年设计并于1970年发布&#xff0c;并以法国数学家和哲学家Blaise Pascal的名字命名。Pascal可以运行在多种平台上&#xff0c;例如Windows、Mac OS和各种版本的UNIX/Linux。[3] 软件名称 Pascal 软件平台 Windows、…

Free Pascal IDE安装

1. Free Pascal IDE 安装 首先&#xff0c;去 https://www.freepascal.org/download.var 下载Free Pascal IDE。我选择的sourceforge镜像 fpc-3.0.2.i386-win32.exe&#xff0c;下载比较慢&#xff0c;请耐心等待。下载完成后&#xff0c;双击exe文件进行安装&#xf…

[pascal入门]数组

一、本节目标 本节我们将要讲述数组。本节目标&#xff1a; 一维数组二维数组字符数组 二、一维数组 我们通过一个案例来简单的理解数组。班主任要计算班级里面50个同学数学成绩的平均成绩&#xff0c;道理上讲这是一个比较简单的问题&#xff0c;只需要把每个人的成绩加起来除…

linux的pascal语言,pascal语言视频教程 Linux GCC常用命令详解

GCC 的意思也只是 GNU C Compiler 而已。经过了这么多年的发展&#xff0c;GCC 已经不仅仅能支持 C 语言&#xff1b;它现在还支持 Ada 语言、C 语言、Java 语言、Objective C 语言、Pascal 语言、COBOL语言&#xff0c;以及支持函数式编程和逻辑编程的 Mercury 语言&#xff0…

vscode 配置 pascal环境

vscode 配置 pascal环境 网上关于配置pascal的教程不太多&#xff0c;我试验了好几个&#xff0c;都没搞对&#xff0c;其中有很多原因吧&#xff0c;最后从较多、较熟悉的c环境开始配置理解&#xff0c;才算是慢慢懂得了这个配置过程&#xff0c;前前后后大概花一个星期&…

信息学竞赛 c语言 pascal,pascal信息学竞赛教程

第一讲: 信息学竞赛讲座:预备知识 计算机语言是计算机软件中非常独特的一部份&#xff0c;它属于系统软件&#xff0c;但又和应用软件息息相关。它的作用是&#xff1a;使人类能够用某些命令、指令去让计算机为人类进行数值、逻辑运算。计算机语言中&#xff0c;只有一种语言是…

Pascal基础教程

第一课 初识Pascal语言 信息学奥林匹克竞赛是一项益智性的竞赛活动&#xff0c;核心是考查选手的智力和使用计算机解题的能力。选手首先应针对竞赛中题目的要求构建数学模型&#xff0c;进而构造出计算机可以接受的算法&#xff0c;之后要写出高级语言程序&#xff0c;上机调试…