📄 os_task.lst
字号:
405 * b) by removing it from any wait lists
406 * c) by preventing OSTimeTick() from making the task ready to run.
407 * The task can then be 'unlinked' from the miscellaneous structures in uC/OS-II.
408 * 2) The function OS_Dummy() is called after OS_EXIT_CRITICAL() because, on most processors,
409 * the next instruction following the enable interrupt instruction is ignored.
410 * 3) An ISR cannot delete a task.
411 * 4) The lock nesting counter is incremented because, for a brief instant, if the current
412 * task is being deleted, the current task would not be able to be rescheduled because it
413 * is removed from the ready list. Incrementing the nesting counter prevents another task
414 * from being schedule. This means that an ISR would return to the current task which is
415 * being deleted. The rest of the deletion would thus be able to be completed.
416 *********************************************************************************************************
417 */
418
419 #if OS_TASK_DEL_EN > 0
INT8U OSTaskDel (INT8U prio) reentrant
{
#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
OS_FLAG_NODE *pnode;
#endif
C51 COMPILER V8.17 OS_TASK 03/26/2009 14:24:25 PAGE 8
OS_TCB *ptcb;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
if (OSIntNesting > 0) { /* See if trying to delete from ISR */
return (OS_ERR_TASK_DEL_ISR);
}
if (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to delete idle task */
return (OS_ERR_TASK_DEL_IDLE);
}
#if OS_ARG_CHK_EN > 0
if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */
if (prio != OS_PRIO_SELF) {
return (OS_ERR_PRIO_INVALID);
}
}
#endif
/*$PAGE*/
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF) { /* See if requesting to delete self */
prio = OSTCBCur->OSTCBPrio; /* Set priority to delete to current */
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0) { /* Task to delete must exist */
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_EXIST);
}
if (ptcb == OS_TCB_RESERVED) { /* Must not be assigned to Mutex */
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_DEL);
}
OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX;
if (OSRdyTbl[ptcb->OSTCBY] == 0) { /* Make task not ready */
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
#if (OS_EVENT_EN)
if (ptcb->OSTCBEventPtr != (OS_EVENT *)0) {
OS_EventTaskRemove(ptcb, ptcb->OSTCBEventPtr); /* Remove this task from any event wait list */
}
#if (OS_EVENT_MULTI_EN > 0)
if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0) { /* Remove this task from any events' wait lists*/
OS_EventTaskRemoveMulti(ptcb, ptcb->OSTCBEventMultiPtr);
}
#endif
#endif
#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
pnode = ptcb->OSTCBFlagNode;
if (pnode != (OS_FLAG_NODE *)0) { /* If task is waiting on event flag */
OS_FlagUnlink(pnode); /* Remove from wait list */
}
#endif
ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from updating */
ptcb->OSTCBStat = OS_STAT_RDY; /* Prevent task from being resumed */
ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
C51 COMPILER V8.17 OS_TASK 03/26/2009 14:24:25 PAGE 9
if (OSLockNesting < 255u) { /* Make sure we don't context switch */
OSLockNesting++;
}
OS_EXIT_CRITICAL(); /* Enabling INT. ignores next instruc. */
OS_Dummy(); /* ... Dummy ensures that INTs will be */
OS_ENTER_CRITICAL(); /* ... disabled HERE! */
if (OSLockNesting > 0) { /* Remove context switch lock */
OSLockNesting--;
}
OSTaskDelHook(ptcb); /* Call user defined hook */
OSTaskCtr--; /* One less task being managed */
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Clear old priority entry */
if (ptcb->OSTCBPrev == (OS_TCB *)0) { /* Remove from TCB chain */
ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
OSTCBList = ptcb->OSTCBNext;
} else {
ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
}
ptcb->OSTCBNext = OSTCBFreeList; /* Return TCB to free TCB list */
OSTCBFreeList = ptcb;
#if OS_TASK_NAME_SIZE > 1
ptcb->OSTCBTaskName[0] = '?'; /* Unknown name */
ptcb->OSTCBTaskName[1] = OS_ASCII_NUL;
#endif
OS_EXIT_CRITICAL();
if (OSRunning == OS_TRUE) {
OS_Sched(); /* Find new highest priority task */
}
return (OS_ERR_NONE);
}
#endif
519 /*$PAGE*/
520 /*
521 *********************************************************************************************************
522 * REQUEST THAT A TASK DELETE ITSELF
523 *
524 * Description: This function is used to:
525 * a) notify a task to delete itself.
526 * b) to see if a task requested that the current task delete itself.
527 * This function is a little tricky to understand. Basically, you have a task that needs
528 * to be deleted however, this task has resources that it has allocated (memory buffers,
529 * semaphores, mailboxes, queues etc.). The task cannot be deleted otherwise these
530 * resources would not be freed. The requesting task calls OSTaskDelReq() to indicate that
531 * the task needs to be deleted. Deleting of the task is however, deferred to the task to
532 * be deleted. For example, suppose that task #10 needs to be deleted. The requesting task
533 * example, task #5, would call OSTaskDelReq(10). When task #10 gets to execute, it calls
534 * this function by specifying OS_PRIO_SELF and monitors the returned value. If the return
535 * value is OS_ERR_TASK_DEL_REQ, another task requested a task delete. Task #10 would look li
-ke
536 * this:
537 *
538 * void Task(void *p_arg)
539 * {
540 * .
541 * .
542 * while (1) {
543 * OSTimeDly(1);
544 * if (OSTaskDelReq(OS_PRIO_SELF) == OS_ERR_TASK_DEL_REQ) {
545 * Release any owned resources;
546 * De-allocate any dynamic memory;
547 * OSTaskDel(OS_PRIO_SELF);
C51 COMPILER V8.17 OS_TASK 03/26/2009 14:24:25 PAGE 10
548 * }
549 * }
550 * }
551 *
552 * Arguments : prio is the priority of the task to request the delete from
553 *
554 * Returns : OS_ERR_NONE if the task exist and the request has been registered
555 * OS_ERR_TASK_NOT_EXIST if the task has been deleted. This allows the caller to know whethe
-r
556 * the request has been executed.
557 * OS_ERR_TASK_DEL if the task is assigned to a Mutex.
558 * OS_ERR_TASK_DEL_IDLE if you requested to delete uC/OS-II's idle task
559 * OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
560 * (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
561 * OS_ERR_TASK_DEL_REQ if a task (possibly another task) requested that the running task be
562 * deleted.
563 *********************************************************************************************************
564 */
565 /*$PAGE*/
566 #if OS_TASK_DEL_EN > 0
INT8U OSTaskDelReq (INT8U prio) reentrant
{
INT8U stat;
OS_TCB *ptcb;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
if (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to delete idle task */
return (OS_ERR_TASK_DEL_IDLE);
}
#if OS_ARG_CHK_EN > 0
if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */
if (prio != OS_PRIO_SELF) {
return (OS_ERR_PRIO_INVALID);
}
}
#endif
if (prio == OS_PRIO_SELF) { /* See if a task is requesting to ... */
OS_ENTER_CRITICAL(); /* ... this task to delete itself */
stat = OSTCBCur->OSTCBDelReq; /* Return request status to caller */
OS_EXIT_CRITICAL();
return (stat);
}
OS_ENTER_CRITICAL();
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0) { /* Task to delete must exist */
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_EXIST); /* Task must already be deleted */
}
if (ptcb == OS_TCB_RESERVED) { /* Must NOT be assigned to a Mutex */
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_DEL);
}
ptcb->OSTCBDelReq = OS_ERR_TASK_DEL_REQ; /* Set flag indicating task to be DEL. */
OS_EXIT_CRITICAL();
return (OS_ERR_NONE);
}
#endif
608 /*$PAGE*/
C51 COMPILER V8.17 OS_TASK 03/26/2009 14:24:25 PAGE 11
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -