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

📄 os_cpu_c.c

📁 ucos2.85在vs2005上模拟环境
💻 C
📖 第 1 页 / 共 2 页
字号:
        {   sprintf(temp, "ERROR: Interrupt timed out in OSInterruptThread   IF=%u\n", virtualInterruptFlag);
            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);
            exit(-1);									//... and exit
        }
        EnterCriticalSection(&criticalSection);
        DBGPRINT(0x00000001, "*** OSInterruptThread\n");
        if (virtualInterruptFlag==FALSE)
            DBGPRINT(0x00000001, "*** virtualInteruptFlag disabled when calling OSInterruptThread XXX %d\n", virtualInterruptFlag);
        DBGPRINT(0x00000001, "--- OSIntEnter\n");
        OSIntEnter();

        if (eventType==WAIT_OBJECT_0)							//Call uCOS' interrupt processing
        {   ResetEvent(hInterruptEvent[0]);
            DBGPRINT(0x00000001, "--- OSTimeTick\n");
            interruptTable[0]();							//IRQ0 reserved for time tick: OSTimeTick();
        } else if (eventType==WAIT_OBJECT_0+1)
        {   ResetEvent(hInterruptEvent[1]);
            interruptTable[1]();
        } else if (eventType==WAIT_OBJECT_0+2)
        {   ResetEvent(hInterruptEvent[2]);
            interruptTable[2]();
        } else if (eventType==WAIT_OBJECT_0+3)
        {   ResetEvent(hInterruptEvent[3]);
            interruptTable[3]();
        } else if (eventType==WAIT_OBJECT_0+4)
        {   ResetEvent(hInterruptEvent[4]);
            interruptTable[4]();
        } else if (eventType==WAIT_OBJECT_0+5)
        {   ResetEvent(hInterruptEvent[5]);
            interruptTable[5]();
        } else if (eventType==WAIT_OBJECT_0+6)
        {   ResetEvent(hInterruptEvent[6]);
            interruptTable[6]();
        } else if (eventType==WAIT_OBJECT_0+7)
        {   ResetEvent(hInterruptEvent[7]);
            interruptTable[7]();
        } else
        {   MessageBox(NULL, temp, "UCOS-II WIN32", MB_OK | MB_SETFOREGROUND | MB_ICONERROR);		//In case of timeout, display an error message ...
        }
        DBGPRINT(0x00000001, "--- OSIntExit\n");
        OSIntExit();
        LeaveCriticalSection(&criticalSection);
    }
}


/*
*********************************************************************************************************
   uCOS-II Functions
*********************************************************************************************************
*/

// OSTimeTickInit ************************************************************
// Initialize the WIN32 multimedia timer to simulate time tick interrupts
void OSTimeTickInit()
{   TIMECAPS timecaps;

    DBGPRINT(0x00000008, "*** OSTimeTickInit\n");

    if (timeGetDevCaps((LPTIMECAPS) & timecaps, sizeof(timecaps)) != TIMERR_NOERROR)
    {   
		printf("uCOS-II ERROR: Timer could not be installed 1\n");
        exit(-1);
    }
    if (timeBeginPeriod(timecaps.wPeriodMin) != TIMERR_NOERROR)
    {   
		printf("uCOS-II ERROR: Timer could not be installed 2\n");
        exit(-1);
    }
    if (timeSetEvent(1000 / OS_TICKS_PER_SEC, 0, (LPTIMECALLBACK) hInterruptEvent[0], 0, TIME_PERIODIC | TIME_CALLBACK_EVENT_SET) == 0)
    {   
		printf("uCOS-II ERROR: Timer could not be installed 3\n");
        exit(-1);
    }
}

// OSTaskStkInit *************************************************************
// This function does initialize the stack of a task (this is only a dummy function
// for compatibility reasons, because this stack is not really used (except to refer
// to the task parameter *pdata)
OS_STK *OSTaskStkInit(void (*task) (void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{   OS_STK *stk;

    DBGPRINT(0x00000010, "*** OSTaskStkInit\n");

    stk = (OS_STK *) ptos;                                      // Load stack pointer
    *--stk = (INT32U) pdata;					// Push pdata on the stack
    *--stk = (INT32U) task;					// Push the task start address on the stack

    return stk;
}


/*
*******************************************************************************
   Internal Hook functions (used by the WIN32 port, not user hookable)
*******************************************************************************
*/

// OSInitHookBegin ***********************************************************
// This hook is invoked at the beginning of the OS initialization. MUST NOT BE DEFINED BY THE APPLICATION.
void OSInitHookBegin()
{   int i;
    char temp[256];
    static BOOLEAN isInitialized = FALSE;

    DBGPRINT(0x00000010, "*** OSInitHookBegin\n");

    if (isInitialized)
    {	
		for (i=0; i < OS_LOWEST_PRIO + 2; i++)
    	{   
			if (hTaskThread[i])
    	    {	
				if (TerminateThread(hTaskThread[i], 0)==FALSE)
        		{   
					printf("ERROR: Terminate thread for task %d (in OSInitHookBegin) %Xh\n", i, GetLastError());
        		}
    	        CloseHandle(hTaskThread[i]);
    	    }
			hTaskThread[i]=NULL;
			taskSuspended[i]=0;
			pTaskTcb[i]=NULL;
    	}
    	return;
    } 
	else
    {	
		isInitialized=TRUE;
    }

    SetProcessAffinityMask(GetCurrentProcess(), 0x1); // dwProcessAffinityMask -> 1 = run only on CPU 0
    hScheduleEvent  = CreateEvent(NULL, FALSE, FALSE, NULL);	//Create the scheduler and interrupt event

    for (i=0; i< NINTERRUPTS; i++)
    {	
		sprintf(temp,"OSirq%u",i);
    	hInterruptEvent[i] = CreateEvent(NULL, TRUE, FALSE, temp);
        interruptTable[i]  = OSDummyISR;
    }

    InitializeCriticalSection(&criticalSection);
    hScheduleThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) OSScheduleThread,  NULL, 0, (INT32U*) &i);	//Create the scheduler and interrupt thread
    hInterruptThread= CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) OSInterruptThread, NULL, 0, &interruptThreadId);
    interruptTable[0] = OSTimeTick;

    SetPriorityClass( hScheduleThread,  THREAD_PRIORITY_HIGHEST);//Set the scheduler and interrupt threads to maximum WIN32 priority
    SetThreadPriority(hScheduleThread,  THREAD_PRIORITY_TIME_CRITICAL);
    SetPriorityClass( hInterruptThread, THREAD_PRIORITY_HIGHEST);
    SetThreadPriority(hInterruptThread, THREAD_PRIORITY_HIGHEST);

    SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlBreakHandler, TRUE);
    Sleep(0);							//Give Windows a chance to start the scheduler and interrupt thread

    //ADD YOUR OWN HOOK CODE HERE IF NECESSARY
}

// OSTCBInitHook **********************************************************
// This hook is invoked during task creation. MUST NOT BE DEFINED BY THE APPLICATION.
void OSTCBInitHook(OS_TCB * pTcb)
{   int i;

    DBGPRINT(0x00000004, "*** OSTCBInitHook %u\n", pTcb->OSTCBPrio);

    if ((i=GetThreadIndexForTask(pTcb))!=-1)			//Test if the TCB is already known
    {	if (TerminateThread(hTaskThread[i], 0)==FALSE)
        {   printf("ERROR: Terminate thread (in OSTCBInitHook) %Xh\n", GetLastError());
        }
        CloseHandle(hTaskThread[i]);
        hTaskThread[i]=NULL;
        taskSuspended[i]=0;
        pTaskTcb[i]=NULL;
        Beep(400, 1000);
        printf("INFO: A thread for a task with priority %d (original prio %d) already existed and was terminated\n", i, pTcb->OSTCBPrio);
    }

    if ((hTaskThread[pTcb->OSTCBPrio] = CreateThread(NULL, 4096, (LPTHREAD_START_ROUTINE) *(pTcb->OSTCBStkPtr),
                                                (void *) *(pTcb->OSTCBStkPtr + 1), CREATE_SUSPENDED, (INT32U*) &i))==NULL)	//Map uCOS-II task to WIN32 thread
    {   printf("ERROR: Create thread error %Xh\n", pTcb->OSTCBPrio, GetLastError());
    	assert(hTaskThread[pTcb->OSTCBPrio]);
    }

    taskSuspended[pTcb->OSTCBPrio]=1;									//Create thread in WIN32 suspended state
    pTaskTcb[pTcb->OSTCBPrio]=pTcb;

    if (OS_BOOST_WIN32_PRIORITY && (pTcb->OSTCBPrio!=OS_LOWEST_PRIO))           //Boost WIN32 thread priorites (except idle thread)
        SetThreadPriority(hTaskThread[pTcb->OSTCBPrio], THREAD_PRIORITY_ABOVE_NORMAL);

    //ADD YOUR OWN HOOK CODE HERE IF NECESSARY
}

void RemoteExitThread(void)					// This functions exits the WIN32 thread associated with a deleted uCOS task
{   //SetEvent(hScheduleEvent);					// Call the scheduler, just in case
    DBGPRINT(0x00000004,"Finally terminating a delete task's WIN32 thread\n");
    ExitThread(0);
}

void ExecuteDeleteTask(int i)
{    
	CONTEXT ctx;
     assert(taskSuspended[i]==-1);

     DBGPRINT(0x00000004, "Delete task %d - go\n", i);
     SetThreadPriority(hTaskThread[i], THREAD_PRIORITY_TIME_CRITICAL);
     ctx.ContextFlags=CONTEXT_FULL;				// Modify the deleted task's thread context in such a way, that it calls RemoteExitThread
     GetThreadContext(hTaskThread[i], &ctx);			// when it is resumed
     ctx.Eip=(DWORD) RemoteExitThread;
     SetThreadContext(hTaskThread[i], &ctx);
     ResumeThread(hTaskThread[i]);				// Resume the thread, so that it can terminate itself
     WaitForSingleObject(hTaskThread[i], INFINITE);
     CloseHandle(hTaskThread[i]);
     hTaskThread[i] = NULL;
     pTaskTcb[i]=NULL;
     taskSuspended[i] = 0;
     DBGPRINT(0x00000004, "Delete task %d - done\n", i);
}

// OSTaskDelHook *************************************************************
// This hook is invoked during task deletion.
void OSTaskDelHook(OS_TCB * pTcb)
{   int i;
    DBGPRINT(0x00000004, "********** Delete Task %d from Task %d********* \n", pTcb->OSTCBPrio, OSPrioCur);

    //DumpTaskList();
    if ((i=GetThreadIndexForTask(pTcb))!=-1)
    {	
		taskSuspended[i] = -1;					// Mark as deleted
    	if (i!=OSPrioCur)
    	{   
			ExecuteDeleteTask(i);
    	}
		else
    	{   
			DBGPRINT(0x00000004, "********** Delete Task %d - %d - marked to be deleted ********* %X - %X\n", i, OSPrioCur, hTaskThread[i], OSTCBCur);
    	}
    }
    //ADD YOUR OWN HOOK CODE HERE IF NECESSARY
}

// OSTaskChangePrioHook ******************************************************
/* Hook to be notified, when task priority is changed be OSChangeTaskPriority().
   This hook is not an offical uCOS-II hook. But if your programs use OSTaskChangePrio()
   and do not run correctly, try to hook this routine, by inserting a call to this hook
   in function OSTaskChangePrio (...) in file OS_Task.c. At the end of this function
   insert:

    OSTaskChangePrioHook(oldprio, newprio); //<<<--- New, insert this
    OS_EXIT_CRITICAL();			    //<<<--- Existing code

    if (OSRunning == OS_TRUE)		    //<<<--- Existing code
    {   OS_Sched();
    }

*/
void OSTaskChangePrioHook(int oldPrio, int newPrio)
{
    printf("*** OSTaskChangePrio Task %d changes priority of task %d to %d\n", OSPrioCur, oldPrio, newPrio);
    hTaskThread[newPrio]   = hTaskThread[oldPrio];
    taskSuspended[newPrio] = taskSuspended[oldPrio];
    pTaskTcb[newPrio] = pTaskTcb[oldPrio];

    DBGPRINT(0x00000004, "*** OSTaskChangePrio Task %d changes priority of task %d to %d\n", OSPrioCur, oldPrio, newPrio);

    hTaskThread[oldPrio]   = NULL;
    taskSuspended[oldPrio] = 0;
    pTaskTcb[oldPrio] = NULL;

    if (oldPrio == OSPrioCur)
	OSPrioCur = newPrio;
}

/*
*******************************************************************************
   Hook functions (user hookable)
*******************************************************************************
*/

#if OS_CPU_HOOKS_EN > 0

/*
void OSInitHookBegin()                  MUST NOT BE DEFINED BY THE APPLICATION, see above.
*/

// OSInitHookEnd *************************************************************
// This hook is invoked at the end of the OS initialization.
void OSInitHookEnd()
{   
	DBGPRINT(0x00000010, "*** OSInitHookEnd\n");
}

void OSTaskCreateHook(OS_TCB * pTcb)
{   
	DBGPRINT(0x00000004, "*** OSTaskCreateHook %u\n", pTcb->OSTCBPrio);
}

/*
void OSTaskDelHook(OS_TCB * pTcb)	MUST NOT BE DEFINED BY THE APPLICATION, see above
*/


/*
void OSTCBInitHook(OS_TCB *pTcb)	MUST NOT BE DEFINED BY THE APPLICATION, see above
*/

// OSTaskIdleHook ************************************************************
// This hook is invoked from the idle task.
void OSTaskIdleHook()
{   if (idleTrigger)						//Issue a debug message, each time the idle task is reinvoked
    {   
		DBGPRINT(0x00000020, "*** OSTaskIdleHook\n");
        idleTrigger = FALSE;
    }

    OS_SLEEP();							//Give Windows a chance to run other applications to when uCOS-II idles
}

// OSTaskStatHook ************************************************************
// This hook is invoked by the statistical task every second.
void OSTaskStatHook()
{
}

// OSTimeTickHook ************************************************************
// This hook is invoked during a time tick.
void OSTimeTickHook()
{
}

// OSTaskSwHook **************************************************************
// This hook is invoked during a task switch.
// OSTCBCur points to the current task (being switched out).
// OSTCBHighRdy points on the new task (being switched in).
void OSTaskSwHook()
{
}

#else
#pragma message("INFO: Hook functions must be defined in the application")
#endif

/*
*******************************************************************************
   Internal Task switch functions
*******************************************************************************
*/

// OSStartHighRdy *************************************************************
// Start first task
void OSStartHighRdy(void)
{   //OSTaskSwHook();						//Call the task switch hook function

    OSTimeTickInit();                                           //Initialize time ticks

    // Increment OSRunning by 1
    OSRunning++;

    DBGPRINT(0x00000002, "*** OSStartHighRdy   from %2u to %2u\n", OSPrioCur, OSPrioHighRdy);

    SetEvent(hScheduleEvent);                                   //Trigger scheduling thread

    WaitForSingleObject(hScheduleThread, INFINITE);		//Wait, until the scheduling thread quits.
    								//This should never happen during normal operation
    printf("INFO: Primary thread killed - exiting\n");
}

// OSCtxSw ********************************************************************
// Task context switch
void OSCtxSw(void)
{   
	DBGPRINT(0x00000002, "*** OSCtxSw          from %2u to %2u\n", OSPrioCur, OSPrioHighRdy);
    SetEvent(hScheduleEvent);					//Trigger scheduling thread
}

// OSIntCtxSw *****************************************************************
// Interrupt context switch
void OSIntCtxSw(void)
{   
	DBGPRINT(0x00000002, "*** OSCIntCtxSw      from %2u to %2u\n", OSPrioCur, OSPrioHighRdy);
    SetEvent(hScheduleEvent);                                   //Trigger scheduling thread
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -