OSTaskSuspend函数
该函数的作用是挂起一个任务,形参也比较简单。这个函数的特点就是可以根据是否有中断嵌套,进行延迟发布。如果有的话,就会调用OS_IntQPost,事件类型为OS_OBJ_TYPE_TASK_SUSPEND,实际上就是等待中断函数结束后,在挂起目标任务。当然这个功能可以通过OS_CFG_ISR_POST_DEFERRED_EN来决定是否开启。如果不是在中断里面,直接挂起一个任务,调用OS_TaskSuspend函数。
#if OS_CFG_TASK_SUSPEND_EN > 0u
void OSTaskSuspend (OS_TCB *p_tcb,
OS_ERR *p_err)
{
#ifdef OS_SAFETY_CRITICAL
if (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;
}
#endif
if (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 > 0u
if (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;
}
#endif
OS_TaskSuspend(p_tcb, p_err);
}
#endif
OS_TaskSuspend函数
该函数的作用是直接挂起一个任务,不在像上一个函数那样,判断中断嵌套,延迟发布。但是挂起一个任务远没有我们想的那么简单,仅仅是从就序列表里面删除。需要根据目标任务的状态来确定,这个任务的挂起后的状态。
如果形参传的是0,意味着要挂起自身。如果调度器被锁住,就不会挂起。、
挂起任务结束后,进行一次任务调度。
#if OS_CFG_TASK_SUSPEND_EN > 0u
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();
}
#endif
OSTaskResume函数
该函数的作用是解除一个任务的挂起,没有特殊情况就会恢复到就绪状态。该函数和OSTaskSuspend相似并没有太大差别。
#if OS_CFG_TASK_SUSPEND_EN > 0u
void OSTaskResume (OS_TCB *p_tcb,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (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_RESUME_ISR;
return;
}
#endif
CPU_CRITICAL_ENTER();
#if OS_CFG_ARG_CHK_EN > 0u
if ((p_tcb == (OS_TCB *)0) || /* We cannot resume 'self' */
(p_tcb == OSTCBCurPtr)) {
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_TASK_RESUME_SELF;
return;
}
#endif
CPU_CRITICAL_EXIT();
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if called from an ISR */
OS_IntQPost((OS_OBJ_TYPE)OS_OBJ_TYPE_TASK_RESUME, /* 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;
}
#endif
OS_TaskResume(p_tcb, p_err);
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
TRACE_OS_TASK_RESUME(p_tcb); /* Record the event. */
#endif
}
#endif
OS_TaskResume函数
这个函数与OS_TaskSuspend类似,没有太大差别。但是p_tcb为0的话不再是代表本身,以为一个挂了的任务不会解救自己。
#if OS_CFG_TASK_SUSPEND_EN > 0u
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_RdyListInsert(p_tcb); /* Insert the task in the ready list */
}
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();
}
#endif
OSTaskDel函数
这个函数的作用是删除一个任务,系统自带的任务可不能删除,你也删除不了。在中断函数里面不能删除任务。p_tcb=0,代表自身。
删除一个任务后清除这个任务的一些信息,比如说任务控制块、邮箱,任务的状态也会修改。最后发起一次任务调度。
#if OS_CFG_TASK_DEL_EN > 0u
void OSTaskDel (OS_TCB *p_tcb,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* See if trying to delete from ISR */
*p_err = OS_ERR_TASK_DEL_ISR;
return;
}
#endif
if (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 > 0u
if (p_tcb == &OSIntQTaskTCB) { /* Cannot delete the ISR handler task */
*p_err = OS_ERR_TASK_DEL_INVALID;
return;
}
#endif
if (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:
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;
}
OS_TickListRemove(p_tcb);
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 */
#endif
OSTaskDelHook(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 > 0u
OS_TaskDbgListRemove(p_tcb);
#endif
OSTaskQty--; /* One less task being managed */
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
TRACE_OS_TASK_DEL(p_tcb); /* Record the event. */
#endif
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 */
}
#endif