⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_cpu_c.c

📁 vc++环境下的ucosII
💻 C
📖 第 1 页 / 共 2 页
字号:

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 + -