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

📄 os_task.c

📁 lpc2368-keil环境下的ucos的移植例程
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*********************************************************************************************************
*   											 uC/OS-II
*   									   The Real-Time Kernel
*   										 TASK MANAGEMENT
*
*   					   (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
*   										All Rights Reserved
*
* File : OS_TASK.C
* By   : Jean J. Labrosse
*********************************************************************************************************
*/

#ifndef  OS_MASTER_FILE
#include "..\APP\includes.h"
#endif

/*
*********************************************************************************************************
*   									 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_NO_ERR		is the call was successful
*   		   OS_PRIO_INVALID  if the priority you specify is higher that the maximum allowed
*   							(i.e. >= OS_LOWEST_PRIO)
*   		   OS_PRIO_EXIST	if the new priority already exist.
*   		   OS_PRIO_ERR  	there is no task with the specified OLD priority (i.e. the OLD task does
*   							not exist.
*********************************************************************************************************
*/

#if OS_TASK_CHANGE_PRIO_EN > 0
INT8U OSTaskChangePrio(INT8U oldprio, INT8U newprio)
{
#if OS_CRITICAL_METHOD == 3 					 /* Allocate storage for CPU status register		   */
	OS_CPU_SR    cpu_sr;
#endif

#if OS_EVENT_EN > 0
	OS_EVENT	*pevent;
#endif

	OS_TCB  	*ptcb;
	INT8U   	 x;
	INT8U   	 y;
	INT8U   	 bitx;
	INT8U   	 bity;



#if OS_ARG_CHK_EN > 0
	if ((oldprio >= OS_LOWEST_PRIO && oldprio != OS_PRIO_SELF) || newprio >= OS_LOWEST_PRIO)
	{
		return (OS_PRIO_INVALID);
	}
#endif
	OS_ENTER_CRITICAL();
	if (OSTCBPrioTbl[newprio] != (OS_TCB *) 0)
	{
		/* New priority must not already exist */
		OS_EXIT_CRITICAL();
		return (OS_PRIO_EXIST);
	}
	else
	{
		OSTCBPrioTbl[newprio] = (OS_TCB *) 1;   				 /* Reserve the entry to prevent others */
		OS_EXIT_CRITICAL();
		y = newprio >> 3;   								 /* Precompute to reduce INT. latency   */
		bity = OSMapTbl[y];
		x = newprio & 0x07;
		bitx = OSMapTbl[x];
		OS_ENTER_CRITICAL();
		if (oldprio == OS_PRIO_SELF)
		{
			/* See if changing self 			   */
			oldprio = OSTCBCur->OSTCBPrio;  					/* Yes, get priority				   */
		}
		ptcb = OSTCBPrioTbl[oldprio];
		if (ptcb != (OS_TCB *) 0)
		{
			/* Task to change must exist		   */
			OSTCBPrioTbl[oldprio] = (OS_TCB *) 0;   			 /* Remove TCB from old priority		*/
			if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00)
			{
				/* If task is ready make it not */
				if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00)
				{
					OSRdyGrp &= ~ptcb->OSTCBBitY;
				}
				OSRdyGrp |= bity;   						 /* Make new priority ready to run  	*/
				OSRdyTbl[y] |= bitx;
#if OS_EVENT_EN > 0
			}
			else
			{
				pevent = ptcb->OSTCBEventPtr;
				if (pevent != (OS_EVENT *) 0)
				{
					/* Remove from event wait list  */
					if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)
					{
						pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
					}
					pevent->OSEventGrp |= bity; 			 /* Add new priority to wait list   	*/
					pevent->OSEventTbl[y] |= bitx;
				}
#endif
			}
			OSTCBPrioTbl[newprio] = ptcb;   					/* Place pointer to TCB @ new priority */
			ptcb->OSTCBPrio = newprio;  				  /* Set new task priority  			 */
			ptcb->OSTCBY = y;
			ptcb->OSTCBX = x;
			ptcb->OSTCBBitY = bity;
			ptcb->OSTCBBitX = bitx;
			OS_EXIT_CRITICAL();
			OS_Sched(); 										/* Run highest priority task ready     */
			return (OS_NO_ERR);
		}
		else
		{
			OSTCBPrioTbl[newprio] = (OS_TCB *) 0;   			 /* Release the reserved prio.  		*/
			OS_EXIT_CRITICAL();
			return (OS_PRIO_ERR);   							/* Task to change didn't exist         */
		}
	}
}
#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
*
*   		   pdata	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 'pdata' as follows:
*
*   						void Task (void *pdata)
*   						{
*   							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_NO_ERR		if the function was successful.
*   		   OS_PRIO_EXIT 	if the task priority already exist
*   							(each task MUST have a unique priority).
*   		   OS_PRIO_INVALID  if the priority you specify is higher that the maximum allowed
*   							(i.e. >= OS_LOWEST_PRIO)
*********************************************************************************************************
*/

#if OS_TASK_CREATE_EN > 0
INT8U OSTaskCreate(void (*task) (void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 				 /* Allocate storage for CPU status register			   */
	OS_CPU_SR  cpu_sr;
#endif
	OS_STK    *psp;
	INT8U      err;


#if OS_ARG_CHK_EN > 0
	if (prio > OS_LOWEST_PRIO)
	{
		/* Make sure priority is within allowable range 		  */
		return (OS_PRIO_INVALID);
	}
#endif
	OS_ENTER_CRITICAL();
	if (OSTCBPrioTbl[prio] == (OS_TCB *) 0)
	{
		/* Make sure task doesn't already exist at this priority  */
		OSTCBPrioTbl[prio] = (OS_TCB *) 1;    /* Reserve the priority to prevent others from doing ...  */
		/* ... the same thing until task is created.			  */
		OS_EXIT_CRITICAL();
		psp = (OS_STK *) OSTaskStkInit(task, pdata, ptos, 0);    /* Initialize the task's stack         */
		err = OS_TCBInit(prio, psp, (OS_STK *) 0, 0, 0, (void *) 0, 0);
		if (err == OS_NO_ERR)
		{
			OS_ENTER_CRITICAL();
			OSTaskCtr++;										/* Increment the #tasks counter 	   */
			OS_EXIT_CRITICAL();
			if (OSRunning == 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_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
*
*   		   pdata	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 'pdata' as follows:
*
*   						void Task (void *pdata)
*   						{
*   							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.  'pstk' 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.
*
* Returns    : OS_NO_ERR		if the function was successful.
*   		   OS_PRIO_EXIT 	if the task priority already exist
*   							(each task MUST have a unique priority).
*   		   OS_PRIO_INVALID  if the priority you specify is higher that the maximum allowed
*   							(i.e. > OS_LOWEST_PRIO)
*********************************************************************************************************
*/
/*$PAGE*/
#if OS_TASK_CREATE_EXT_EN > 0
INT8U OSTaskCreateExt(void   (*task) (void *pd), void *pdata, OS_STK *ptos, INT8U    prio, INT16U   id, OS_STK *pbos, INT32U   stk_size, void *pext, INT16U   opt)
{
#if OS_CRITICAL_METHOD == 3 				 /* Allocate storage for CPU status register			   */
	OS_CPU_SR  cpu_sr;
#endif
	OS_STK    *psp;
	INT8U      err;


#if OS_ARG_CHK_EN > 0
	if (prio > OS_LOWEST_PRIO)
	{
		/* Make sure priority is within allowable range 		  */
		return (OS_PRIO_INVALID);
	}
#endif
	OS_ENTER_CRITICAL();
	if (OSTCBPrioTbl[prio] == (OS_TCB *) 0)
	{
		/* Make sure task doesn't already exist at this priority  */
		OSTCBPrioTbl[prio] = (OS_TCB *) 1;    /* Reserve the priority to prevent others from doing ...  */
		/* ... the same thing until task is created.			  */
		OS_EXIT_CRITICAL();

		if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) ||    /* See if stack checking has been enabled 	*/
			((opt & OS_TASK_OPT_STK_CLR) != 0x0000))
		{
			/* See if stack needs to be cleared 		  */
#if OS_STK_GROWTH == 1
			(void) memset(pbos, 0, stk_size * sizeof(OS_STK));
#else
			(void) memset(ptos, 0, stk_size * sizeof(OS_STK));
#endif
		}

		psp = (OS_STK *) OSTaskStkInit(task, pdata, ptos, opt); /* Initialize the task's stack          */
		err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);
		if (err == OS_NO_ERR)
		{
			OS_ENTER_CRITICAL();
			OSTaskCtr++;									   /* Increment the #tasks counter  	   */
			OS_EXIT_CRITICAL();
			if (OSRunning == 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_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_NO_ERR		   if the call is successful
*   		   OS_TASK_DEL_IDLE    if you attempted to delete uC/OS-II's idle task
*   		   OS_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_TASK_DEL_ERR     if the task you want to delete does not exist
*   		   OS_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
*   			  task is being deleted, the current task would not be able to be rescheduled because it
*   			  is removed from the ready list.  Incrementing the nesting counter prevents another task
*   			  from being schedule.  This means that an ISR would return to the current task which is
*   			  being deleted.  The rest of the deletion would thus be able to be completed.
*********************************************************************************************************
*/
/*$PAGE*/
#if OS_TASK_DEL_EN > 0
INT8U OSTaskDel(INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 					 /* Allocate storage for CPU status register		   */
	OS_CPU_SR     cpu_sr;
#endif

#if OS_EVENT_EN > 0
	OS_EVENT	 *pevent;
#endif    
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
	OS_FLAG_NODE *pnode;
#endif
	OS_TCB  	 *ptcb;
	//   BOOLEAN	   self;



	if (OSIntNesting > 0)
	{
		/* See if trying to delete from ISR    */
		return (OS_TASK_DEL_ISR);
	}
#if OS_ARG_CHK_EN > 0
	if (prio == OS_IDLE_PRIO)
	{
		/* Not allowed to delete idle task     */
		return (OS_TASK_DEL_IDLE);
	}
	if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF)
	{
		/* Task priority valid ?			   */
		return (OS_PRIO_INVALID);
	}
#endif
	OS_ENTER_CRITICAL();
	if (prio == OS_PRIO_SELF)
	{
		/* See if requesting to delete self    */
		prio = OSTCBCur->OSTCBPrio; 							/* Set priority to delete to current   */
	}
	ptcb = OSTCBPrioTbl[prio];
	if (ptcb != (OS_TCB *) 0)
	{
		/* Task to delete must exist	  */
		if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00)
		{

⌨️ 快捷键说明

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