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

📄 os_task.c

📁 MCB2300_ucgui_LCD320240.rar LPC2368的uc/gui的移植
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
*********************************************************************************************************
*   											 uC/OS-II
*   									   The Real-Time Kernel
*   										 TASK MANAGEMENT
*
*   					   (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL
*   										All Rights Reserved
*
* File    : OS_TASK.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
#include <ucos_ii.h>
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*   									 CHANGE PRIORITY OF A TASK
*
* Description: This function allows you to change the priority of a task dynamically.  Note that the new
*   		   priority MUST be available.
*
* Arguments  : oldp 	is the old priority
*
*   		   newp 	is the new priority
*
* Returns    : OS_ERR_NONE  		  is the call was successful
*   		   OS_ERR_PRIO_INVALID    if the priority you specify is higher that the maximum allowed
*   								  (i.e. >= OS_LOWEST_PRIO)
*   		   OS_ERR_PRIO_EXIST	  if the new priority already exist.
*   		   OS_ERR_PRIO  		  there is no task with the specified OLD priority (i.e. the OLD task does
*   								  not exist.
*   		   OS_ERR_TASK_NOT_EXIST  if the task is assigned to a Mutex PIP.
*********************************************************************************************************
*/

#if OS_TASK_CHANGE_PRIO_EN > 0
INT8U OSTaskChangePrio(INT8U oldprio, INT8U newprio)
{
#if OS_EVENT_EN
	OS_EVENT	*pevent;
#endif
	OS_TCB  	*ptcb;
	INT8U   	 x;
	INT8U   	 y;
#if OS_LOWEST_PRIO <= 63
	INT8U   	 bitx;
	INT8U   	 bity;
#else
	INT16U  	 bitx;
	INT16U  	 bity;
#endif
	INT8U   	 y_old;
#if OS_CRITICAL_METHOD == 3
	OS_CPU_SR    cpu_sr = 0;									/* Storage for CPU status register     */
#endif



#if OS_ARG_CHK_EN > 0
	if (oldprio >= OS_LOWEST_PRIO)
	{
		if (oldprio != OS_PRIO_SELF)
		{
			return (OS_ERR_PRIO_INVALID);
		}
	}
	if (newprio >= OS_LOWEST_PRIO)
	{
		return (OS_ERR_PRIO_INVALID);
	}
#endif
	OS_ENTER_CRITICAL();
	if (OSTCBPrioTbl[newprio] != (OS_TCB *) 0)
	{
		/* New priority must not already exist */
		OS_EXIT_CRITICAL();
		return (OS_ERR_PRIO_EXIST);
	}
	if (oldprio == OS_PRIO_SELF)
	{
		/* See if changing self 			   */
		oldprio = OSTCBCur->OSTCBPrio;  						/* Yes, get priority				   */
	}
	ptcb = OSTCBPrioTbl[oldprio];
	if (ptcb == (OS_TCB *) 0)
	{
		/* Does task to change exist?   	   */
		OS_EXIT_CRITICAL(); 									/* No, can't change its priority!      */
		return (OS_ERR_PRIO);
	}
	if (ptcb == OS_TCB_RESERVED)
	{
		/* Is task assigned to Mutex		   */
		OS_EXIT_CRITICAL(); 									/* No, can't change its priority!      */
		return (OS_ERR_TASK_NOT_EXIST);
	}
#if OS_LOWEST_PRIO <= 63
	y = (INT8U) (newprio >> 3); 			 /* Yes, compute new TCB fields 		*/
	x = (INT8U) (newprio & 0x07);
	bity = (INT8U) (1 << y);
	bitx = (INT8U) (1 << x);
#else
	y = (INT8U) ((newprio >> 4) & 0x0F);
	x = (INT8U) (newprio & 0x0F);
	bity = (INT16U) (1 << y);
	bitx = (INT16U) (1 << x);
#endif

	OSTCBPrioTbl[oldprio] = (OS_TCB *) 0;   					 /* Remove TCB from old priority		*/
	OSTCBPrioTbl[newprio] = ptcb;   							/* Place pointer to TCB @ new priority */
	y_old = ptcb->OSTCBY;
	if ((OSRdyTbl[y_old] & ptcb->OSTCBBitX) != 0)
	{
		/* If task is ready make it not 	   */
		OSRdyTbl[y_old] &= ~ptcb->OSTCBBitX;
		if (OSRdyTbl[y_old] == 0)
		{
			OSRdyGrp &= ~ptcb->OSTCBBitY;
		}
		OSRdyGrp |= bity;   								 /* Make new priority ready to run  	*/
		OSRdyTbl[y] |= bitx;
	}
#if OS_EVENT_EN
	pevent = ptcb->OSTCBEventPtr;
	if (pevent != (OS_EVENT *) 0)
	{
		/* ... remove from event wait list     */
		pevent->OSEventTbl[y_old] &= ~ptcb->OSTCBBitX;
		if (pevent->OSEventTbl[y_old] == 0)
		{
			pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
		}
		pevent->OSEventGrp |= bity; 						 /* Add new priority to wait list   	*/
		pevent->OSEventTbl[y] |= bitx;
	}
#endif
	ptcb->OSTCBPrio = newprio;  								/* Set new task priority			   */
	ptcb->OSTCBY = y;
	ptcb->OSTCBX = x;
	ptcb->OSTCBBitY = bity;
	ptcb->OSTCBBitX = bitx;
	OS_EXIT_CRITICAL();
	if (OSRunning == OS_TRUE)
	{
		OS_Sched(); 											/* Find new highest priority task      */
	}
	return (OS_ERR_NONE);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*   										 CREATE A TASK
*
* Description: This function is used to have uC/OS-II manage the execution of a task.  Tasks can either
*   		   be created prior to the start of multitasking or by a running task.  A task cannot be
*   		   created by an ISR.
*
* Arguments  : task 	is a pointer to the task's code
*
*   		   p_arg	is a pointer to an optional data area which can be used to pass parameters to
*   					the task when the task first executes.  Where the task is concerned it thinks
*   					it was invoked and passed the argument 'p_arg' as follows:
*
*   						void Task (void *p_arg)
*   						{
*   							for (;;) {
*   								Task code;
*   							}
*   						}
*
*   		   ptos 	is a pointer to the task's top of stack.  If the configuration constant
*   					OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
*   					memory to low memory).  'pstk' will thus point to the highest (valid) memory
*   					location of the stack.  If OS_STK_GROWTH is set to 0, 'pstk' will point to the
*   					lowest memory location of the stack and the stack will grow with increasing
*   					memory locations.
*
*   		   prio 	is the task's priority.  A unique priority MUST be assigned to each task and the
*   					lower the number, the higher the priority.
*
* Returns    : OS_ERR_NONE  		   if the function was successful.
*   		   OS_PRIO_EXIT 		   if the task priority already exist
*   								   (each task MUST have a unique priority).
*   		   OS_ERR_PRIO_INVALID     if the priority you specify is higher that the maximum allowed
*   								   (i.e. >= OS_LOWEST_PRIO)
*   		   OS_ERR_TASK_CREATE_ISR  if you tried to create a task from an ISR.
*********************************************************************************************************
*/

#if OS_TASK_CREATE_EN > 0
INT8U OSTaskCreate(void (*task) (void *p_arg), void *p_arg, OS_STK *ptos, INT8U prio)
{
	OS_STK    *psp;
	INT8U      err;
#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 (prio > OS_LOWEST_PRIO)
	{
		/* Make sure priority is within allowable range 		  */
		return (OS_ERR_PRIO_INVALID);
	}
#endif
	OS_ENTER_CRITICAL();
	if (OSIntNesting > 0)
	{
		/* Make sure we don't create the task from within an ISR  */
		OS_EXIT_CRITICAL();
		return (OS_ERR_TASK_CREATE_ISR);
	}
	if (OSTCBPrioTbl[prio] == (OS_TCB *) 0)
	{
		/* Make sure task doesn't already exist at this priority  */
		OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ...  */
		/* ... the same thing until task is created.			  */
		OS_EXIT_CRITICAL();
		psp = OSTaskStkInit(task, p_arg, ptos, 0);  			/* Initialize the task's stack         */
		err = OS_TCBInit(prio, psp, (OS_STK *) 0, 0, 0, (void *) 0, 0);
		if (err == OS_ERR_NONE)
		{
			if (OSRunning == OS_TRUE)
			{
				/* Find highest priority task if multitasking has started */
				OS_Sched();
			}
		}
		else
		{
			OS_ENTER_CRITICAL();
			OSTCBPrioTbl[prio] = (OS_TCB *) 0;/* Make this priority available to others 				*/
			OS_EXIT_CRITICAL();
		}
		return (err);
	}
	OS_EXIT_CRITICAL();
	return (OS_ERR_PRIO_EXIST);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*   								  CREATE A TASK (Extended Version)
*
* Description: This function is used to have uC/OS-II manage the execution of a task.  Tasks can either
*   		   be created prior to the start of multitasking or by a running task.  A task cannot be
*   		   created by an ISR.  This function is similar to OSTaskCreate() except that it allows
*   		   additional information about a task to be specified.
*
* Arguments  : task 	 is a pointer to the task's code
*
*   		   p_arg	 is a pointer to an optional data area which can be used to pass parameters to
*   					 the task when the task first executes.  Where the task is concerned it thinks
*   					 it was invoked and passed the argument 'p_arg' as follows:
*
*   						 void Task (void *p_arg)
*   						 {
*   							 for (;;) {
*   								 Task code;
*   							 }
*   						 }
*
*   		   ptos 	 is a pointer to the task's top of stack.  If the configuration constant
*   					 OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
*   					 memory to low memory).  'ptos' will thus point to the highest (valid) memory
*   					 location of the stack.  If OS_STK_GROWTH is set to 0, 'ptos' will point to the
*   					 lowest memory location of the stack and the stack will grow with increasing
*   					 memory locations.  'ptos' MUST point to a valid 'free' data item.
*
*   		   prio 	 is the task's priority.  A unique priority MUST be assigned to each task and the
*   					 lower the number, the higher the priority.
*
*   		   id   	 is the task's ID (0..65535)
*
*   		   pbos 	 is a pointer to the task's bottom of stack.  If the configuration constant
*   					 OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
*   					 memory to low memory).  'pbos' will thus point to the LOWEST (valid) memory
*   					 location of the stack.  If OS_STK_GROWTH is set to 0, 'pbos' will point to the
*   					 HIGHEST memory location of the stack and the stack will grow with increasing
*   					 memory locations.  'pbos' MUST point to a valid 'free' data item.
*
*   		   stk_size  is the size of the stack in number of elements.  If OS_STK is set to INT8U,
*   					 'stk_size' corresponds to the number of bytes available.  If OS_STK is set to
*   					 INT16U, 'stk_size' contains the number of 16-bit entries available.  Finally, if
*   					 OS_STK is set to INT32U, 'stk_size' contains the number of 32-bit entries
*   					 available on the stack.
*
*   		   pext 	 is a pointer to a user supplied memory location which is used as a TCB extension.
*   					 For example, this user memory can hold the contents of floating-point registers
*   					 during a context switch, the time each task takes to execute, the number of times
*   					 the task has been switched-in, etc.
*
*   		   opt  	 contains additional information (or options) about the behavior of the task.  The
*   					 LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application
*   					 specific.  See OS_TASK_OPT_??? in uCOS-II.H.  Current choices are:
*
*   					 OS_TASK_OPT_STK_CHK	  Stack checking to be allowed for the task
*   					 OS_TASK_OPT_STK_CLR	  Clear the stack when the task is created
*   					 OS_TASK_OPT_SAVE_FP	  If the CPU has floating-point registers, save them
*   											  during a context switch.
*
* Returns    : OS_ERR_NONE  		   if the function was successful.
*   		   OS_PRIO_EXIT 		   if the task priority already exist
*   								   (each task MUST have a unique priority).
*   		   OS_ERR_PRIO_INVALID     if the priority you specify is higher that the maximum allowed
*   								   (i.e. > OS_LOWEST_PRIO)
*   		   OS_ERR_TASK_CREATE_ISR  if you tried to create a task from an ISR.
*********************************************************************************************************
*/
/*$PAGE*/
#if OS_TASK_CREATE_EXT_EN > 0
INT8U OSTaskCreateExt(void   (*task) (void *p_arg), void *p_arg, OS_STK *ptos, INT8U	prio, INT16U   id, OS_STK *pbos, INT32U   stk_size, void *pext, INT16U   opt)
{
	OS_STK    *psp;
	INT8U      err;
#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 (prio > OS_LOWEST_PRIO)
	{
		/* Make sure priority is within allowable range 		  */
		return (OS_ERR_PRIO_INVALID);
	}
#endif
	OS_ENTER_CRITICAL();
	if (OSIntNesting > 0)
	{
		/* Make sure we don't create the task from within an ISR  */
		OS_EXIT_CRITICAL();
		return (OS_ERR_TASK_CREATE_ISR);
	}
	if (OSTCBPrioTbl[prio] == (OS_TCB *) 0)
	{
		/* Make sure task doesn't already exist at this priority  */
		OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ...  */
		/* ... the same thing until task is created.			  */
		OS_EXIT_CRITICAL();

#if OS_TASK_STAT_STK_CHK_EN > 0
		OS_TaskStkClr(pbos, stk_size, opt); 				   /* Clear the task stack (if needed)     */
#endif  	  

		psp = OSTaskStkInit(task, p_arg, ptos, opt);		   /* Initialize the task's stack          */
		err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);
		if (err == OS_ERR_NONE)
		{
			if (OSRunning == OS_TRUE)
			{
				/* Find HPT if multitasking has started */
				OS_Sched();
			}
		}
		else
		{
			OS_ENTER_CRITICAL();
			OSTCBPrioTbl[prio] = (OS_TCB *) 0;  				/* Make this priority avail. to others  */
			OS_EXIT_CRITICAL();
		}
		return (err);
	}
	OS_EXIT_CRITICAL();
	return (OS_ERR_PRIO_EXIST);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*   										 DELETE A TASK
*
* Description: This function allows you to delete a task.  The calling task can delete itself by
*   		   its own priority number.  The deleted task is returned to the dormant state and can be
*   		   re-activated by creating the deleted task again.
*
* Arguments  : prio    is the priority of the task to delete.  Note that you can explicitely delete
*   				   the current task without knowing its priority level by setting 'prio' to
*   				   OS_PRIO_SELF.
*
* Returns    : OS_ERR_NONE  		   if the call is successful
*   		   OS_ERR_TASK_DEL_IDLE    if you attempted to delete uC/OS-II's idle task
*   		   OS_ERR_PRIO_INVALID     if the priority you specify is higher that the maximum allowed
*   								   (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
*   		   OS_ERR_TASK_DEL  	   if the task is assigned to a Mutex PIP.   
*   		   OS_ERR_TASK_NOT_EXIST   if the task you want to delete does not exist.
*   		   OS_ERR_TASK_DEL_ISR     if you tried to delete a task from an ISR
*
* Notes 	 : 1) To reduce interrupt latency, OSTaskDel() 'disables' the task:
*   				 a) by making it not ready
*   				 b) by removing it from any wait lists
*   				 c) by preventing OSTimeTick() from making the task ready to run.
*   			  The task can then be 'unlinked' from the miscellaneous structures in uC/OS-II.
*   		   2) The function OS_Dummy() is called after OS_EXIT_CRITICAL() because, on most processors,
*   			  the next instruction following the enable interrupt instruction is ignored.
*   		   3) An ISR cannot delete a task.
*   		   4) The lock nesting counter is incremented because, for a brief instant, if the current

⌨️ 快捷键说明

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