📄 task.c
字号:
{
return E_CREATE_FAIL;
}
if(prio > CFG_LOWEST_PRIO)
{
return E_CREATE_FAIL;
}
#if CFG_STK_CHECKOUT_EN >0
if(sktSz < 20)
{
return E_CREATE_FAIL;
}
#endif // CFG_STK_CHECKOUT_EN
#endif // CFG_PAR_CHECKOUT_EN
#if CFG_TASK_SCHEDULE_EN == 0
if(TCBRunning != NULL)
return E_CREATE_FAIL;
#endif
stkTopPtr = InitTaskContext(task,argv,stk); /* Initialize task context. */
ptcb = AssignTCB(); /* Get free TCB to use */
if(ptcb == NULL) /* Is free TCB equal to NULL? */
{
return E_CREATE_FAIL; /* Yes,error return */
}
ptcb->stkPtr = stkTopPtr; /* Initialize TCB as user set */
ptcb->prio = prio;
#if CFG_STK_CHECKOUT_EN >0
ptcb->stack = stk+1 - sktSz; /* Set bottom stack for stack overflow check */
*(U32*)(ptcb->stack) = MAGIC_WORD;
#endif
#if CFG_TASK_WAITTING_EN >0
ptcb->delayTick = INVALID_VALUE;
#endif
#if CFG_TASK_SCHEDULE_EN == 0
ptcb->taskFuc = task;
ptcb->taskStk = stk;
#endif
ptcb->TCBnext = NULL; /* Initialize TCB link in READY list */
ptcb->TCBprev = NULL;
#if CFG_ROBIN_EN >0 /* Set task time slice for task robin */
timeSlice = (parameter&0x7fff0000)>>20;
if(timeSlice == 0)
{
timeSlice = CFG_TIME_SLICE;
}
ptcb->timeSlice = timeSlice;
#endif
#if CFG_FLAG_EN > 0
ptcb->pnode = NULL; /* Initialize task as no flag waiting */
#endif
#if CFG_EVENT_EN > 0
ptcb->eventID = INVALID_ID; /* Initialize task as no event waiting*/
ptcb->pmail = NULL;
ptcb->waitNext = NULL;
ptcb->waitPrev = NULL;
#endif
#if CFG_MUTEX_EN > 0
/* Initialize task as no mutex holding or waiting */
ptcb->mutexID = INVALID_ID;
#endif
#if CFG_ORDER_LIST_SCHEDULE_EN ==0
ActiveTaskPri(prio);
#endif
if((parameter>>31) == 0) /* Is task in waitting state? */
{ /* No,set it into ready list */
OsSchedLock(); /* Lock schedule */
InsertToTCBRdyList(ptcb); /* Insert into the READY list */
OsSchedUnlock(); /* Unlock schedule */
}
else
{ /* Yes,Set task status as TASK_WAITING*/
ptcb->state = TASK_WAITING;
}
return ptcb->taskID; /* Return task ID */
}
/**
*******************************************************************************
* @brief Delete Task
* @param[in] taskID Task ID
* @param[out] None
* @retval E_INVALID_ID Invalid task ID.
* @retval E_PROTECTED_TASK Protected task in OS.
* @retval E_OK Delete successful.
*
* @par Description
* @details This function is called to delete assign task.
*******************************************************************************
*/
StatusType CoDelTask(OS_TID taskID)
{
P_OSTCB ptcb;
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM)
{
return E_INVALID_ID;
}
#endif
ptcb = &TCBTbl[taskID];
#if CFG_PAR_CHECKOUT_EN >0
if(ptcb->state == TASK_DORMANT)
{
return E_INVALID_ID;
}
#endif
if(taskID == 0) /* Is idle task? */
{
return E_PROTECTED_TASK; /* Yes,error return */
}
if(ptcb->state == TASK_RUNNING) /* Is task running? */
{
if(OSSchedLock != 0) /* Yes,is OS lock? */
{
return E_OS_IN_LOCK; /* Yes,error return */
}
}
#if CFG_MUTEX_EN >0 /* Do task hold mutex? */
if(ptcb->mutexID != INVALID_ID)
{
if(MutexTbl[ptcb->mutexID].taskID == ptcb->taskID)
{ /* Yes,leave the mutex */
CoLeaveMutexSection(ptcb->mutexID);
}
}
#endif
OsSchedLock(); /* Lock schedule */
if(ptcb->state == TASK_READY) /* Is task in READY list? */
{
RemoveFromTCBRdyList(ptcb); /* Yes,remove task from the READY list*/
}
#if CFG_TASK_WAITTING_EN > 0
else if(ptcb->state == TASK_WAITING)/* Is task in the WAITING list? */
{
/* Yes,Is task in delay list? */
if(ptcb->delayTick != INVALID_VALUE)
{
RemoveDelayList(ptcb); /* Yes,remove task from READY list */
}
#if CFG_EVENT_EN > 0
if(ptcb->eventID != INVALID_ID) /* Is task in event waiting list? */
{
/* Yes,remove task from event waiting list */
RemoveEventWaittingList(ptcb);
}
#endif
#if CFG_FLAG_EN > 0
if(ptcb->pnode != NULL) /* Is task in flag waiting list? */
{
/* Yes,remove task from flag waiting list */
RemoveLinkNode(ptcb->pnode);
}
#endif
#if CFG_MUTEX_EN >0
if(ptcb->mutexID != INVALID_ID) /* Is task in mutex waiting list? */
{
RemoveMutexList(ptcb); /* Yes,remove task from mutex waiting list*/
}
#endif
}
#endif
ptcb->state = TASK_DORMANT; /* Release TCB */
TaskSchedReq = TRUE;
#if CFG_ORDER_LIST_SCHEDULE_EN ==0
DeleteTaskPri(ptcb->prio);
#endif
#if CFG_TASK_SCHEDULE_EN >0
ptcb->TCBnext = FreeTCB;
FreeTCB = ptcb;
#endif
OsSchedUnlock(); /* Unlock schedule */
return E_OK; /* return OK */
}
/**
*******************************************************************************
* @brief Exit Task
* @param[in] None
* @param[out] None
* @retval None
*
* @par Description
* @details This function is called to exit current task.
*******************************************************************************
*/
void CoExitTask(void)
{
CoDelTask(TCBRunning->taskID); /* Call task delete function */
}
#if CFG_TASK_SCHEDULE_EN ==0
/**
*******************************************************************************
* @brief Activate Task
* @param[in] taskID Task ID
* @param[in] argv Task argv
* @param[out] None
* @retval E_INVALID_ID Invalid task ID.
* @retval E_OK Activate task successful.
*
* @par Description
* @details This function is called to activate current task.
*******************************************************************************
*/
StatusType CoActivateTask(OS_TID taskID,void *argv)
{
P_OSTCB ptcb;
OS_STK* stkTopPtr;
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM)
{
return E_INVALID_ID;
}
#endif
ptcb = &TCBTbl[taskID];
#if CFG_PAR_CHECKOUT_EN >0
if(ptcb->stkPtr == NULL)
return E_INVALID_ID;
#endif
if(ptcb->state != TASK_DORMANT)
return E_OK;
/* Initialize task context. */
stkTopPtr = InitTaskContext(ptcb->taskFuc,argv,ptcb->taskStk);
ptcb->stkPtr = stkTopPtr; /* Initialize TCB as user set */
OsSchedLock(); /* Lock schedule */
InsertToTCBRdyList(ptcb); /* Insert into the READY list */
OsSchedUnlock(); /* Unlock schedule */
return E_OK;
}
#endif
/**
*******************************************************************************
* @brief Get current task id
* @param[in] None
* @param[out] None
* @retval ID of the current task.
*
* @par Description
* @details This function is called to get current task id.
*******************************************************************************
*/
OS_TID CoGetCurTaskID(void)
{
return (TCBRunning->taskID); /* Return running task ID */
}
#if CFG_TASK_SUSPEND_EN >0
/**
*******************************************************************************
* @brief Suspend Task
* @param[in] taskID ID of task that want to suspend.
* @param[out] None
* @retval E_OK Task suspend successful.
* @retval E_INVALID_ID Invalid event ID.
* @retval E_PROTECTED_TASK Can't suspend idle task.
* @retval E_ALREADY_IN_WAITING Task now in waiting state.
*
* @par Description
* @details This function is called to exit current task.
*******************************************************************************
*/
StatusType CoSuspendTask(OS_TID taskID)
{
P_OSTCB ptcb;
if(taskID == 0) /* Is idle task? */
{
return E_PROTECTED_TASK; /* Yes,error return */
}
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM)
{
return E_INVALID_ID;
}
#endif
ptcb = &TCBTbl[taskID];
#if CFG_PAR_CHECKOUT_EN >0
if(ptcb->state == TASK_DORMANT)
{
return E_INVALID_ID;
}
#endif
if(OSSchedLock != 0)
{
return E_OS_IN_LOCK;
}
if(ptcb->state == TASK_WAITING) /* Is task in WAITING list? */
{
return E_ALREADY_IN_WAITING; /* Yes,error return */
}
OsSchedLock();
if(ptcb != TCBRunning) /* Is runing task? */
{
RemoveFromTCBRdyList(ptcb); /* No,Remove task from READY list */
}
else
{
TaskSchedReq = TRUE;
}
ptcb->state = TASK_WAITING; /* Set task status as TASK_WAITING */
OsSchedUnlock(); /* Call task schedule */
return E_OK; /* Return OK */
}
/**
*******************************************************************************
* @brief Awake Task
* @param[in] taskID ID of task that will been awaked.
* @param[out] None
* @retval E_OK Task awake successful.
* @retval E_INVALID_ID Invalid task ID.
* @retval E_TASK_NOT_WAITING Task now not in waiting state.
* @retval E_TASK_WAIT_OTHER Task now waiting other awake event.
* @retval E_PROTECTED_TASK Idle task mustn't be awaked.
*
* @par Description
* @details This function is called to awake current task.
*******************************************************************************
*/
StatusType CoAwakeTask(OS_TID taskID)
{
P_OSTCB ptcb;
if(taskID == 0) /* Is idle task? */
{
return E_PROTECTED_TASK; /* Yes,error return */
}
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM)
{
return E_INVALID_ID;
}
#endif
ptcb = &TCBTbl[taskID];
#if CFG_PAR_CHECKOUT_EN >0
if(ptcb->state == TASK_DORMANT)
{
return E_INVALID_ID;
}
#endif
if(ptcb->state != TASK_WAITING) /* Is task in WAITING list */
{
return E_TASK_NOT_WAITING; /* No,error return */
}
#if CFG_TASK_WAITTING_EN > 0
if(ptcb->delayTick != INVALID_VALUE)/* Is task in READY list */
{
return E_TASK_WAIT_OTHER; /* Yes,error return */
}
#if CFG_FLAG_EN > 0
if(ptcb->pnode != NULL) /* Is task in flag waiting list */
{
return E_TASK_WAIT_OTHER; /* Yes,error return */
}
#endif
#if CFG_EVENT_EN>0
if(ptcb->eventID != INVALID_ID) /* Is task in event waiting list */
{
return E_TASK_WAIT_OTHER; /* Yes,error return */
}
#endif
#if CFG_MUTEX_EN > 0
if(ptcb->mutexID != INVALID_ID) /* Is task in mutex waiting list */
{
return E_TASK_WAIT_OTHER; /* Yes,error return */
}
#endif
#endif //CFG_TASK_WAITTING_EN
/* All no,so WAITING state was set by CoSuspendTask() */
OsSchedLock(); /* Lock schedule */
InsertToTCBRdyList(ptcb); /* Insert the task into the READY list*/
OsSchedUnlock(); /* Unlock schedule */
return E_OK; /* return OK */
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -