📄 133.htm
字号:
********************************************************************************************************** <br>
* REQUEST THAT A TASK DELETE ITSELF <br>
* <br>
* Description : This function is used to: <br>
* a) notify a task to delete itself. <br>
* b) to see if a task requested that the current task delete iitself. <br>
* This function is a little tricky to understand. Basically, you have a task that needs <br>
* to be deleted however, this task has resources that it has alloccated (memory buffers, <br>
* semaphores, mailboxes, queues etc.). The task cannot be deletedd otherwise these <br>
* resources would not be freed. The requesting task calls OSTaskDDelReq() to indicate that <br>
* the task needs to be deleted. Deleting of the task is however, deferred to the task to <br>
* be deleted. For example, suppose that task #10 needs to be deleeted. The requesting task <br>
* example #5, would call OSTaskDelReq(10). When task #10 gets to execute, it calls this <br>
* function by specifying OS_PRIO_SELF and monitors the returned vaalue. If the return value <br>
* is OS_TASK_DEL_REQ, another task requested a task delete. Task #10 would look like this: <br>
* <br>
* void OS_FAR Task(void *data) <br>
* { <br>
* . <br>
* . <br>
* while (1) { <br>
* OSTimeDly(1); <br>
* if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) { <br>
* Release any owned resources <br>
* De-allocate any dynamic memory <br>
* OSTaskDel(OS_PRIO_SELF); <br>
* } <br>
* } <br>
* } <br>
* <br>
* Arguments : 'prio' is the priority of the task to request the delete from <br>
* <br>
* <br>
* Returns : if 'prio' is OS_PRIO_SELF: <br>
* returns OS_TASK_DEL_REQ if a task requested to delete SELF <br>
* returns OS_NO_ERR if no task requested to delete SELF <br>
* if 'prio' is other than OS_PRIO_SELF: <br>
* request that the task be deleted <br>
********************************************************************************************************** <br>
*/ <br>
/*$PAGE*/ <br>
UBYTE OSTaskDelReq(UBYTE prio) <br>
{ <br>
BOOLEAN stat; <br>
OS_TCB *ptcb; <br>
<br>
<br>
if (prio == OS_LO_PRIO) { /* Not allowed tto delete idle task */ <br>
return (OS_TASK_DEL_IDLE); <br>
} <br>
if (prio >= OS_MAX_TASKS && prio != OS_PRIO_SELF) { /* Make sure tassk priority is valid */ <br>
return (OS_PRIO_INVALID); <br>
} <br>
if (prio == OS_PRIO_SELF) { /* See if task tto delete is requesting */ <br>
OS_ENTER_CRITICAL(); <br>
stat = OSTCBCur->OSTCBDelReq; /* Return requesst status to caller */ <br>
OS_EXIT_CRITICAL(); <br>
return (stat); <br>
} else { <br>
OS_ENTER_CRITICAL(); <br>
if ((ptcb = OSTCBPrioTbl[prio]) != (OS_TCB *)0) { /* Task to delette must exist */ <br>
ptcb->OSTCBDelReq = OS_TASK_DEL_REQ; /* Set flag indiicating task to be DEL. */ <br>
} <br>
OS_EXIT_CRITICAL(); <br>
return (OS_NO_ERR); <br>
} <br>
} <br>
#endif <br>
/*$PAGE*/ <br>
#if OS_TASK_SUSPEND_EN <br>
/* <br>
********************************************************************************************************** <br>
* SUSPEND A TASK <br>
* <br>
* Description : This function is called to suspend a task. The task can be the calling task if if the <br>
* priority passed to OSTaskSuspend() is the priority of the callinng task. <br>
* Arguments : 'prio' is the priority of the task to suspend. If you speciify OS_PRIO_SELF, the <br>
* calling task will suspend itself and rescheduling willl occur. <br>
* <br>
* Returns : OS_NO_ERR if the requested task is suspended <br>
* OS_TASK_SUSPEND_PRIO if the task to suspend does not exist <br>
* Note : You should use this function with great care. If you suspend a task that is waiting for <br>
* a message you will prevent this task from running when the messaage arrives. <br>
********************************************************************************************************** <br>
*/ <br>
<br>
UBYTE OSTaskSuspend(UBYTE prio) <br>
{ <br>
BOOLEAN self; <br>
OS_TCB *ptcb; <br>
<br>
<br>
if (prio == OS_LO_PRIO) { /* Not allowed tto suspend idle task */ <br>
return (OS_TASK_SUSPEND_IDLE); <br>
} <br>
if (prio >= OS_MAX_TASKS && prio != OS_PRIO_SELF) { /* Make sure tassk priority is valid */ <br>
return (OS_PRIO_INVALID); <br>
} <br>
OS_ENTER_CRITICAL(); <br>
if (prio == OS_PRIO_SELF) { /* See if suspennd SELF */ <br>
prio = OSTCBCur->OSTCBPrio; <br>
self = TRUE; <br>
} else { <br>
self = FALSE; <br>
} <br>
if ((ptcb = OSTCBPrioTbl[prio]) == (OS_TCB *)0) { /* Task to suspend must exist */ <br>
OS_EXIT_CRITICAL(); <br>
return (OS_TASK_SUSPEND_PRIO); <br>
} else { <br>
if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) { /* Make tassk not ready */ <br>
OSRdyGrp &= ~ptcb->OSTCBBitY; <br>
} <br>
ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* Status oof task is 'SUSPENDED' */ <br>
OS_EXIT_CRITICAL(); <br>
if (self == TRUE) { /* Context switch only if SELF */ <br>
OSSched(); <br>
} <br>
return (OS_NO_ERR); <br>
} <br>
} <br>
<br>
<br>
/*$PAGE*/ <br>
/* <br>
********************************************************************************************************** <br>
* RESUME A SUSPENDED TASK <br>
* <br>
* Description : This function is called to resume a previously suspended task. <br>
* Arguments : 'prio' is the priority of the task to resume. <br>
* <br>
* Returns : OS_NO_ERR if the requested task is resumed <br>
* OS_TASK_RESUME_PRIO if the task to resume does not exist <br>
* OS_TASK_NOT_SUSPENDED if the task to resume has not been susppended <br>
********************************************************************************************************** <br>
*/ <br>
<br>
UBYTE OSTaskResume(UBYTE prio) <br>
{ <br>
OS_TCB *ptcb; <br>
<br>
<br>
OS_ENTER_CRITICAL(); <br>
if ((ptcb = OSTCBPrioTbl[prio]) == (OS_TCB *)0) { /* Task to suspend must exist */ <br>
OS_EXIT_CRITICAL(); <br>
return (OS_TASK_RESUME_PRIO); <br>
} else { <br>
if (ptcb->OSTCBStat & OS_STAT_SUSPEND) { /* Tassk must be suspended */ <br>
if ((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Remmove suspension */ <br>
OSRdyGrp |= ptcb->OSTCBBitY; /* Makke task ready to run */ <br>
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; <br>
OS_EXIT_CRITICAL(); <br>
OSSched(); <br>
} else { <br>
OS_EXIT_CRITICAL(); <br>
} <br>
return (OS_NO_ERR); <br>
} else { <br>
OS_EXIT_CRITICAL(); <br>
return (OS_TASK_NOT_SUSPENDED); <br>
} <br>
} <br>
} <br>
#endif <br>
/*$PAGE*/ <br>
/* <br>
********************************************************************************************************** <br>
* DELAY TASK 'n' TICKS (n from 1 to 65535) <br>
********************************************************************************************************** <br>
*/ <br>
<br>
void OSTimeDly(UWORD ticks) <br>
{ <br>
if (ticks > 0) { <br>
OS_ENTER_CRITICAL(); <br>
if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) { /* Dellay current task */ <br>
OSRdyGrp &= ~OSTCBCur->OSTCBBitY; <br>
} <br>
OSTCBCur->OSTCBDly = ticks; /* Loaad ticks in TCB */ <br>
OS_EXIT_CRITICAL(); <br>
OSSched(); <br>
} <br>
} <br>
/*$PAGE*/ <br>
/* <br>
********************************************************************************************************** <br>
* RESUME A DELAYED TASK <br>
********************************************************************************************************** <br>
*/ <br>
*/ <br>
<br>
UBYTE OSTimeDlyResume(UBYTE prio) <br>
{ <br>
OS_TCB *ptcb; <br>
<br>
<br>
OS_ENTER_CRITICAL(); <br>
ptcb = (OS_TCB *)&OSTCBPrioTbl[prio]; <br>
if (ptcb != (OS_TCB *)0) { /* See if such task eexist */ <br>
if (ptcb->OSTCBDly != 0) { /* See if task is dellayed */ <br>
ptcb->OSTCBDly = 0; /* Clear the time dellay */ <br>
if (!(ptcb->OSTCBStat & OS_STAT_SUSPEND)) { /* See if task is reaady to run */ <br>
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready too run */ <br>
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; <br>
OS_EXIT_CRITICAL(); <br>
OSSched(); /* See if this is neww highest priority */ <br>
} else { <br>
OS_EXIT_CRITICAL(); /* Task may be suspennded */ <br>
} <br>
return (OS_NO_ERR); <br>
} else { <br>
OS_EXIT_CRITICAL(); <br>
return (OS_TIME_NOT_DLY); /* Indicate that taskk was not delayed */ <br>
} <br>
} else { <br>
OS_EXIT_CRITICAL(); <br>
return (OS_TASK_NOT_EXIST); /* The task does not exist */ <br>
} <br>
} <br>
/*$PAGE*/ <br>
/* <br>
********************************************************************************************************** <br>
* PROCESS SYSTEM TICK <br>
********************************************************************************************************** <br>
*/ <br>
<br>
void OSTimeTick(void) <br>
{ <br>
OS_TCB *ptcb; <br>
<br>
<br>
ptcb = OSTCBList; /* Point at first TCBB in TCB list */ <br>
while (ptcb->OSTCBPrio != OS_LO_PRIO) { /* Go through all TCBBs in TCB list */ <br>
OS_ENTER_CRITICAL(); <br>
if (ptcb->OSTCBDly != 0) { /* Delayed or waitingg for event with TO */ <br>
if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of tticks to end of delay */ <br>
if (!(ptcb->OSTCBStat & OS_STAT_SUSPEND)) { /* Is task suspennded? */ <br>
OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make taskk Rdy to Run (timed out)*/ <br>
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; <br>
} else { /* Yes, Leave 1 ttick to prevent ... */ <br>
ptcb->OSTCBDly = 1; /* ... loosing thhe task when the ... */ <br>
} /* ... suspensionn is removed. */ <br>
} <br>
} <br>
OS_EXIT_CRITICAL(); <br>
ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */ <br>
} <br>
OS_ENTER_CRITICAL(); <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -