📄 os_cpu_c.c
字号:
{ 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 + -