#ifOS_TASK_CHANGE_PRIO_EN >0u
INT8U OSTaskChangePrio(INT8U oldprio,INT8U newprio){#if(OS_EVENT_EN)OS_EVENT *pevent;#if(OS_EVENT_MULTI_EN >0u)OS_EVENT **pevents;#endif#endifOS_TCB *ptcb;INT8U y_new;INT8U x_new;INT8U y_old;OS_PRIO bity_new;OS_PRIO bitx_new;OS_PRIO bity_old;OS_PRIO bitx_old;#ifOS_CRITICAL_METHOD ==3uOS_CPU_SR cpu_sr =0u;/* Storage for CPU status register */#endif/*$PAGE*/#ifOS_ARG_CHK_EN >0uif(oldprio >= OS_LOWEST_PRIO){if(oldprio != OS_PRIO_SELF){return(OS_ERR_PRIO_INVALID);}}if(newprio >= OS_LOWEST_PRIO){return(OS_ERR_PRIO_INVALID);}#endifOS_ENTER_CRITICAL();if(OSTCBPrioTbl[newprio]!=(OS_TCB *)0)/* New priority must not already exist */{OS_EXIT_CRITICAL();return(OS_ERR_PRIO_EXIST);}if(oldprio == OS_PRIO_SELF)/* See if changing self */{oldprio = OSTCBCur->OSTCBPrio;/* Yes, get priority */}ptcb = OSTCBPrioTbl[oldprio];if(ptcb ==(OS_TCB *)0)/* Does task to change exist? */{OS_EXIT_CRITICAL();/* No, can't change its priority! */return(OS_ERR_PRIO);}if(ptcb == OS_TCB_RESERVED)/* Is task assigned to Mutex */{OS_EXIT_CRITICAL();/* No, can't change its priority! */return(OS_ERR_TASK_NOT_EXIST);}#ifOS_LOWEST_PRIO <=63uy_new =(INT8U)(newprio >>3u);/* Yes, compute new TCB fields */x_new =(INT8U)(newprio &0x07u);#elsey_new =(INT8U)((INT8U)(newprio >>4u)&0x0Fu);x_new =(INT8U)(newprio &0x0Fu);#endifbity_new =(OS_PRIO)(1uL<< y_new);bitx_new =(OS_PRIO)(1uL<< x_new);OSTCBPrioTbl[oldprio]=(OS_TCB *)0;/* Remove TCB from old priority */OSTCBPrioTbl[newprio]= ptcb;/* Place pointer to TCB @ new priority */y_old = ptcb->OSTCBY;bity_old = ptcb->OSTCBBitY;bitx_old = ptcb->OSTCBBitX;if((OSRdyTbl[y_old]& bitx_old)!=0u)/* If task is ready make it not */{OSRdyTbl[y_old]&=(OS_PRIO)~bitx_old;if(OSRdyTbl[y_old]==0u){OSRdyGrp &=(OS_PRIO)~bity_old;}OSRdyGrp |= bity_new;/* Make new priority ready to run */OSRdyTbl[y_new]|= bitx_new;}#if(OS_EVENT_EN)pevent = ptcb->OSTCBEventPtr;if(pevent !=(OS_EVENT *)0){pevent->OSEventTbl[y_old]&=(OS_PRIO)~bitx_old;/* Remove old task prio from wait list */if(pevent->OSEventTbl[y_old]==0u){pevent->OSEventGrp &=(OS_PRIO)~bity_old;}pevent->OSEventGrp |= bity_new;/* Add new task prio to wait list */pevent->OSEventTbl[y_new]|= bitx_new;}#if(OS_EVENT_MULTI_EN >0u)if(ptcb->OSTCBEventMultiPtr !=(OS_EVENT **)0){pevents = ptcb->OSTCBEventMultiPtr;pevent =*pevents;while(pevent !=(OS_EVENT *)0){pevent->OSEventTbl[y_old]&=(OS_PRIO)~bitx_old;/* Remove old task prio from wait lists */if(pevent->OSEventTbl[y_old]==0u){pevent->OSEventGrp &=(OS_PRIO)~bity_old;}pevent->OSEventGrp |= bity_new;/* Add new task prio to wait lists */pevent->OSEventTbl[y_new]|= bitx_new;pevents++;pevent =*pevents;}}#endif#endifptcb->OSTCBPrio = newprio;/* Set new task priority */ptcb->OSTCBY = y_new;ptcb->OSTCBX = x_new;ptcb->OSTCBBitY = bity_new;ptcb->OSTCBBitX = bitx_new;OS_EXIT_CRITICAL();if(OSRunning == OS_TRUE){OS_Sched();/* Find new highest priority task */}return(OS_ERR_NONE);}#endif
Task挂起
#ifOS_TASK_SUSPEND_EN >0u
INT8U OSTaskSuspend(INT8U prio){BOOLEAN self;OS_TCB *ptcb;INT8U y;#ifOS_CRITICAL_METHOD ==3u/* Allocate storage for CPU status register */OS_CPU_SR cpu_sr =0u;#endif#ifOS_ARG_CHK_EN >0uif(prio == OS_TASK_IDLE_PRIO)/* Not allowed to suspend idle task */{return(OS_ERR_TASK_SUSPEND_IDLE);}if(prio >= OS_LOWEST_PRIO)/* Task priority valid ? */{if(prio != OS_PRIO_SELF){return(OS_ERR_PRIO_INVALID);}}#endifOS_ENTER_CRITICAL();if(prio == OS_PRIO_SELF)/* See if suspend SELF */{prio = OSTCBCur->OSTCBPrio;self = OS_TRUE;}elseif(prio == OSTCBCur->OSTCBPrio)/* See if suspending self */{self = OS_TRUE;}else{self = OS_FALSE;/* No suspending another task */}ptcb = OSTCBPrioTbl[prio];if(ptcb ==(OS_TCB *)0)/* Task to suspend must exist */{OS_EXIT_CRITICAL();return(OS_ERR_TASK_SUSPEND_PRIO);}if(ptcb == OS_TCB_RESERVED)/* See if assigned to Mutex */{OS_EXIT_CRITICAL();return(OS_ERR_TASK_NOT_EXIST);}y = ptcb->OSTCBY;OSRdyTbl[y]&=(OS_PRIO)~ptcb->OSTCBBitX;/* Make task not ready */if(OSRdyTbl[y]==0u){OSRdyGrp &=(OS_PRIO)~ptcb->OSTCBBitY;}ptcb->OSTCBStat |= OS_STAT_SUSPEND;/* Status of task is 'SUSPENDED' */OS_EXIT_CRITICAL();if(self == OS_TRUE)/* Context switch only if SELF */{OS_Sched();/* Find new highest priority task */}return(OS_ERR_NONE);}#endif
Task恢复
#ifOS_TASK_SUSPEND_EN >0u
INT8U OSTaskResume(INT8U prio){OS_TCB *ptcb;#ifOS_CRITICAL_METHOD ==3u/* Storage for CPU status register */OS_CPU_SR cpu_sr =0u;#endif#ifOS_ARG_CHK_EN >0uif(prio >= OS_LOWEST_PRIO)/* Make sure task priority is valid */{return(OS_ERR_PRIO_INVALID);}#endifOS_ENTER_CRITICAL();ptcb = OSTCBPrioTbl[prio];if(ptcb ==(OS_TCB *)0)/* Task to suspend must exist */{OS_EXIT_CRITICAL();return(OS_ERR_TASK_RESUME_PRIO);}if(ptcb == OS_TCB_RESERVED)/* See if assigned to Mutex */{OS_EXIT_CRITICAL();return(OS_ERR_TASK_NOT_EXIST);}if((ptcb->OSTCBStat & OS_STAT_SUSPEND)!= OS_STAT_RDY)/* Task must be suspended */{ptcb->OSTCBStat &=(INT8U)~(INT8U)OS_STAT_SUSPEND;/* Remove suspension */if(ptcb->OSTCBStat == OS_STAT_RDY)/* See if task is now ready */{if(ptcb->OSTCBDly ==0u){OSRdyGrp |= ptcb->OSTCBBitY;/* Yes, Make task ready to run */OSRdyTbl[ptcb->OSTCBY]|= ptcb->OSTCBBitX;OS_EXIT_CRITICAL();if(OSRunning == OS_TRUE){OS_Sched();/* Find new highest priority task */}}else{OS_EXIT_CRITICAL();}}else/* Must be pending on event */{OS_EXIT_CRITICAL();}return(OS_ERR_NONE);}OS_EXIT_CRITICAL();return(OS_ERR_TASK_NOT_SUSPENDED);}#endif
Task信息获取
#ifOS_TASK_QUERY_EN >0u
INT8U OSTaskQuery(INT8U prio,OS_TCB *p_task_data){OS_TCB *ptcb;#ifOS_CRITICAL_METHOD ==3u/* Allocate storage for CPU status register */OS_CPU_SR cpu_sr =0u;#endif#ifOS_ARG_CHK_EN >0uif(prio > OS_LOWEST_PRIO)/* Task priority valid ? */{if(prio != OS_PRIO_SELF){return(OS_ERR_PRIO_INVALID);}}if(p_task_data ==(OS_TCB *)0)/* Validate 'p_task_data' */{return(OS_ERR_PDATA_NULL);}#endifOS_ENTER_CRITICAL();if(prio == OS_PRIO_SELF)/* See if suspend SELF */{prio = OSTCBCur->OSTCBPrio;}ptcb = OSTCBPrioTbl[prio];if(ptcb ==(OS_TCB *)0)/* Task to query must exist */{OS_EXIT_CRITICAL();return(OS_ERR_PRIO);}if(ptcb == OS_TCB_RESERVED)/* Task to query must not be assigned to a Mutex */{OS_EXIT_CRITICAL();return(OS_ERR_TASK_NOT_EXIST);}/* Copy TCB into user storage area */OS_MemCopy((INT8U *)p_task_data,(INT8U *)ptcb,sizeof(OS_TCB));OS_EXIT_CRITICAL();return(OS_ERR_NONE);}#endif
Task调度器上锁(os_core.c)
#ifOS_SCHED_LOCK_EN >0uvoidOSSchedLock(void){#ifOS_CRITICAL_METHOD ==3u/* Allocate storage for CPU status register */OS_CPU_SR cpu_sr =0u;#endifif(OSRunning == OS_TRUE)/* Make sure multitasking is running */{OS_ENTER_CRITICAL();if(OSIntNesting ==0u)/* Can't call from an ISR */{if(OSLockNesting <255u)/* Prevent OSLockNesting from wrapping back to 0 */{OSLockNesting++;/* Increment lock nesting level */}}OS_EXIT_CRITICAL();}}#endif
Task调度器开锁(os_core.c)
#ifOS_SCHED_LOCK_EN >0uvoidOSSchedUnlock(void){#ifOS_CRITICAL_METHOD ==3u/* Allocate storage for CPU status register */OS_CPU_SR cpu_sr =0u;#endifif(OSRunning == OS_TRUE)/* Make sure multitasking is running */{OS_ENTER_CRITICAL();if(OSIntNesting ==0u)/* Can't call from an ISR */{if(OSLockNesting >0u)/* Do not decrement if already 0 */{OSLockNesting--;/* Decrement lock nesting level */if(OSLockNesting ==0u)/* See if scheduler is enabled */{OS_EXIT_CRITICAL();OS_Sched();/* See if a HPT is ready */}else{OS_EXIT_CRITICAL();}}else{OS_EXIT_CRITICAL();}}else{OS_EXIT_CRITICAL();}}}#endif