void OS_Sched (void) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif INT8U y; OS_ENTER_CRITICAL(); //为实现任务切换,OSTCBHighRdy必须指向优先级最高的那个任务控制块OS_TCB,这是通过将 if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Sched. only if all ISRs done & not locked */ //如果函数不是在中断服务子程序中调用的,且调度允许的,则任务调度函数将找出进入就绪态的 //最高优先级任务,进入就绪态的任务在就绪表中OSRdyTbl[ ]中相应位置位. y = OSUnMapTbl[OSRdyGrp]; /* Get pointer to HPT ready to run */ OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); //找到最高优先级任务后,函数检查这个优先级最高的任务是否是当前正在运行的任务,以避免不 //必要的任务调度,多花时间 if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */ //为实现任务切换,OSTCBHighRdy必须指向优先级最高的那个任务控制块OS_TCB,这是通过将 //以OSPrioHighRdy为下标的OSTCBPrioTbl[]数组中的那个元素赋给OSTCBHighRdy来实现的 OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; OSCtxSwCtr++; //统计计数器OSCtxSwCtr加1,以跟踪任务切换次数 OS_TASK_SW(); //最后宏调用OS_TASK_SW()来完成实际上的任务切换 } } OS_EXIT_CRITICAL(); }
void OS_STOP() { OS_ENTER_CRITICAL(); ++OSTerminateTickW32; ++OSTerminateCtxSwW32; OS_TASK_SW(); OS_EXIT_CRITICAL(); Sleep(1000/OS_TICKS_PER_SEC); }
/*$PAGE*/ void *OSMboxPend (INT8U pevent, INT16U timeout, INT8U *perr) // SW/HW RTOS { void *pmsg; Xuint64 Reg64Value_o; Xuint64 Reg64Value_i, Reg64Value_i5; Reg64Value_o.Lower = 0; Reg64Value_o.Upper = 0; Reg64Value_i.Lower = 0; Reg64Value_i.Upper = 0; Reg64Value_i5.Lower = 0; Reg64Value_i5.Upper = 0; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (perr == (INT8U *)0) { /* Validate 'perr' */ return ((void *)0); } if (pevent == 0) { /* Validate 'pevent' */ *perr = OS_ERR_PEVENT_NULL; return ((void *)0); } #endif if (OSIntNesting > 0) { /* See if called from ISR ... */ *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ return ((void *)0); } if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ return ((void *)0); } Reg64Value_o.Lower |= timeout; Reg64Value_o.Lower = (Reg64Value_o.Lower << 8) | pevent; Reg64Value_o.Lower = (Reg64Value_o.Lower << 8) | HWRTOS_MBOX_PEND; OS_ENTER_CRITICAL(); HWRTOS_WriteSlaveReg0(hwrtos_addrp, &Reg64Value_o); HWRTOS_ReadSlaveReg4(hwrtos_addrp, &Reg64Value_i); //OS_EXIT_CRITICAL(); if ((Reg64Value_i.Lower & 0x00010000) == 0x00010000) { //OS_ENTER_CRITICAL(); OSCurPrioStkPtr = &OSStkPtr[(Reg64Value_i.Lower & 0xFF000000) >> 24]; OSHiPrioStkPtr = &OSStkPtr[(Reg64Value_i.Upper & 0x000000FF)]; OS_TASK_SW(); OS_EXIT_CRITICAL(); //return from function will enable interrupt }
//////////////////////////////////////////////////////////// // Function name: Schedule // Description: Schedule a task queue to run // Parameter: none // Return value: Whether the operation succeeded // Function calls: none // //////////////////////////////////////////////////////////// StatusType Schedule(void) { //static sint8_least tmpMaxTask = 1; TCB_Type *tmpTCB; #ifdef _OS1_DEBUG_ for(tmpIndex = 0; tmpIndex < OS_MAX_RESOURCE; tmpIndex++) { if(Os_Res_Owner[tmpIndex] == Os_TCBCurr->taskID) { //Resource not released return E_OS_RESOURCE; } } if(InterruptState == TRUE) { //Call in interrupt return E_OS_CALLEVEL; } #endif //没有合适的则运行优先级最低的任务 Os_TCBReady = &Os_TCB[0]; for(tmpTCB=&Os_TCB[OS_MAX_TASK]; tmpTCB->taskID>0; tmpTCB--) { if(tmpTCB->state == READY) { tmpTCB->state = RUNNING; //Os_TCBCurr = &Os_TCB[tmpIndex]; Os_TCBReady = tmpTCB; break; } } //当前任务正在进行,触发软中断进行任务切换 if(Os_TCBCurr->state == RUNNING) { Os_TCBCurr->state = READY; Os_TCBCurr=Os_TCBReady; Os_TCBReady->state = RUNNING; SuspendAllInterrupts(); OS_TASK_SW(); ResumeAllInterrupts(); } return E_OK; }
void OS_Sched (void) { OS_CPU_SR cpu_sr = 0u; OS_ENTER_CRITICAL(); if (OSIntNesting == 0u) { /* Schedule only if all ISRs done and ... */ if (OSLockNesting == 0u) { /* ... scheduler is not locked */ OS_SchedNew(); OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */ OSCtxSwCtr++; /* Increment context switch counter */ OS_TASK_SW(); /* Perform a context switch */ } } } OS_EXIT_CRITICAL(); }
void OS_Sched (void) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif INT8U y; OS_ENTER_CRITICAL(); if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Sched. only if all ISRs done & not locked */ y = OSUnMapTbl[OSRdyGrp]; /* Get pointer to HPT ready to run */ OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */ OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; OSCtxSwCtr++; /* Increment context switch counter */ OS_TASK_SW(); /* Perform a context switch */ } } OS_EXIT_CRITICAL(); }