📄 os_cpu_c.c
字号:
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);
}
/*
;*********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From task level)
; void OSCtxSw(void)
;
; Note(s): 1) Upon entry,
; OSTCBCur points to the OS_TCB of the task to suspend
; OSTCBHighRdy points to the OS_TCB of the task to resume
;
; 2) The stack frame of the task to suspend looks as follows:
;
; SP -> OFFSET of task to suspend (Low memory)
; SEGMENT of task to suspend
; PSW of task to suspend (High memory)
;
; 3) The stack frame of the task to resume looks as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> DS (Low memory)
; ES
; DI
; SI
; BP
; SP
; BX
; DX
; CX
; AX
; OFFSET of task code address
; SEGMENT of task code address
; Flags to load in PSW (High memory)
;*********************************************************************************************************
*/
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);
}
/*
;*********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From an ISR)
; void OSIntCtxSw(void)
;
; Note(s): 1) Upon entry,
; OSTCBCur points to the OS_TCB of the task to suspend
; OSTCBHighRdy points to the OS_TCB of the task to resume
;
; 2) The stack frame of the task to suspend looks as follows:
;
; SP+0 --> OFFSET of return address of OSIntCtxSw() (Low memory)
; +2 SEGMENT of return address of OSIntCtxSw()
; +4 PSW saved by OS_ENTER_CRITICAL() in OSIntExit()
; +6 OFFSET of return address of OSIntExit()
; +8 SEGMENT of return address of OSIntExit()
; +10 DS
; ES
; DI
; SI
; BP
; SP
; BX
; DX
; CX
; AX
; OFFSET of task code address
; SEGMENT of task code address
; Flags to load in PSW (High memory)
;
; 3) The stack frame of the task to resume looks as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> DS (Low memory)
; ES
; DI
; SI
; BP
; SP
; BX
; DX
; CX
; AX
; OFFSET of task code address
; SEGMENT of task code address
; Flags to load in PSW (High memory)
;*********************************************************************************************************
*/
void OSIntCtxSw()
{
DWORD n = 0;
if(!(SS_SP->Exit)) {
n = SuspendThread(SS_SP->Handle);
}
OSTaskSwHook();
OSTrace( OBJ_SW, PT_SW_INT, OSTCBHighRdy, 0, OSPrioCur,OSPrioHighRdy,0 );
OSTCBCur = OSTCBHighRdy;
OSPrioCur = OSPrioHighRdy;
SS_SP = (OS_EMU_STK*) OSTCBHighRdy->OSTCBStkPtr;
ResumeThread(SS_SP->Handle);
}
/*
;*********************************************************************************************************
; HANDLE TICK ISR
;
; Description: This function is called 199.99 times per second or, 11 times faster than the normal DOS
; tick rate of 18.20648 Hz. Thus every 11th time, the normal DOS tick handler is called.
; This is called chaining. 10 times out of 11, however, the interrupt controller on the PC
; must be cleared to allow for the next interrupt.
;
; Arguments : none
;
; Returns : none
;
; Note(s) : The following C-like pseudo-code describe the operation being performed in the code below.
;
; Save all registers on the current task's stack;
; OSIntNesting++;
; OSTickDOSCtr--;
; if (OSTickDOSCtr == 0) {
; INT 81H; Chain into DOS every 54.925 mS
; (Interrupt will be cleared by DOS)
; } else {
; Send EOI to PIC; Clear tick interrupt by sending an End-Of-Interrupt to the 8259
; PIC (Priority Interrupt Controller)
; }
; OSTimeTick(); Notify uC/OS-II that a tick has occured
; OSIntExit(); Notify uC/OS-II about end of ISR
; Restore all registers that were save on the current task's stack;
; Return from Interrupt;
;*********************************************************************************************************
*/
void OSTickISR()
{
OSIntEnter();
OSTimeTick();
OSIntExit();
}
/*
*********************************************************************************************************
* WIN32 TASK - OSCtxSwW32()
*
* Description: These functions are body of OS multitasking in WIN32.
*
* Arguments : lpParameter is a pointer to special paraleter of the task.
*
* Note(s) : 1) Priorities of these tasks are very important.
*********************************************************************************************************
*/
DWORD WINAPI OSCtxSwW32( LPVOID lpParameter )
{
OS_INIT_CRITICAL();
while(!OSTerminateCtxSwW32)
{
if( WAIT_OBJECT_0 == WaitForSingleObject(OSCtxSwW32Event,INFINITE) )
{
OS_ENTER_CRITICAL();
OSCtxSw();
OS_EXIT_CRITICAL();
}
}
return 0;
}
/*
*********************************************************************************************************
* WIN32 TASK - OSTickW32()
*
* Description: These functions are body of OS multitasking in WIN32.
*
* Arguments : lpParameter is a pointer to special paraleter of the task.
*
* Note(s) : 1) Priorities of these tasks are very important.
*********************************************************************************************************
*/
DWORD WINAPI OSTickW32( LPVOID lpParameter )
{
OS_INIT_CRITICAL();
while(!OSTerminateTickW32)
{
OSTickISR();
#ifdef WIN_MM_TICK
if( WaitForSingleObject(OSTickEventHandle, 5000) == WAIT_TIMEOUT)
{
#ifdef OS_CPU_TRACE
OS_Printf("Error: MM OSTick Timeout!\n");
#endif
}
ResetEvent(OSTickEventHandle);
#else
Sleep(1000/OS_TICKS_PER_SEC);
#endif
}
return 0;
}
/*
*********************************************************************************************************
* WIN32 TASK - OSTaskW32()
*
* Description: These functions are body of OS multitasking in WIN32.
*
* Arguments : lpParameter is a pointer to special paraleter of the task.
*
* Note(s) : 1) Priorities of these tasks are very important.
*********************************************************************************************************
*/
DWORD WINAPI OSTaskW32( LPVOID lpParameter )
{
OS_TCB *ptcb;
OS_EMU_STK *stack;
ptcb = (OS_TCB*) lpParameter;
stack = (OS_EMU_STK*) ptcb->OSTCBStkPtr;
#ifdef DISABLE_PRIORITY_BOOST
if( SetThreadPriorityBoost( stack->Handle, TRUE ) == 0 ) {
#ifdef OS_CPU_TRACE
OS_Printf("Error: SetThreadPriorityBoost\n");
#endif
}
#endif
OS_INIT_CRITICAL();
stack->Task(stack->pData);
stack->Exit = 1;
OSTaskDel(ptcb->OSTCBPrio);
return 0;
}
/*
*********************************************************************************************************
* WIN32 TASK - OS_SLEEP()
*
* Description: These functions are body of OS multitasking in WIN32.
*
* Arguments : lpParameter is a pointer to special paraleter of the task.
*
* Note(s) : 1) Priorities of these tasks are very important.
*********************************************************************************************************
*/
void OS_SLEEP()
{
Sleep(1);
}
/*
*********************************************************************************************************
* WIN32 TASK - OS_STOP()
*
* Description: These functions are body of OS multitasking in WIN32.
*
* Arguments : lpParameter is a pointer to special paraleter of the task.
*
* Note(s) : 1) Priorities of these tasks are very important.
*********************************************************************************************************
*/
void OS_STOP()
{
OS_ENTER_CRITICAL();
++OSTerminateTickW32;
++OSTerminateCtxSwW32;
OS_TASK_SW();
OS_EXIT_CRITICAL();
Sleep(1000/OS_TICKS_PER_SEC);
}
/*
*********************************************************************************************************
* OS_Printf()
*
* Description: These functions help make application more reliable.
*
* OS_Printf - analog of printf, but use critical sections
*********************************************************************************************************
*/
int OS_Printf(char *str, ...)
{
int ret;
va_list marker;
va_start( marker, str );
OS_ENTER_CRITICAL();
ret = vprintf( str, marker );
OS_EXIT_CRITICAL();
va_end( marker );
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -