📄 os_task.src
字号:
; * memory locations. 'pstk' MUST point to a valid 'free' data item.
; *
; * prio is the task's priority. A unique priority MUST be assigned to each task and the
; * lower the number, the higher the priority.
; *
; * id is the task's ID (0..65535)
; *
; * pbos is a pointer to the task's bottom of stack. If the configuration constant
; * OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
; * memory to low memory). 'pbos' will thus point to the LOWEST (valid) memory
; * location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the
; * HIGHEST memory location of the stack and the stack will grow with increasing
; * memory locations. 'pbos' MUST point to a valid 'free' data item.
; *
; * stk_size is the size of the stack in number of elements. If OS_STK is set to INT8U,
; * 'stk_size' corresponds to the number of bytes available. If OS_STK is set to
; * INT16U, 'stk_size' contains the number of 16-bit entries available. Finally, if
; * OS_STK is set to INT32U, 'stk_size' contains the number of 32-bit entries
; * available on the stack.
; *
; * pext is a pointer to a user supplied memory location which is used as a TCB extension.
; * For example, this user memory can hold the contents of floating-point registers
; * during a context switch, the time each task takes to execute, the number of times
; * the task has been switched-in, etc.
; *
; * opt contains additional information (or options) about the behavior of the task. The
; * LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application
; * specific. See OS_TASK_OPT_??? in uCOS-II.H.
; *
; * Returns : OS_NO_ERR if the function was successful.
; * OS_PRIO_EXIT if the task priority already exist
; * (each task MUST have a unique priority).
; * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
; * (i.e. > OS_LOWEST_PRIO)
; *********************************************************************************************************
; */
; /*$PAGE*/
; #if OS_TASK_CREATE_EXT_EN
; INT8U OSTaskCreateExt (void (*task)(void *pd),
; void *ppdata,
; OS_STK *ptos,
; INT8U prio,
; INT16U id,
; OS_STK *pbos,
; INT32U stk_size,
; void *pext,
; INT16U opt) reentrant
; {
; void *psp;
; INT8U err;
; INT16U i;
; OS_STK *pfill;
;
;
; if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */
; return (OS_PRIO_INVALID);
; }
; OS_ENTER_CRITICAL();
; if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */
; OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the priority to prevent others from doing ... */
; /* ... the same thing until task is created. */
; OS_EXIT_CRITICAL();
;
; if (opt & OS_TASK_OPT_STK_CHK) { /* See if stack checking has been enabled */
; if (opt & OS_TASK_OPT_STK_CLR) { /* See if stack needs to be cleared */
; pfill = pbos; /* Yes, fill the stack with zeros */
; for (i = 0; i < stk_size; i++) {
; #if OS_STK_GROWTH == 1
; *pfill++ = (OS_STK)0;
; #else
; *pfill-- = (OS_STK)0;
; #endif
; }
; }
; }
;
; psp = (void *)OSTaskStkInit(task, ppdata, ptos, opt); /* Initialize the task's stack */
; err = OSTCBInit(prio, psp, pbos, id, stk_size, pext, opt);
; if (err == OS_NO_ERR) {
; OS_ENTER_CRITICAL();
; OSTaskCtr++; /* Increment the #tasks counter */
; OSTaskCreateHook(OSTCBPrioTbl[prio]); /* Call user defined hook */
; OS_EXIT_CRITICAL();
; if (OSRunning) { /* Find highest priority task if multitasking has started */
; OSSched();
; }
; } else {
; OS_ENTER_CRITICAL();
; OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */
; OS_EXIT_CRITICAL();
; }
; return (err);
; } else {
; OS_EXIT_CRITICAL();
; return (OS_PRIO_EXIST);
; }
; }
; #endif
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * DELETE A TASK
; *
; * Description: This function allows you to delete a task. The calling task can delete itself by
; * its own priority number. The deleted task is returned to the dormant state and can be
; * re-activated by creating the deleted task again.
; *
; * Arguments : prio is the priority of the task to delete. Note that you can explicitely delete
; * the current task without knowing its priority level by setting 'prio' to
; * OS_PRIO_SELF.
; *
; * Returns : OS_NO_ERR if the call is successful
; * OS_TASK_DEL_IDLE if you attempted to delete uC/OS-II's idle task
; * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
; * (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
; * OS_TASK_DEL_ERR if the task you want to delete does not exist
; * OS_TASK_DEL_ISR if you tried to delete a task from an ISR
; *
; * Notes : 1) To reduce interrupt latency, OSTaskDel() 'disables' the task:
; * a) by making it not ready
; * b) by removing it from any wait lists
; * c) by preventing OSTimeTick() from making the task ready to run.
; * The task can then be 'unlinked' from the miscellaneous structures in uC/OS-II.
; * 2) The function OSDummy() is called after OS_EXIT_CRITICAL() because, on most processors,
; * the next instruction following the enable interrupt instruction is ignored. You can
; * replace OSDummy() with a macro that basically executes a NO OP (i.e. OS_NOP()). The
; * NO OP macro would avoid the execution time of the function call and return.
; * 3) An ISR cannot delete a task.
; * 4) The lock nesting counter is incremented because, for a brief instant, if the current
; * task is being deleted, the current task would not be able to be rescheduled because it
; * is removed from the ready list. Incrementing the nesting counter prevents another task
; * from being schedule. This means that the ISR would return to the current task which is
; * being deleted. The rest of the deletion would thus be able to be completed.
; *********************************************************************************************************
; */
; /*$PAGE*/
; #if OS_TASK_DEL_EN
; INT8U OSTaskDel (INT8U prio) reentrant
; {
; OS_TCB *ptcb;
; OS_EVENT *pevent;
;
;
; if (prio == OS_IDLE_PRIO) { /* Not allowed to delete idle task */
; return (OS_TASK_DEL_IDLE);
; }
; if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) { /* Task priority valid ? */
; return (OS_PRIO_INVALID);
; }
; OS_ENTER_CRITICAL();
; if (OSIntNesting > 0) { /* See if trying to delete from ISR */
; OS_EXIT_CRITICAL();
; return (OS_TASK_DEL_ISR);
; }
; if (prio == OS_PRIO_SELF) { /* See if requesting to delete self */
; prio = OSTCBCur->OSTCBPrio; /* Set priority to delete to current */
; }
; if ((ptcb = OSTCBPrioTbl[prio]) != (OS_TCB *)0) { /* Task to delete must exist */
; if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) {/* Make task not ready */
; OSRdyGrp &= ~ptcb->OSTCBBitY;
; }
; if ((pevent = ptcb->OSTCBEventPtr) != (OS_EVENT *)0) { /* If task is waiting on event */
; if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) { /* ... remove task from */
; pevent->OSEventGrp &= ~ptcb->OSTCBBitY; /* ... event ctrl block */
; }
; }
; ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from updating */
; ptcb->OSTCBStat = OS_STAT_RDY; /* Prevent task from being resumed */
; OSLockNesting++;
; OS_EXIT_CRITICAL(); /* Enabling INT. ignores next instruc. */
; OSDummy(); /* ... Dummy ensures that INTs will be */
; OS_ENTER_CRITICAL(); /* ... disabled HERE! */
; 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;
; OS_EXIT_CRITICAL();
; OSSched(); /* Find new highest priority task */
; return (OS_NO_ERR);
; } else {
; OS_EXIT_CRITICAL();
; return (OS_TASK_DEL_ERR);
; }
; }
; #endif
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * REQUEST THAT A TASK DELETE ITSELF
; *
; * Description: This function is used to:
; * a) notify a task to delete itself.
; * b) to see if a task requested that the current task delete itself.
; * This function is a little tricky to understand. Basically, you have a task that needs
; * to be deleted however, this task has resources that it has allocated (memory buffers,
; * semaphores, mailboxes, queues etc.). The task cannot be deleted otherwise these
; * resources would not be freed. The requesting task calls OSTaskDelReq() to indicate that
; * the task needs to be deleted. Deleting of the task is however, deferred to the task to
; * be deleted. For example, suppose that task #10 needs to be deleted. The requesting task
; * example, task #5, would call OSTaskDelReq(10). When task #10 gets to execute, it calls
; * this function by specifying OS_PRIO_SELF and monitors the returned value. If the return
; * value is OS_TASK_DEL_REQ, another task requested a task delete. Task #10 would look like
; * this:
; *
; * void Task(void *data)
; * {
; * .
; * .
; * while (1) {
; * OSTimeDly(1);
; * if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) {
; * Release any owned resources;
; * De-allocate any dynamic memory;
; * OSTaskDel(OS_PRIO_SELF);
; * }
; * }
; * }
; *
; * Arguments : prio is the priority of the task to request the delete from
; *
; * Returns : OS_NO_ERR if the task exist and the request has been registered
; * OS_TASK_NOT_EXIST if the task has been deleted. This allows the caller to know whether
; * the request has been executed.
; * OS_TASK_DEL_IDLE if you requested to delete uC/OS-II's idle task
; * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
; * (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
; * OS_TASK_DEL_REQ if a task (possibly another task) requested that the running task be
; * deleted.
; *********************************************************************************************************
; */
; /*$PAGE*/
; #if OS_TASK_DEL_EN
; INT8U OSTaskDelReq (INT8U prio) reentrant
; {
; BOOLEAN stat;
; INT8U err;
; OS_TCB *ptcb;
;
;
; if (prio == OS_IDLE_PRIO) { /* Not allowed to delete idle task */
; return (OS_TASK_DEL_IDLE);
; }
; if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) { /* Task priority valid ? */
; return (OS_PRIO_INVALID);
; }
; 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);
; } 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. */
; err = OS_NO_ERR;
; } else {
; err = OS_TASK_NOT_EXIST; /* Task must be deleted */
; }
; OS_EXIT_CRITICAL();
; return (err);
; }
; }
; #endif
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * 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 : OS_NO_ERR if the requested task is resumed
; * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
; * (i.e. >= OS_LOWEST_PRIO)
; * 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
; *********************************************************************************************************
; */
;
; #if OS_TASK_SUSPEND_EN
; INT8U OSTaskResume (INT8U prio) reentrant
; {
; OS_TCB *ptcb;
;
;
; if (prio >= OS_LOWEST_PRIO) { /* Make sure task priority is valid */
; return (OS_PRIO_INVALID);
; }
; 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 */
; (ptcb->OSTCBDly == 0)) { /* Must not be delayed */
; 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 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -