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

📄 os_task.c

📁 lpc2368-keil环境下的ucos的移植例程
💻 C
📖 第 1 页 / 共 2 页
字号:
			/* Make task not ready  		  */
			OSRdyGrp &= ~ptcb->OSTCBBitY;
		}
#if OS_EVENT_EN > 0
		pevent = ptcb->OSTCBEventPtr;
		if (pevent != (OS_EVENT *) 0)
		{
			/* If task is waiting on event  	   */
			if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)
			{
				/* ... remove task from */
				pevent->OSEventGrp &= ~ptcb->OSTCBBitY; 					   /* ... event ctrl block */
			}
		}
#endif
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
		pnode = ptcb->OSTCBFlagNode;
		if (pnode != (OS_FLAG_NODE *) 0)
		{
			/* If task is waiting on event flag    */
			OS_FlagUnlink(pnode);   							/* Remove from wait list			   */
		}
#endif
		ptcb->OSTCBDly = 0; 								   /* Prevent OSTimeTick() from updating  */
		ptcb->OSTCBStat = OS_STAT_RDY;  						/* Prevent task from being resumed     */
		if (OSLockNesting < 255)
		{
			OSLockNesting++;
		}
		OS_EXIT_CRITICAL(); 									/* Enabling INT. ignores next instruc. */
		OS_Dummy(); 											/* ... Dummy ensures that INTs will be */
		OS_ENTER_CRITICAL();									/* ... disabled HERE!   			   */
		if (OSLockNesting > 0)
		{
			OSLockNesting--;
		}
		OSTaskDelHook(ptcb);									/* Call user defined hook   		   */
		OSTaskCtr--;											/* One less task being managed  	   */
		OSTCBPrioTbl[prio] = (OS_TCB *) 0;  					 /* Clear old priority entry			*/
		if (ptcb->OSTCBPrev == (OS_TCB *) 0)
		{
			/* Remove from TCB chain			   */
			ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *) 0;
			OSTCBList = ptcb->OSTCBNext;
		}
		else
		{
			ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
			ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
		}
		ptcb->OSTCBNext = OSTCBFreeList;						/* Return TCB to free TCB list  	   */
		OSTCBFreeList = ptcb;
		OS_EXIT_CRITICAL();
		OS_Sched(); 											/* Find new highest priority task      */
		return (OS_NO_ERR);
	}
	OS_EXIT_CRITICAL();
	return (OS_TASK_DEL_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*   								 REQUEST THAT A TASK DELETE ITSELF
*
* Description: This function is used to:
*   				a) notify a task to delete itself.
*   				b) to see if a task requested that the current task delete itself.
*   		   This function is a little tricky to understand.  Basically, you have a task that needs
*   		   to be deleted however, this task has resources that it has allocated (memory buffers,
*   		   semaphores, mailboxes, queues etc.).  The task cannot be deleted otherwise these
*   		   resources would not be freed.  The requesting task calls OSTaskDelReq() to indicate that
*   		   the task needs to be deleted.  Deleting of the task is however, deferred to the task to
*   		   be deleted.  For example, suppose that task #10 needs to be deleted.  The requesting task
*   		   example, task #5, would call OSTaskDelReq(10).  When task #10 gets to execute, it calls
*   		   this function by specifying OS_PRIO_SELF and monitors the returned value.  If the return
*   		   value is OS_TASK_DEL_REQ, another task requested a task delete.  Task #10 would look like
*   		   this:
*
*   				void Task(void *data)
*   				{
*   					.
*   					.
*   					while (1) {
*   						OSTimeDly(1);
*   						if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) {
*   							Release any owned resources;
*   							De-allocate any dynamic memory;
*   							OSTaskDel(OS_PRIO_SELF);
*   						}
*   					}
*   				}
*
* Arguments  : prio    is the priority of the task to request the delete from
*
* Returns    : OS_NO_ERR		  if the task exist and the request has been registered
*   		   OS_TASK_NOT_EXIST  if the task has been deleted.  This allows the caller to know whether
*   							  the request has been executed.
*   		   OS_TASK_DEL_IDLE   if you requested 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_REQ    if a task (possibly another task) requested that the running task be
*   							  deleted.
*********************************************************************************************************
*/
/*$PAGE*/
#if OS_TASK_DEL_EN > 0
INT8U OSTaskDelReq(INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 					 /* Allocate storage for CPU status register		   */
	OS_CPU_SR  cpu_sr;
#endif
	BOOLEAN    stat;
	INT8U      err;
	OS_TCB    *ptcb;


#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
	if (prio == OS_PRIO_SELF)
	{
		/* See if a task is requesting to ...  */
		OS_ENTER_CRITICAL();									/* ... this task to delete itself      */
		stat = OSTCBCur->OSTCBDelReq;   						/* Return request status to caller     */
		OS_EXIT_CRITICAL();
		return (stat);
	}
	OS_ENTER_CRITICAL();
	ptcb = OSTCBPrioTbl[prio];
	if (ptcb != (OS_TCB *) 0)
	{
		/* Task to delete must exist		   */
		ptcb->OSTCBDelReq = OS_TASK_DEL_REQ;					/* Set flag indicating task to be DEL. */
		err = OS_NO_ERR;
	}
	else
	{
		err = OS_TASK_NOT_EXIST;				  /* Task must be deleted   			 */
	}
	OS_EXIT_CRITICAL();
	return (err);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*   									 RESUME A SUSPENDED TASK
*
* Description: This function is called to resume a previously suspended task.  This is the only call that
*   		   will remove an explicit task suspension.
*
* Arguments  : prio 	is the priority of the task to resume.
*
* Returns    : OS_NO_ERR				if the requested task is resumed
*   		   OS_PRIO_INVALID  		if the priority you specify is higher that the maximum allowed
*   									(i.e. >= OS_LOWEST_PRIO)
*   		   OS_TASK_RESUME_PRIO  	if the task to resume does not exist
*   		   OS_TASK_NOT_SUSPENDED	if the task to resume has not been suspended
*********************************************************************************************************
*/

#if OS_TASK_SUSPEND_EN > 0
INT8U OSTaskResume(INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 					 /* Allocate storage for CPU status register		   */
	OS_CPU_SR  cpu_sr;
#endif
	OS_TCB    *ptcb;


#if OS_ARG_CHK_EN > 0
	if (prio >= OS_LOWEST_PRIO)
	{
		/* Make sure task priority is valid    */
		return (OS_PRIO_INVALID);
	}
#endif
	OS_ENTER_CRITICAL();
	ptcb = OSTCBPrioTbl[prio];
	if (ptcb == (OS_TCB *) 0)
	{
		/* Task to suspend must exist   	   */
		OS_EXIT_CRITICAL();
		return (OS_TASK_RESUME_PRIO);
	}
	if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY)
	{
		/* Task must be suspended   */
		if (((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) &&   	/* Remove suspension		*/
			(ptcb->OSTCBDly == 0))
		{
			/* Must not be delayed  	*/
			OSRdyGrp |= ptcb->OSTCBBitY;					 /* Make task ready to run   */
			OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
			OS_EXIT_CRITICAL();
			OS_Sched();
		}
		else
		{
			OS_EXIT_CRITICAL();
		}
		return (OS_NO_ERR);
	}
	OS_EXIT_CRITICAL();
	return (OS_TASK_NOT_SUSPENDED);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*   										  STACK CHECKING
*
* Description: This function is called to check the amount of free memory left on the specified task's
*   		   stack.
*
* Arguments  : prio 	is the task priority
*
*   		   pdata	is a pointer to a data structure of type OS_STK_DATA.
*
* Returns    : OS_NO_ERR		   upon success
*   		   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_NOT_EXIST   if the desired task has not been created
*   		   OS_TASK_OPT_ERR     if you did NOT specified OS_TASK_OPT_STK_CHK when the task was created
*********************************************************************************************************
*/
#if OS_TASK_CREATE_EXT_EN > 0
INT8U OSTaskStkChk(INT8U prio, OS_STK_DATA *pdata)
{
#if OS_CRITICAL_METHOD == 3 					 /* Allocate storage for CPU status register		   */
	OS_CPU_SR  cpu_sr;
#endif
	OS_TCB    *ptcb;
	OS_STK    *pchk;
	INT32U     free;
	INT32U     size;


#if OS_ARG_CHK_EN > 0
	if (prio > OS_LOWEST_PRIO && prio != OS_PRIO_SELF)
	{
		/* Make sure task priority is valid    */
		return (OS_PRIO_INVALID);
	}
#endif
	pdata->OSFree = 0;  										/* Assume failure, set to 0 size	   */
	pdata->OSUsed = 0;
	OS_ENTER_CRITICAL();
	if (prio == OS_PRIO_SELF)
	{
		/* See if check for SELF						*/
		prio = OSTCBCur->OSTCBPrio;
	}
	ptcb = OSTCBPrioTbl[prio];
	if (ptcb == (OS_TCB *) 0)
	{
		/* Make sure task exist 						*/
		OS_EXIT_CRITICAL();
		return (OS_TASK_NOT_EXIST);
	}
	if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0)
	{
		/* Make sure stack checking option is set   	*/
		OS_EXIT_CRITICAL();
		return (OS_TASK_OPT_ERR);
	}
	free = 0;
	size = ptcb->OSTCBStkSize;
	pchk = ptcb->OSTCBStkBottom;
	OS_EXIT_CRITICAL();
#if OS_STK_GROWTH == 1
	while (*pchk++ == (OS_STK) 0)
	{
		/* Compute the number of zero entries on the stk */
		free++;
	}
#else
	while (*pchk-- == (OS_STK) 0)
	{
		free++;
	}
#endif
	pdata->OSFree = free * sizeof(OS_STK);  		  /* Compute number of free bytes on the stack     */
	pdata->OSUsed = (size - free) * sizeof(OS_STK);   /* Compute number of bytes used on the stack     */
	return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*   										 SUSPEND A TASK
*
* Description: This function is called to suspend a task.  The task can be the calling task if the
*   		   priority passed to OSTaskSuspend() is the priority of the calling task or OS_PRIO_SELF.
*
* Arguments  : prio 	is the priority of the task to suspend.  If you specify OS_PRIO_SELF, the
*   					calling task will suspend itself and rescheduling will occur.
*
* Returns    : OS_NO_ERR				if the requested task is suspended
*   		   OS_TASK_SUSPEND_IDLE 	if you attempted to suspend the idle task which is not allowed.
*   		   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_SUSPEND_PRIO 	if the task to suspend does not exist
*
* Note  	 : You should use this function with great care.  If you suspend a task that is waiting for
*   		   an event (i.e. a message, a semaphore, a queue ...) you will prevent this task from
*   		   running when the event arrives.
*********************************************************************************************************
*/

#if OS_TASK_SUSPEND_EN > 0
INT8U OSTaskSuspend(INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 					 /* Allocate storage for CPU status register		   */
	OS_CPU_SR  cpu_sr;
#endif
	BOOLEAN    self;
	OS_TCB    *ptcb;


#if OS_ARG_CHK_EN > 0
	if (prio == OS_IDLE_PRIO)
	{
		/* Not allowed to suspend idle task    */
		return (OS_TASK_SUSPEND_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 suspend SELF  			   */
		prio = OSTCBCur->OSTCBPrio;
		self = TRUE;
	}
	else if (prio == OSTCBCur->OSTCBPrio)
	{
		/* See if suspending self   		   */
		self = TRUE;
	}
	else
	{
		self = FALSE;   										/* No suspending another task   	   */
	}
	ptcb = OSTCBPrioTbl[prio];
	if (ptcb == (OS_TCB *) 0)
	{
		/* Task to suspend must exist   	   */
		OS_EXIT_CRITICAL();
		return (OS_TASK_SUSPEND_PRIO);
	}
	if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00)
	{
		/* Make task not ready  			   */
		OSRdyGrp &= ~ptcb->OSTCBBitY;
	}
	ptcb->OSTCBStat |= OS_STAT_SUSPEND; 						/* Status of task is 'SUSPENDED'	   */
	OS_EXIT_CRITICAL();
	if (self == TRUE)
	{
		/* Context switch only if SELF  	   */
		OS_Sched();
	}
	return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
*   										 QUERY A TASK
*
* Description: This function is called to obtain a copy of the desired task's TCB.
*
* Arguments  : prio 	is the priority of the task to obtain information from.
*
* Returns    : OS_NO_ERR	   if the requested task is suspended
*   		   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_PRIO_ERR     if the desired task has not been created
*********************************************************************************************************
*/

#if OS_TASK_QUERY_EN > 0
INT8U OSTaskQuery(INT8U prio, OS_TCB *pdata)
{
#if OS_CRITICAL_METHOD == 3 					 /* Allocate storage for CPU status register		   */
	OS_CPU_SR  cpu_sr;
#endif
	OS_TCB    *ptcb;


#if OS_ARG_CHK_EN > 0
	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 suspend SELF  					*/
		prio = OSTCBCur->OSTCBPrio;
	}
	ptcb = OSTCBPrioTbl[prio];
	if (ptcb == (OS_TCB *) 0)
	{
		/* Task to query must exist 				*/
		OS_EXIT_CRITICAL();
		return (OS_PRIO_ERR);
	}
	memcpy(pdata, ptcb, sizeof(OS_TCB));				   /* Copy TCB into user storage area   	   */
	OS_EXIT_CRITICAL();
	return (OS_NO_ERR);
}
#endif

⌨️ 快捷键说明

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