📄 emos_task.c
字号:
{
/* Task to delete must exist */
ptcb->osTCBDelReq = EMOS_TASK_DEL_REQ; /* Set flag indicating task to be DEL. */
err = EMOS_NO_ERR;
}
else
{
err = EMOS_TASK_NOT_EXIST; /* Task must be deleted */
}
EMOS_EXIT_CRITICAL();
return (err);
}
}
#endif
/********************************************************************************************************
* RESUME A SUSPENDED TASK
* Description: This function is called to resume a previously suspended task. This is the only call that
* will remove an explicit task suspension.
* Arguments : prio is the priority of the task to resume.
* Returns : EMOS_NO_ERR if the requested task is resumed
* EMOS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
* (i.e. >= EMOS_LOWEST_PRIO)
* EMOS_TASK_RESUME_PRIO if the task to resume does not exist
* EMOS_TASK_NOT_SUSPENDED if the task to resume has not been suspended
**********************************************************************************************************/
#if EMOS_TASK_SUSPEND_EN
uint8 emosTaskResume (uint8 prio)
{
EMOS_TCB_T* ptcb = NULL;
if (prio >= EMOS_LOWEST_PRIO)
{
/* Make sure task priority is valid*/
return (EMOS_PRIO_INVALID);
}
EMOS_ENTER_CRITICAL();
if ((ptcb = gEmosTCBPrioTbl[prio]) == (EMOS_TCB_T *)0)
{
/* Task to suspend must exist*/
EMOS_EXIT_CRITICAL();
return (EMOS_TASK_RESUME_PRIO);
}
else
{
if (ptcb->osTCBStat & EMOS_STAT_SUSPEND)
{
/* Task must be suspended */
if (((ptcb->osTCBStat &= ~EMOS_STAT_SUSPEND) == EMOS_STAT_RDY) && /* Remove suspension */
(ptcb->osTCBDly == 0))
{
/* Must not be delayed*/
gEmosRdyGrp |= ptcb->osTCBBitY; /* Make task ready to run */
gEmosRdyTbl[ptcb->osTCBY] |= ptcb->osTCBBitX;
EMOS_EXIT_CRITICAL();
emosSched();
}
else
{
EMOS_EXIT_CRITICAL();
}
return (EMOS_NO_ERR);
}
else
{
EMOS_EXIT_CRITICAL();
return (EMOS_TASK_NOT_SUSPENDED);
}
}
}
#endif
/**********************************************************************************************************
* STACK CHECKING
* Description: This function is called to check the amount of free memory left on the specified task's
* stack.
* Arguments : prio is the task priority
* pdata is a pointer to a data structure of type EMOS_STK_DATA.
* Returns : EMOS_NO_ERR upon success
* EMOS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
* (i.e. > EMOS_LOWEST_PRIO) or, you have not specified EMOS_PRIO_SELF.
* EMOS_TASK_NOT_EXIST if the desired task has not been created
* EMOS_TASK_OPT_ERR if you did NOT specified EMOS_TASK_OPT_STK_CHK when the task was created
**********************************************************************************************************/
#if EMOS_TASK_CREATE_EXT_EN
uint8 emosTaskStkChk (uint8 prio, EMOS_STK_DATA_T *pdata)
{
EMOS_TCB_T* ptcb = NULL;
EMOS_STK* pchk = NULL;
uint32 free;
uint32 size;
pdata->osFree = 0; /* Assume failure, set to 0 size */
pdata->osUsed = 0;
if (prio > EMOS_LOWEST_PRIO && prio != EMOS_PRIO_SELF)
{ /* Make sure task priority is valid */
return (EMOS_PRIO_INVALID);
}
EMOS_ENTER_CRITICAL();
if (prio == EMOS_PRIO_SELF)
{ /* See if check for SELF*/
prio = gEmosTCBCur->osTCBPrio;
}
ptcb = gEmosTCBPrioTbl[prio];
if (ptcb == (EMOS_TCB_T *)0)
{
/* Make sure task exist*/
EMOS_EXIT_CRITICAL();
return (EMOS_TASK_NOT_EXIST);
}
if ((ptcb->osTCBOpt & EMOS_TASK_OPT_STK_CHK) == 0)
{ /* Make sure stack checking option is set */
EMOS_EXIT_CRITICAL();
return (EMOS_TASK_OPT_ERR);
}
free = 0;
size = ptcb->osTCBStkSize;
pchk = ptcb->osTCBStkBottom;
EMOS_EXIT_CRITICAL();
#if EMOS_STK_GROWTH == 1
while (*pchk++ == 0)
{
/* Compute the number of zero entries on the stk */
free++;
}
#else
while (*pchk-- == 0)
{
free++;
}
#endif
pdata->osFree = free * sizeof(EMOS_STK); /* Compute number of free bytes on the stack */
pdata->osUsed = (size - free) * sizeof(EMOS_STK); /* Compute number of bytes used on the stack */
return (EMOS_NO_ERR);
}
#endif
/*********************************************************************************************************
* SUSPEND A TASK
* Description: This function is called to suspend a task. The task can be the calling task if the
* priority passed to OSTaskSuspend() is the priority of the calling task or EMOS_PRIO_SELF.
* Arguments : prio is the priority of the task to suspend. If you specify EMOS_PRIO_SELF, the
* calling task will suspend itself and rescheduling will occur.
* Returns : EMOS_NO_ERR if the requested task is suspended
* EMOS_TASK_SUSPEND_IDLE if you attempted to suspend the idle task which is not allowed.
* EMOS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
* (i.e. >= EMOS_LOWEST_PRIO) or, you have not specified EMOS_PRIO_SELF.
* EMOS_TASK_SUSPEND_PRIO if the task to suspend does not exist
* Note : You should use this function with great care. If you suspend a task that is waiting for
* an event (i.e. a message, a semaphore, a queue ...) you will prevent this task from
* running when the event arrives.
**********************************************************************************************************/
#if EMOS_TASK_SUSPEND_EN
uint8 emosTaskSuspend (uint8 prio)
{
bool self;
EMOS_TCB_T* ptcb = NULL;
if (prio == EMOS_IDLE_PRIO)
{ /* Not allowed to suspend idle task*/
return (EMOS_TASK_SUSPEND_IDLE);
}
if (prio >= EMOS_LOWEST_PRIO && prio != EMOS_PRIO_SELF)
{
/* Task priority invalid*/
return (EMOS_PRIO_INVALID);
}
EMOS_ENTER_CRITICAL();
if (prio == EMOS_PRIO_SELF)
{ /* See if suspend SELF*/
prio = gEmosTCBCur->osTCBPrio;
self = EMOS_TRUE;
}
else if (prio == gEmosTCBCur->osTCBPrio)
{ /* See if suspending self*/
self = EMOS_TRUE;
}
else
{
self = EMOS_FALSE; /* No suspending another task */
}
if ((ptcb = gEmosTCBPrioTbl[prio]) == (EMOS_TCB_T *)0)
{ /* Task to suspend must exist */
EMOS_EXIT_CRITICAL();
return (EMOS_TASK_SUSPEND_PRIO);
}
else
{
if ((gEmosRdyTbl[ptcb->osTCBY] &= ~ptcb->osTCBBitX) == 0)
{
/* Make task not ready*/
gEmosRdyGrp &= ~ptcb->osTCBBitY;
}
ptcb->osTCBStat |= EMOS_STAT_SUSPEND; /* Status of task is 'SUSPENDED'*/
EMOS_EXIT_CRITICAL();
if (self == EMOS_TRUE)
{
/*Context switch only if SELF*/
emosSched();
}
return (EMOS_NO_ERR);
}
}
#endif
/**********************************************************************************************************
* QUERY A TASK
* Description: This function is called to obtain a copy of the desired task's TCB.
* Arguments : prio is the priority of the task to obtain information from.
* Returns : EMOS_NO_ERR if the requested task is suspended
* EMOS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
* (i.e. > EMOS_LOWEST_PRIO) or, you have not specified EMOS_PRIO_SELF.
* EMOS_PRIO_ERR if the desired task has not been created
**********************************************************************************************************/
uint8 emosTaskQuery (uint8 prio, EMOS_TCB_T *pdata)
{
EMOS_TCB_T* ptcb = NULL;
if (prio > EMOS_LOWEST_PRIO && prio != EMOS_PRIO_SELF)
{
/* Task priority INvalid*/
return (EMOS_PRIO_INVALID);
}
EMOS_ENTER_CRITICAL();
if (prio == EMOS_PRIO_SELF)
{
/* See if suspend SELF*/
prio = gEmosTCBCur->osTCBPrio;
}
if ((ptcb = gEmosTCBPrioTbl[prio]) == (EMOS_TCB_T *)0)
{
/* Task to query must exist*/
EMOS_EXIT_CRITICAL();
return (EMOS_PRIO_ERR);
}
*pdata = *ptcb; /* Copy TCB into user storage area*/
EMOS_EXIT_CRITICAL();
return (EMOS_NO_ERR);
}
/*
* Please add "$" around "Id" and "Log".
* $Id$
* $Log$
*
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -