📄 ucos.c
字号:
* returns OS_TASK_DEL_REQ if a task requested to delete SELF
* returns OS_NO_ERR if no task requested to delete SELF
* if 'prio' is other than OS_PRIO_SELF:
* request that the task be deleted
*********************************************************************************************************
*/
/*$PAGE*/
UBYTE OSTaskDelReq(UBYTE prio)
{
BOOLEAN stat;
OS_TCB *ptcb;
if (prio == OS_LO_PRIO) { /* Not allowed to delete idle task */
return (OS_TASK_DEL_IDLE);
}
if (prio >= OS_MAX_TASKS && prio != OS_PRIO_SELF) { /* Make sure task priority is valid */
return (OS_PRIO_INVALID);
}
if (prio == OS_PRIO_SELF) { /* See if task to delete is requesting */
OS_ENTER_CRITICAL();
stat = OSTCBCur->OSTCBDelReq; /* Return request status to caller */
OS_EXIT_CRITICAL();
return (stat);
} else {
OS_ENTER_CRITICAL();
if ((ptcb = OSTCBPrioTbl[prio]) != (OS_TCB *)0) { /* Task to delete must exist */
ptcb->OSTCBDelReq = OS_TASK_DEL_REQ; /* Set flag indicating task to be DEL. */
}
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
}
#endif
/*$PAGE*/
#if OS_TASK_SUSPEND_EN
/*
*********************************************************************************************************
* SUSPEND A TASK
*
* Description : This function is called to suspend a task. The task can be the calling task if if the
* priority passed to OSTaskSuspend() is the priority of the calling task.
* Arguments : 'prio' is the priority of the task to suspend. If you specify OS_PRIO_SELF, the
* calling task will suspend itself and rescheduling will occur.
*
* Returns : OS_NO_ERR if the requested task is suspended
* OS_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
* a message you will prevent this task from running when the message arrives.
*********************************************************************************************************
*/
UBYTE OSTaskSuspend(UBYTE prio)
{
BOOLEAN self;
OS_TCB *ptcb;
if (prio == OS_LO_PRIO) { /* Not allowed to suspend idle task */
return (OS_TASK_SUSPEND_IDLE);
}
if (prio >= OS_MAX_TASKS && prio != OS_PRIO_SELF) { /* Make sure task priority is valid */
return (OS_PRIO_INVALID);
}
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF) { /* See if suspend SELF */
prio = OSTCBCur->OSTCBPrio;
self = TRUE;
} else {
self = FALSE;
}
if ((ptcb = OSTCBPrioTbl[prio]) == (OS_TCB *)0) { /* Task to suspend must exist */
OS_EXIT_CRITICAL();
return (OS_TASK_SUSPEND_PRIO);
} else {
if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) { /* Make task not ready */
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* Status of task is 'SUSPENDED' */
OS_EXIT_CRITICAL();
if (self == TRUE) { /* Context switch only if SELF */
OSSched();
}
return (OS_NO_ERR);
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* RESUME A SUSPENDED TASK
*
* Description : This function is called to resume a previously suspended task.
* Arguments : 'prio' is the priority of the task to resume.
*
* Returns : OS_NO_ERR if the requested task is resumed
* OS_TASK_RESUME_PRIO if the task to resume does not exist
* OS_TASK_NOT_SUSPENDED if the task to resume has not been suspended
*********************************************************************************************************
*/
UBYTE OSTaskResume(UBYTE prio)
{
OS_TCB *ptcb;
OS_ENTER_CRITICAL();
if ((ptcb = OSTCBPrioTbl[prio]) == (OS_TCB *)0) { /* Task to suspend must exist */
OS_EXIT_CRITICAL();
return (OS_TASK_RESUME_PRIO);
} else {
if (ptcb->OSTCBStat & OS_STAT_SUSPEND) { /* Task must be suspended */
if ((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Remove suspension */
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
OSSched();
} else {
OS_EXIT_CRITICAL();
}
return (OS_NO_ERR);
} else {
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_SUSPENDED);
}
}
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* DELAY TASK 'n' TICKS (n from 1 to 65535)
*
* Description : This function is called to delay execution of the currently running task until some time
* expires. If the specified delay is greater than 0 then a context switch will result.
* Arguments : 'ticks' is the time delay that the task will be suspended in 'ticks'. Note that by
* specifying 0, the task will not be delayed.
*********************************************************************************************************
*/
void OSTimeDly(UWORD ticks)
{
if (ticks > 0) { /* 0 means no delay! */
OS_ENTER_CRITICAL();
if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) { /* Delay current task */
OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
}
OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */
OS_EXIT_CRITICAL();
OSSched(); /* Find next task to run! */
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* RESUME A DELAYED TASK
*********************************************************************************************************
*/
UBYTE OSTimeDlyResume(UBYTE prio)
{
OS_TCB *ptcb;
OS_ENTER_CRITICAL();
ptcb = (OS_TCB *)OSTCBPrioTbl[prio]; /* Make sure that task exist */
if (ptcb != (OS_TCB *)0) {
if (ptcb->OSTCBDly != 0) { /* See if task is delayed */
ptcb->OSTCBDly = 0; /* Clear the time delay */
if (!(ptcb->OSTCBStat & OS_STAT_SUSPEND)) { /* See if task is ready to run */
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
OSSched(); /* See if this is new highest priority */
} else {
OS_EXIT_CRITICAL(); /* Task may be suspended */
}
return (OS_NO_ERR);
} else {
OS_EXIT_CRITICAL();
return (OS_TIME_NOT_DLY); /* Indicate that task was not delayed */
}
} else {
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_EXIST); /* The task does not exist */
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* PROCESS SYSTEM TICK
*********************************************************************************************************
*/
void OSTimeTick(void)
{
OS_TCB *ptcb;
ptcb = OSTCBList; /* Point at first TCB in TCB list */
while (ptcb->OSTCBPrio != OS_LO_PRIO) { /* Go through all TCBs in TCB list */
OS_ENTER_CRITICAL();
if (ptcb->OSTCBDly != 0) { /* Delayed or waiting for event with TO */
if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of ticks to end of delay */
if (!(ptcb->OSTCBStat & OS_STAT_SUSPEND)) { /* Is task suspended? */
OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make task Rdy to Run (timed out)*/
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
} else { /* Yes, Leave 1 tick to prevent ... */
ptcb->OSTCBDly = 1; /* ... loosing the task when the ... */
} /* ... suspension is removed. */
}
}
OS_EXIT_CRITICAL();
ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */
}
OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter */
OSTime++;
OS_EXIT_CRITICAL();
}
/*$PAGE*/
/*
*********************************************************************************************************
* SET SYSTEM CLOCK
*********************************************************************************************************
*/
void OSTimeSet(ULONG ticks)
{
OS_ENTER_CRITICAL();
OSTime = ticks;
OS_EXIT_CRITICAL();
}
/*
*********************************************************************************************************
* GET CURRENT SYSTEM TIME
*********************************************************************************************************
*/
ULONG OSTimeGet(void)
{
ULONG ticks;
OS_ENTER_CRITICAL();
ticks = OSTime;
OS_EXIT_CRITICAL();
return (ticks);
}
/*$PAGE*/
#if OS_SEM_EN
/*
*********************************************************************************************************
* INITIALIZE SEMAPHORE
*********************************************************************************************************
*/
OS_EVENT *OSSemCreate(UWORD cnt)
{
OS_EVENT *pevent;
OS_ENTER_CRITICAL();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -