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

📄 os_cpu_c.c

📁 此源码为UCOS在WIN32环境下的移植版本
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************************************************                                                uC/OS-II*                                The Real-Time Kernel (by Jean J. Labrosse)**                                             LINUX PORT**                          (c) Copyright 2004-... Werner.Zimmermann@fht-esslingen.de*                                           All Rights Reserved** File : OS_CPU_C.C* By   : Werner Zimmermann** Changes:  1.50 First Release of LINUX Port - same version number as WIN32 port*           1.60 Increased resolution of PC_Elapsed... time measurement. Now uses the Pentium*                time stamp counter.*           2.00 Major change of signal generation and handling to adapt the Linux port to*		 threading changes in Linux kernel 2.6.x. Use gettid() instead getpid() and*		 tkill() instead of kill() because clone() changed.*	    2.10 Include paths modified to work with uCOS-II 2.70*           3.00 Modifications to work with uCOS-II 2.80, 30 May 2006,*		 made OSTaskIdleHook() and OSTaskCreateHook() instead of OSTCBInitHook() user callable.***********************************************************************************************************/#define OS_PORT_VERSION 300					//Version number of the uCOS-II LINUX port#define SHOWTID 1/**********************************************************************************************************   Includes**********************************************************************************************************/#include    <stdio.h>#include    <stdlib.h>#include    <stdarg.h>#include    <sys/time.h>#include    <sys/resource.h>#include    <sys/sem.h>#include    <signal.h>#include    <sched.h>#include    <assert.h>#include    <linux/unistd.h>#include    <asm/unistd.h>#if (OS_VERSION <= 270)#include    "os_cpu.h"#include    "os_cfg.h"#include    "ucos_ii.h"#else#include    "ucos_ii.h"#endiftypedef struct itimerval ITIMERVAL;typedef int (*LPTHREAD_START_ROUTINE)(void*);/**********************************************************************************************************   Global variables**********************************************************************************************************/INT32S  hMainThread;INT32S  hScheduleEvent, hScheduleThread;			//Scheduler thread variablesINT32S  hTaskThread[OS_LOWEST_PRIO + 2];			//Map uCOS tasks to LINUX threadsINT8S   taskSuspended[OS_LOWEST_PRIO + 2];			//Suspend status of mapped tasks/threads#define NINTERRUPTS 8						//Number of interrupt events (DO NOT CHANGE)INT32S  hInterruptEvent[NINTERRUPTS], hInterruptThread;		//Interrupt handling thread variablesvoid (*interruptTable[NINTERRUPTS])();BOOLEAN virtualInterruptFlag=TRUE;INT32S eventType = 0;sigset_t interruptSignalSet, scheduleSignalSet, oldScheduleSignalSet, oldInterruptSignalSet;BOOLEAN  interruptSignalFlag=FALSE, scheduleSignalFlag=FALSE;INT32S criticalSection;BOOLEAN idleTrigger = TRUE;					//Trigger a message, when the idle task is								//invoked (used for debugging purposes)#define NLOG	16						//Log last scheduled tasks (used forINT16U taskLog[NLOG];						//... debugging purposes)/**********************************************************************************************************   Port-specific functions**********************************************************************************************************/void InitializeCriticalSection(INT32S *sema){   *sema = semget(1, 1, IPC_CREAT | 0666);    semctl(*sema, 0, SETVAL, 1);}void EnterCriticalSection(INT32S *sema){   struct sembuf op;    op.sem_num=0;    op.sem_flg=0;    op.sem_op=-1;   }void LeaveCriticalSection(INT32S *sema){   struct sembuf op;    op.sem_num=0;    op.sem_flg=0;    op.sem_op=+1;   }// DBGPRINT ******************************************************************// Debug outputvoid DBGPRINT(INT32U debugLevel, const char *fmt,...){    va_list argptr;    FILE *fd;    if ((debugLevel & DEBUGLEVEL) == 0)				//Debug output selection        return;    if (DEBUGLEVEL < 0x10000000UL)                              //Screen output (does influence real-time performance!)    {   va_start(argptr, fmt);        vprintf(fmt, argptr);        va_end(argptr);    } else                                                      //File output (does influence real-time performance!)    {   va_start(argptr, fmt);        if ((fd = fopen("ucos.log","a+"))!=NULL)        {   vfprintf(fd, fmt, argptr);            fclose(fd);        }        va_end(argptr);    }}// OSLog *********************************************************************// Log the last NLOG scheduled tasks in taskLog (with taskLog[0] = last task)void OSLog(INT16U prio){   int i;    for (i=NLOG-1; i > 0; i--)					//Shift the previous logged values by one        taskLog[i]=taskLog[i-1];    taskLog[0]=prio;						//Log the last one into taskLog[0]}// OSPortVersion *************************************************************// Return the version number of the uCOS-II LINUX portINT16U OSPortVersion(void){    return OS_PORT_VERSION;}void CtrlBreakHandler(int ctrl){    if (ctrl==SIGTSTP)					//Handler if CTRL-D is pressed    {	printf("---Exiting OSPrioCur=%u-------------\n", OSPrioCur);	//---Display current task priority    } else if (ctrl==SIGINT)				//Handler if CTRL-C is pressed    {	printf("---Exiting OSPrioCur=%u-------------\n", OSPrioCur);	//---Display current task priority and exit 	exit(0);    }}// OSEnableInterruptFlag ****************************************************// Enable the interrupt flagvoid OSEnableInterruptFlag(void){    if (virtualInterruptFlag==FALSE)				//If the timer interrupt previously was disabled,    {   virtualInterruptFlag=TRUE;	if (getpid()!=hInterruptThread)	    sigprocmask(SIG_UNBLOCK, &interruptSignalSet, NULL);//... resume the interrupt thread    }    DBGPRINT(0x00000080, ">>> ODEnableInterruptFlag %2d\n", virtualInterruptFlag);}// OSDisableInterruptFlag ****************************************************// Disable the Interrupt Flagvoid OSDisableInterruptFlag(void){    if (virtualInterruptFlag==TRUE)				//If the timer interrupt previously was enabled,    {       	if (getpid()!=hInterruptThread)				//... suspend the interrupt thread ...	    sigprocmask(SIG_BLOCK, &interruptSignalSet, NULL);  	virtualInterruptFlag=FALSE;    }    DBGPRINT(0x00000080, ">>> OSDisableInterrupts   %2d\n", virtualInterruptFlag);}void OSDummyISR(void){   perror("Got unsupported interrupt");}// OSTickTickCallback ********************************************************// Callback function for time tick 'interrupt', acts as a relay to OSTickISRvoid OSTimeTickCallback(int para){    DBGPRINT(0x00000008, "*** OSTimeTickCallback\n");     DBGPRINT(0x00000008, "--- Sending signal to PID=%u\n", hInterruptThread);     kill(hInterruptThread, hInterruptEvent[0]);		//Trigger the interrupt thread}// OSScheduleThread ***********************************************************// Start tasks, triggered by hScheduleEventvoid OSScheduleEventHandler(int val){   //dummy handler, necessary for pause() in OSScheduleThread()    DBGPRINT(0x00000001, "--- OSScheduleEventHandler ---\n");    scheduleSignalFlag=TRUE;}void OSScheduleThread(int param){   char temp[256];    INT16U oldPrio, nextPrio;    DBGPRINT(0x00000001, "*** OSScheduleThread First Call %u  %u  PID=%u  TID=%u\n", oldPrio, nextPrio, getpid(), gettid());    while (1)    { 	DBGPRINT(0x00000001, "--- OSScheduleThread: Going to pause ---\n");//    	pause();	sigprocmask(SIG_BLOCK, &scheduleSignalSet, &oldScheduleSignalSet);	while(!scheduleSignalFlag)	    sigsuspend(&oldScheduleSignalSet); 	sigprocmask(SIG_UNBLOCK, &scheduleSignalSet, NULL);    	scheduleSignalFlag=FALSE;	DBGPRINT(0x00000001, "--- OSScheduleThread: Resume from pause ---\n");	OSTaskSwHook();						//Call the task switch hook function	EnterCriticalSection(&criticalSection);	oldPrio =OSPrioCur;        nextPrio=OSPrioHighRdy;        OSTCBCur  = OSTCBHighRdy;        OSPrioCur = OSPrioHighRdy;        idleTrigger = TRUE;        DBGPRINT(0x00000001, "*** OSScheduleThread from %2u to %2u  PID=%u  TID=%u\n", oldPrio, nextPrio, getpid(), gettid());        if (oldPrio != nextPrio && taskSuspended[oldPrio]==0)				//If switching context to a new task ...        {   DBGPRINT(0x00000001, "--- Sending signal SIGSTOP to PID=%u\n", hTaskThread[oldPrio]);	    kill(hTaskThread[oldPrio], SIGSTOP);					//... suspend the thread associated with the current task	    taskSuspended[oldPrio]++;        }        if (taskSuspended[nextPrio])        {   taskSuspended[nextPrio]--;            if (taskSuspended[nextPrio] < 0)                taskSuspended[nextPrio] = 0;            if (virtualInterruptFlag==FALSE)                OSEnableInterruptFlag();            OSLog(nextPrio);	    DBGPRINT(0x00000001, "--- Sending signal SIGCONT to PID=%u\n", hTaskThread[nextPrio]);	    kill(hTaskThread[nextPrio], SIGCONT);					//... and resume the thread associated with the new task	} else        {   if (virtualInterruptFlag==FALSE)                OSEnableInterruptFlag();        }	LeaveCriticalSection(&criticalSection);    }}// OSInterruptThread **********************************************************// Time tick interrupt processingvoid OSInterruptEventHandler(int val){   eventType=val;    //dummy handler, necessary for pause() in OSInterruptThread()    DBGPRINT(0x00000001, "--- OSInterruptEventHandler ---\n");    interruptSignalFlag=TRUE;}void OSInterruptThread(int param){   char temp[256];    DBGPRINT(0x00000001, "*** OSInterruptThread First Call  PID=%u  TID=%u\n", getpid(), gettid());    while (1)    {  	DBGPRINT(0x00000001, "--- OSInterruptThread: Going to pause ---\n");//    	pause();	sigprocmask(SIG_BLOCK, &interruptSignalSet, &oldInterruptSignalSet);	while(!interruptSignalFlag)	    sigsuspend(&oldInterruptSignalSet); 	sigprocmask(SIG_UNBLOCK, &interruptSignalSet, NULL);    	interruptSignalFlag=FALSE;	DBGPRINT(0x00000001, "--- OSInterruptThread: Resume from pause ---\n");	EnterCriticalSection(&criticalSection);	DBGPRINT(0x00000001, "*** OSInterruptThread  PDI=%x  TID=%u\n", getpid(), gettid());        if (virtualInterruptFlag==FALSE)            DBGPRINT(0x00000001, "*** virtualInteruptFlag disabled when calling OSInterruptThread XXX %d\n", virtualInterruptFlag);        DBGPRINT(0x00000001, "--- OSIntEnter\n");        OSIntEnter();        DBGPRINT(0x00000001, "--- OSTimeTick\n");        if (eventType==hInterruptEvent[0])						//Call uCOS' interrupt processing        {   interruptTable[0]();							//IRQ0 reserved vor time tick: OSTimeTick();

⌨️ 快捷键说明

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