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

📄 os_core.c

📁 MCB2300_ucgui_LCD320240.rar LPC2368的uc/gui的移植
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
*********************************************************************************************************
*   											 uC/OS-II
*   									   The Real-Time Kernel
*   										  CORE FUNCTIONS
*
*   					   (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL
*   										All Rights Reserved
*
* File    : OS_CORE.C
* By	  : Jean J. Labrosse
* Version : V2.85
*
* LICENSING TERMS:
* ---------------
*   uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.  
* If you plan on using  uC/OS-II  in a commercial product you need to contact Micri祄 to properly license 
* its use in your product. We provide ALL the source code for your convenience and to help you experience 
* uC/OS-II.   The fact that the  source is provided does  NOT  mean that you can use it without  paying a 
* licensing fee.
*********************************************************************************************************
*/

#ifndef  OS_MASTER_FILE
#define  OS_GLOBALS
#include <ucos_ii.h>
#endif

/*
*********************************************************************************************************
*   									PRIORITY RESOLUTION TABLE
*
* Note: Index into table is bit pattern to resolve highest priority
*   	Indexed value corresponds to highest priority bit position (i.e. 0..7)
*********************************************************************************************************
*/

INT8U  const  OSUnMapTbl[256] = {
0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0x00 to 0x0F   						  */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0x10 to 0x1F   						  */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0x20 to 0x2F   						  */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0x30 to 0x3F   						  */
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0x40 to 0x4F   						  */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0x50 to 0x5F   						  */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0x60 to 0x6F   						  */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0x70 to 0x7F   						  */
7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0x80 to 0x8F   						  */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0x90 to 0x9F   						  */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0xA0 to 0xAF   						  */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0xB0 to 0xBF   						  */
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0xC0 to 0xCF   						  */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0xD0 to 0xDF   						  */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 	  /* 0xE0 to 0xEF   						  */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0  	  /* 0xF0 to 0xFF   						  */
};

/*$PAGE*/
/*
*********************************************************************************************************
*   									FUNCTION PROTOTYPES
*********************************************************************************************************
*/

static  void OS_InitEventList(void);

static  void OS_InitMisc(void);

static  void OS_InitRdyList(void);

static  void OS_InitTaskIdle(void);

#if OS_TASK_STAT_EN > 0
static  void OS_InitTaskStat(void);
#endif

static  void OS_InitTCBList(void);

static  void OS_SchedNew(void);

/*$PAGE*/
/*
*********************************************************************************************************
*   					  GET THE NAME OF A SEMAPHORE, MUTEX, MAILBOX or QUEUE
*
* Description: This function is used to obtain the name assigned to a semaphore, mutex, mailbox or queue.
*
* Arguments  : pevent    is a pointer to the event group.  'pevent' can point either to a semaphore,
*   					 a mutex, a mailbox or a queue.  Where this function is concerned, the actual
*   					 type is irrelevant.
*
*   		   pname	 is a pointer to an ASCII string that will receive the name of the semaphore,
*   					 mutex, mailbox or queue.  The string must be able to hold at least
*   					 OS_EVENT_NAME_SIZE characters.
*
*   		   perr 	 is a pointer to an error code that can contain one of the following values:
*
*   					 OS_ERR_NONE				if the name was copied to 'pname'
*   					 OS_ERR_EVENT_TYPE  		if 'pevent' is not pointing to the proper event
*   												control block type.
*   					 OS_ERR_PNAME_NULL  		You passed a NULL pointer for 'pname'
*   					 OS_ERR_PEVENT_NULL 		if you passed a NULL pointer for 'pevent'
*
* Returns    : The length of the string or 0 if the 'pevent' is a NULL pointer.
*********************************************************************************************************
*/

#if OS_EVENT_EN && (OS_EVENT_NAME_SIZE > 1)
INT8U OSEventNameGet(OS_EVENT *pevent, INT8U *pname, INT8U *perr)
{
	INT8U      len;
#if OS_CRITICAL_METHOD == 3 					 /* Allocate storage for CPU status register		   */
	OS_CPU_SR  cpu_sr = 0;
#endif



#if OS_ARG_CHK_EN > 0
	if (perr == (INT8U *) 0)
	{
		/* Validate 'perr'  								  */
		return (0);
	}
	if (pevent == (OS_EVENT *) 0)
	{
		/* Is 'pevent' a NULL pointer?  					  */
		*perr = OS_ERR_PEVENT_NULL;
		return (0);
	}
	if (pname == (INT8U *) 0)
	{
		/* Is 'pname' a NULL pointer?   					  */
		*perr = OS_ERR_PNAME_NULL;
		return (0);
	}
#endif
	if (OSIntNesting > 0)
	{
		/* See if trying to call from an ISR				  */
		*perr = OS_ERR_NAME_GET_ISR;
		return (0);
	}
	switch (pevent->OSEventType)
	{
		case OS_EVENT_TYPE_SEM:
		case OS_EVENT_TYPE_MUTEX:
		case OS_EVENT_TYPE_MBOX:
		case OS_EVENT_TYPE_Q:
			break;

		default:
			*perr = OS_ERR_EVENT_TYPE;
			return (0);
	}
	OS_ENTER_CRITICAL();
	len = OS_StrCopy(pname, pevent->OSEventName);   /* Copy name from OS_EVENT  					 */
	OS_EXIT_CRITICAL();
	*perr = OS_ERR_NONE;
	return (len);
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*   					  ASSIGN A NAME TO A SEMAPHORE, MUTEX, MAILBOX or QUEUE
*
* Description: This function assigns a name to a semaphore, mutex, mailbox or queue.
*
* Arguments  : pevent    is a pointer to the event group.  'pevent' can point either to a semaphore,
*   					 a mutex, a mailbox or a queue.  Where this function is concerned, it doesn't
*   					 matter the actual type.
*
*   		   pname	 is a pointer to an ASCII string that will be used as the name of the semaphore,
*   					 mutex, mailbox or queue.  The string must be able to hold at least
*   					 OS_EVENT_NAME_SIZE characters.
*
*   		   perr 	 is a pointer to an error code that can contain one of the following values:
*
*   					 OS_ERR_NONE				if the requested task is resumed
*   					 OS_ERR_EVENT_TYPE  		if 'pevent' is not pointing to the proper event
*   												control block type.
*   					 OS_ERR_PNAME_NULL  		You passed a NULL pointer for 'pname'
*   					 OS_ERR_PEVENT_NULL 		if you passed a NULL pointer for 'pevent'
*   					 OS_ERR_NAME_SET_ISR		if you called this function from an ISR
*
* Returns    : None
*********************************************************************************************************
*/

#if OS_EVENT_EN && (OS_EVENT_NAME_SIZE > 1)
void OSEventNameSet(OS_EVENT *pevent, INT8U *pname, INT8U *perr)
{
	INT8U      len;
#if OS_CRITICAL_METHOD == 3 					 /* Allocate storage for CPU status register		   */
	OS_CPU_SR  cpu_sr = 0;
#endif



#if OS_ARG_CHK_EN > 0
	if (perr == (INT8U *) 0)
	{
		/* Validate 'perr'  								  */
		return;
	}
	if (pevent == (OS_EVENT *) 0)
	{
		/* Is 'pevent' a NULL pointer?  					  */
		*perr = OS_ERR_PEVENT_NULL;
		return;
	}
	if (pname == (INT8U *) 0)
	{
		/* Is 'pname' a NULL pointer?   					  */
		*perr = OS_ERR_PNAME_NULL;
		return;
	}
#endif
	if (OSIntNesting > 0)
	{
		/* See if trying to call from an ISR				  */
		*perr = OS_ERR_NAME_SET_ISR;
		return;
	}
	switch (pevent->OSEventType)
	{
		case OS_EVENT_TYPE_SEM:
		case OS_EVENT_TYPE_MUTEX:
		case OS_EVENT_TYPE_MBOX:
		case OS_EVENT_TYPE_Q:
			break;

		default:
			*perr = OS_ERR_EVENT_TYPE;
			return;
	}
	OS_ENTER_CRITICAL();
	len = OS_StrLen(pname); 						  /* Can we fit the string in the storage area?    */
	if (len > (OS_EVENT_NAME_SIZE - 1))
	{
		/* No   										 */
		OS_EXIT_CRITICAL();
		*perr = OS_ERR_EVENT_NAME_TOO_LONG;
		return;
	}
	(void) OS_StrCopy(pevent->OSEventName, pname);     /* Yes, copy name to the event control block 	*/
	OS_EXIT_CRITICAL();
	*perr = OS_ERR_NONE;
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*   										  INITIALIZATION
*
* Description: This function is used to initialize the internals of uC/OS-II and MUST be called prior to
*   		   creating any uC/OS-II object and, prior to calling OSStart().
*
* Arguments  : none
*
* Returns    : none
*********************************************************************************************************
*/

void OSInit(void)
{
	OSInitHookBegin();  										 /* Call port specific initialization code   */

	OS_InitMisc();  											 /* Initialize miscellaneous variables  	 */

	OS_InitRdyList();   										 /* Initialize the Ready List   			 */

	OS_InitTCBList();   										 /* Initialize the free list of OS_TCBs 	 */

	OS_InitEventList(); 										 /* Initialize the free list of OS_EVENTs    */

#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
	OS_FlagInit();  											 /* Initialize the event flag structures	 */
#endif

#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
	OS_MemInit();   											 /* Initialize the memory manager   		 */
#endif

#if (OS_Q_EN > 0) && (OS_MAX_QS > 0)
	OS_QInit(); 												 /* Initialize the message queue structures  */
#endif

	OS_InitTaskIdle();  										 /* Create the Idle Task					 */
#if OS_TASK_STAT_EN > 0
	OS_InitTaskStat();  										 /* Create the Statistic Task   			 */
#endif

#if OS_TMR_EN > 0
	OSTmr_Init();   											 /* Initialize the Timer Manager			 */
#endif

	OSInitHookEnd();											 /* Call port specific init. code   		 */

#if OS_DEBUG_EN > 0
	OSDebugInit();
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
*   										   ENTER ISR
*
* Description: This function is used to notify uC/OS-II that you are about to service an interrupt
*   		   service routine (ISR).  This allows uC/OS-II to keep track of interrupt nesting and thus
*   		   only perform rescheduling at the last nested ISR.
*
* Arguments  : none
*
* Returns    : none
*
* Notes 	 : 1) This function should be called ith interrupts already disabled
*   		   2) Your ISR can directly increment OSIntNesting without calling this function because
*   			  OSIntNesting has been declared 'global'.
*   		   3) You MUST still call OSIntExit() even though you increment OSIntNesting directly.
*   		   4) You MUST invoke OSIntEnter() and OSIntExit() in pair.  In other words, for every call
*   			  to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
*   			  end of the ISR.
*   		   5) You are allowed to nest interrupts up to 255 levels deep.
*   		   6) I removed the OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() around the increment because
*   			  OSIntEnter() is always called with interrupts disabled.
*********************************************************************************************************
*/

void OSIntEnter(void)
{
	if (OSRunning == OS_TRUE)
	{
		if (OSIntNesting < 255u)
		{
			OSIntNesting++; 					 /* Increment ISR nesting level 					   */
		}
	}
}
/*$PAGE*/
/*
*********************************************************************************************************
*   											EXIT ISR
*
* Description: This function is used to notify uC/OS-II that you have completed serviving an ISR.  When
*   		   the last nested ISR has completed, uC/OS-II will call the scheduler to determine whether
*   		   a new, high-priority task, is ready to run.
*
* Arguments  : none
*
* Returns    : none
*
* Notes 	 : 1) You MUST invoke OSIntEnter() and OSIntExit() in pair.  In other words, for every call
*   			  to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
*   			  end of the ISR.
*   		   2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock())
*********************************************************************************************************
*/

void OSIntExit(void)
{
#if OS_CRITICAL_METHOD == 3 							   /* Allocate storage for CPU status register */
	OS_CPU_SR  cpu_sr = 0;
#endif



	if (OSRunning == OS_TRUE)
	{
		OS_ENTER_CRITICAL();
		if (OSIntNesting > 0)
		{
			/* Prevent OSIntNesting from wrapping   	*/
			OSIntNesting--;
		}
		if (OSIntNesting == 0)
		{
			/* Reschedule only if all ISRs complete ... */
			if (OSLockNesting == 0)
			{
				/* ... and not locked.  					*/
				OS_SchedNew();
				if (OSPrioHighRdy != OSPrioCur)
				{
					/* No Ctx Sw if current task is highest rdy */
					OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
#if OS_TASK_PROFILE_EN > 0
					OSTCBHighRdy->OSTCBCtxSwCtr++;  	   /* Inc. # of context switches to this task  */
#endif
					OSCtxSwCtr++;   					   /* Keep track of the number of ctx switches */
					OSIntCtxSw();   					   /* Perform interrupt level ctx switch	   */
				}
			}
		}
		OS_EXIT_CRITICAL();
	}
}
/*$PAGE*/
/*
*********************************************************************************************************
*   									   PREVENT SCHEDULING
*
* Description: This function is used to prevent rescheduling to take place.  This allows your application
*   		   to prevent context switches until you are ready to permit context switching.
*
* Arguments  : none
*
* Returns    : none
*
* Notes 	 : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair.  In other words, for every
*   			  call to OSSchedLock() you MUST have a call to OSSchedUnlock().
*********************************************************************************************************
*/

#if OS_SCHED_LOCK_EN > 0
void OSSchedLock(void)
{
#if OS_CRITICAL_METHOD == 3 					 /* Allocate storage for CPU status register		   */
	OS_CPU_SR  cpu_sr = 0;
#endif



	if (OSRunning == OS_TRUE)
	{
		/* Make sure multitasking is running				  */
		OS_ENTER_CRITICAL();
		if (OSIntNesting == 0)
		{
			/* Can't call from an ISR                             */
			if (OSLockNesting < 255u)
			{

⌨️ 快捷键说明

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