void OSCtxSw(void) { asm("\ lea nextstart,%eax;\ push %eax;\ pushf;\ pusha;\ movl _OSTCBCur,%ebx;\ movl %esp,(%ebx);\ "); OSTaskSwHook(); OSTCBCur = OSTCBHighRdy; OSPrioCur = OSPrioHighRdy; asm("\ movl _OSTCBCur,%ebx;\ movl (%ebx),%esp;\ popa;\ popf;\ ret\ "); asm("nextstart:"); return; }
void OSIntCtxSw (void) { OSTaskSwHook(); OSTCBCur = OSTCBHighRdy; OSPrioCur = OSPrioHighRdy; OSIntCtxRestore(OSTCBHighRdy->OSTCBStkPtr); }
//OSStartHighRdy:让优先级最高的任务运行函数--------------------------------* //功 能:让优先级最高的就绪态任务开始运行 * //参 数:无 * //返 回:无 * //-------------------------------------------------------------------------* void OSStartHighRdy(void) { OSTaskSwHook(); OSRunning = 1; asm{ ldx OSTCBCur //将TCB的地址给X lds 0,X //将值给SP pula staa $30 //恢复页面寄存器 nop //延时 rti } }
void OSStartHighRdy(void) { OSTaskSwHook(); OSRunning = TRUE; asm("\ movl %eax,_OSRunning;\ movl _OSTCBCur,%ebx;\ movl (%ebx),%esp;\ popa;\ popf;\ ret\ "); }
//OSIntCtxSw:中断级任务切换函数--------------------------------------------* //功 能:如果在中断服务结束时,中断中激活了更高优先级的任务,则调用该函数 * //参 数:无 * //返 回:无 * //-------------------------------------------------------------------------* void OSIntCtxSw(void) { OSTaskSwHook(); OSTCBCur = OSTCBHighRdy; //Change OSTCBCur and OSPrioCur OSPrioCur = OSPrioHighRdy; asm{ ldx OSTCBCur //get the new task's TCB's address lds 0,x pula staa $30 nop //retore ppage from stack rti } }
void OSCtxSw() { DWORD n = 0; if(!(SS_SP->Exit)) { n = SuspendThread(SS_SP->Handle); } OSTaskSwHook(); OSTrace( OBJ_SW, PT_SW_CTX, OSTCBHighRdy, 0, OSPrioCur, OSPrioHighRdy,0 ); OSTCBCur = OSTCBHighRdy; OSPrioCur = OSPrioHighRdy; SS_SP = (OS_EMU_STK*) OSTCBHighRdy->OSTCBStkPtr; ResumeThread(SS_SP->Handle); }
void OSIntCtxSw(void) { OS_STK *sp; OSTaskSwHook(); sp = (OS_STK *)Context.Esp; //得到主线程当前堆栈指针 //在堆栈中保存相应寄存器。 *--sp = Context.Eip; //先保存eip *--sp = Context.EFlags; //保存efl *--sp = Context.Eax; *--sp = Context.Ecx; *--sp = Context.Edx; *--sp = Context.Ebx; *--sp = Context.Esp; //此时保存的esp是错误的,但OSTCBCur保存了正确的 *--sp = Context.Ebp; *--sp = Context.Esi; *--sp = Context.Edi; OSTCBCur->OSTCBStkPtr = (OS_STK *)sp; //保存当前esp OSTCBCur = OSTCBHighRdy; //得到当前就绪最高优先级任务的tcb OSPrioCur = OSPrioHighRdy; //得到当前就绪任务最高优先级数 sp = OSTCBHighRdy->OSTCBStkPtr; //得到重新执行的任务的堆栈指针 //恢复所有处理器的寄存器 Context.Edi = *sp++; Context.Esi = *sp++; Context.Ebp = *sp++; Context.Esp = *sp++; //此时上下文中得到的esp是不正确的 Context.Ebx = *sp++; Context.Edx = *sp++; Context.Ecx = *sp++; Context.Eax = *sp++; Context.EFlags = *sp++; Context.Eip = *sp++; Context.Esp = (unsigned long)sp; //得到正确的esp SetThreadContext(mainhandle, &Context); //保存主线程上下文 }
void OSStartHighRdy (void) { OSTaskSwHook(); OSRunning = 1; OSCtxRestore(OSTCBHighRdy->OSTCBStkPtr); }
void OSStartHighRdy() { DWORD dwID; OSInitTrace(100000); OS_ENTER_CRITICAL(); OSTaskSwHook(); ++OSRunning; OSCtxSwW32Event = CreateEvent(NULL,FALSE,FALSE,NULL); OSCtxSwW32Handle = CreateThread( NULL, 0, OSCtxSwW32, 0, 0, &dwID ); SetPriorityClass(OSCtxSwW32Handle,THREAD_PRIORITY_HIGHEST); #ifdef SET_AFFINITY_MASK if( SetThreadAffinityMask( OSCtxSwW32Handle, 1 ) == 0 ) { #ifdef OS_CPU_TRACE OS_Printf("Error: SetThreadAffinityMask\n"); #endif } #endif SetThreadPriority(OSCtxSwW32Handle,THREAD_PRIORITY_TIME_CRITICAL); OSTick32Handle = CreateThread( NULL, 0, OSTickW32, 0, 0, &dwID ); SetPriorityClass(OSTick32Handle,THREAD_PRIORITY_HIGHEST); #ifdef SET_AFFINITY_MASK if( SetThreadAffinityMask( OSTick32Handle, 1 ) == 0 ) { #ifdef OS_CPU_TRACE OS_Printf("Error: SetThreadAffinityMask\n"); #endif } #endif SetThreadPriority(OSTick32Handle,THREAD_PRIORITY_HIGHEST); #ifdef WIN_MM_TICK timeGetDevCaps(&OSTimeCap, sizeof(OSTimeCap)); if( OSTimeCap.wPeriodMin < WIN_MM_MIN_RES ) OSTimeCap.wPeriodMin = WIN_MM_MIN_RES; timeBeginPeriod(OSTimeCap.wPeriodMin); OSTickEventHandle = CreateEvent(NULL, FALSE, FALSE, NULL); OSTickTimer = timeSetEvent((1000/OS_TICKS_PER_SEC),OSTimeCap.wPeriodMin,(LPTIMECALLBACK)OSTickEventHandle, dwID,TIME_PERIODIC|TIME_CALLBACK_EVENT_SET); #endif SS_SP = (OS_EMU_STK*) OSTCBHighRdy->OSTCBStkPtr; /* OSTCBCur = OSTCBHighRdy; */ /* OSPrioCur = OSPrioHighRdy; */ ResumeThread(SS_SP->Handle); OS_EXIT_CRITICAL(); WaitForSingleObject(OSCtxSwW32Handle,INFINITE); #ifdef WIN_MM_TICK timeKillEvent(OSTickTimer); timeEndPeriod(OSTimeCap.wPeriodMin); CloseHandle(OSTickEventHandle); #endif CloseHandle(OSTick32Handle); CloseHandle(OSCtxSwW32Event); }
// OSScheduleThread *********************************************************** // Start tasks, triggered by hScheduleEvent void OSScheduleThread(INT32U param) { char temp[256]; INT16S oldIndex, nextIndex; #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr = TRUE; #endif DBGPRINT(0x00000001, "*** OSScheduleThread First Call\n"); while (1) { if (WaitForSingleObject(hScheduleEvent, OS_SCHEDULER_TIMEOUT) == WAIT_TIMEOUT) //Wait for a scheduler event (with timeout) { sprintf(temp, "ERROR: Scheduler timed out in OSScheduleThread %u --> %u IF=%u <-%u<%u<%u<%u<%u<%u<%u<%u<-\n", OSPrioCur, OSPrioHighRdy, virtualInterruptFlag, taskLog[0], taskLog[1], taskLog[2], taskLog[3], taskLog[4], taskLog[5], taskLog[6], taskLog[7] ); DBGPRINT(0x00000040, temp); MessageBox(NULL, temp, "UCOS-II WIN32", MB_OK | MB_SETFOREGROUND | MB_ICONERROR); //In case of timeout, display an error message ... OSRunning=0; SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlBreakHandler, FALSE); return; //... and exit (will return to OSStartHighRdy()) } OSTaskSwHook(); //Call the task switch hook function EnterCriticalSection(&criticalSection); if (taskSuspended[OSPrioCur]==-1) { DBGPRINT(0x00000001, "Old Task %d marked for deletion - %X - %X\n", OSPrioCur, hTaskThread[OSPrioCur], OSTCBCur); SuspendThread(hTaskThread[OSPrioCur]); ExecuteDeleteTask(OSPrioCur); oldIndex = OSPrioCur; } else { oldIndex = GetThreadIndexForTask(OSTCBCur); } nextIndex= GetThreadIndexForTask(OSTCBHighRdy); if (oldIndex==-1 || nextIndex==-1) { printf("ERROR: Internal scheduling error: oldIndex=%d - %d nextIndex=%d - %d\n",oldIndex, OSTCBCur->OSTCBPrio, nextIndex, OSTCBHighRdy->OSTCBPrio); exit(-1); } OSTCBCur = OSTCBHighRdy; //Now logically switch to the new task OSPrioCur = (INT8U) nextIndex; idleTrigger = TRUE; DBGPRINT(0x00000001, "*** OSScheduleThread from %2u to %2u\n", oldIndex, nextIndex); if (OSTCBPrioTbl[oldIndex] == NULL) //If a task has been deleted { if (hTaskThread[oldIndex]) //... remove it, normally this should never happen { if (TerminateThread(hTaskThread[oldIndex], 0)==FALSE) { printf("ERROR: Terminate thread for task %d (in OSScheduleThread) WIN32 error code: %Xh\n", oldIndex, GetLastError()); } CloseHandle(hTaskThread[oldIndex]); } hTaskThread[oldIndex] = NULL; taskSuspended[oldIndex]=0; } else if (oldIndex != nextIndex && taskSuspended[oldIndex]==0) //If switching context to a new task ... { if (SuspendThread(hTaskThread[oldIndex])!=0) //... suspend the thread associated with the current task printf("ERROR: SuspendThread() (in OSSCheduleThread) failed with error %Xh - task %d - %d\n", GetLastError(), oldIndex, taskSuspended[oldIndex]); taskSuspended[oldIndex]++; //(update suspend counter to avoid multiple suspends of the same task) } if (taskSuspended[nextIndex]>0) { taskSuspended[nextIndex]--; //(updates suspend counter to avoid multiple resumes of the same task) if (taskSuspended[nextIndex] < 0) taskSuspended[nextIndex]=0; if (virtualInterruptFlag==FALSE) #if OS_CRITICAL_METHOD == 3 OSEnableInterruptFlag(&cpu_sr); #else OSEnableInterruptFlag(); #endif OSLog(nextIndex); if (ResumeThread(hTaskThread[nextIndex])!=1) //... and resume the thread associated with the new task printf("ERROR: ResumeThread() (in OSSCheduleThread) failed with error %Xh\n", GetLastError()); } else { if (virtualInterruptFlag==FALSE) #if OS_CRITICAL_METHOD == 3 OSEnableInterruptFlag(&cpu_sr); #else OSEnableInterruptFlag(); #endif } LeaveCriticalSection(&criticalSection); } }