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

📄 os_flag.c

📁 lpc2368-keil环境下的ucos的移植例程
💻 C
📖 第 1 页 / 共 3 页
字号:
			*err = OS_FLAG_INVALID_OPT;
			return ((OS_FLAGS) 0);
	}
	sched = FALSE;  								 /* Indicate that we don't need rescheduling       */
	pnode = (OS_FLAG_NODE *) pgrp->OSFlagWaitList;
	while (pnode != (OS_FLAG_NODE *) 0)
	{
		/* Go through all tasks waiting on event flag(s)  */
		switch (pnode->OSFlagNodeWaitType)
		{
			case OS_FLAG_WAIT_SET_ALL:
				/* See if all req. flags are set for current node */
				flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
				if (flags_rdy == pnode->OSFlagNodeFlags)
				{
					if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE)
					{
						/* Make task RTR, event(s) Rx'd   */
						sched = TRUE;   							/* When done we will reschedule   */
					}
				}
				break;

			case OS_FLAG_WAIT_SET_ANY:
				/* See if any flag set  						  */
				flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
				if (flags_rdy != (OS_FLAGS) 0)
				{
					if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE)
					{
						/* Make task RTR, event(s) Rx'd   */
						sched = TRUE;   							/* When done we will reschedule   */
					}
				}
				break;

#if OS_FLAG_WAIT_CLR_EN > 0
			case OS_FLAG_WAIT_CLR_ALL:
				/* See if all req. flags are set for current node */
				flags_rdy = ~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
				if (flags_rdy == pnode->OSFlagNodeFlags)
				{
					if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE)
					{
						/* Make task RTR, event(s) Rx'd   */
						sched = TRUE;   							/* When done we will reschedule   */
					}
				}
				break;

			case OS_FLAG_WAIT_CLR_ANY:
				/* See if any flag set  						  */
				flags_rdy = ~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
				if (flags_rdy != (OS_FLAGS) 0)
				{
					if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE)
					{
						/* Make task RTR, event(s) Rx'd   */
						sched = TRUE;   							/* When done we will reschedule   */
					}
				}
				break;
#endif
		}
		pnode = (OS_FLAG_NODE *) pnode->OSFlagNodeNext; /* Point to next task waiting for event flag(s) */
	}
	OS_EXIT_CRITICAL();
	if (sched == TRUE)
	{
		OS_Sched();
	}
	OS_ENTER_CRITICAL();
	flags_cur = pgrp->OSFlagFlags;
	OS_EXIT_CRITICAL();
	*err = OS_NO_ERR;
	return (flags_cur);
}
/*$PAGE*/
/*
*********************************************************************************************************
*   										QUERY EVENT FLAG
*
* Description: This function is used to check the value of the event flag group.
*
* Arguments  : pgrp 		is a pointer to the desired event flag group.
*
*   		   err  		 is a pointer to an error code returned to the called:
*   						 OS_NO_ERR  			The call was successfull
*   						 OS_FLAG_INVALID_PGRP   You passed a NULL pointer
*   						 OS_ERR_EVENT_TYPE  	You are not pointing to an event flag group
*
* Returns    : The current value of the event flag group.
*
* Called From: Task or ISR
*********************************************************************************************************
*/

#if OS_FLAG_QUERY_EN > 0
OS_FLAGS OSFlagQuery(OS_FLAG_GRP *pgrp, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3 					  /* Allocate storage for CPU status register   	   */
	OS_CPU_SR  cpu_sr;
#endif
	OS_FLAGS   flags;


#if OS_ARG_CHK_EN > 0
	if (pgrp == (OS_FLAG_GRP *) 0)
	{
		/* Validate 'pgrp'  								 */
		*err = OS_FLAG_INVALID_PGRP;
		return ((OS_FLAGS) 0);
	}
	if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG)
	{
		/* Validate event block type						 */
		*err = OS_ERR_EVENT_TYPE;
		return ((OS_FLAGS) 0);
	}
#endif
	OS_ENTER_CRITICAL();
	flags = pgrp->OSFlagFlags;
	OS_EXIT_CRITICAL();
	*err = OS_NO_ERR;
	return (flags); 							  /* Return the current value of the event flags	   */
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*   					  SUSPEND TASK UNTIL EVENT FLAG(s) RECEIVED OR TIMEOUT OCCURS
*
* Description: This function is internal to uC/OS-II and is used to put a task to sleep until the desired
*   		   event flag bit(s) are set.
*
* Arguments  : pgrp 		 is a pointer to the desired event flag group.
*
*   		   pnode		 is a pointer to a structure which contains data about the task waiting for
*   						 event flag bit(s) to be set.
*
*   		   flags		 Is a bit pattern indicating which bit(s) (i.e. flags) you wish to check.
*   						 The bits you want are specified by setting the corresponding bits in
*   						 'flags'.  e.g. if your application wants to wait for bits 0 and 1 then
*   						 'flags' would contain 0x03.
*
*   		   wait_type	 specifies whether you want ALL bits to be set/cleared or ANY of the bits
*   						 to be set/cleared.
*   						 You can specify the following argument:
*
*   						 OS_FLAG_WAIT_CLR_ALL   You will check ALL bits in 'mask' to be clear (0)
*   						 OS_FLAG_WAIT_CLR_ANY   You will check ANY bit  in 'mask' to be clear (0)
*   						 OS_FLAG_WAIT_SET_ALL   You will check ALL bits in 'mask' to be set   (1)
*   						 OS_FLAG_WAIT_SET_ANY   You will check ANY bit  in 'mask' to be set   (1)
*
*   		   timeout  	 is the desired amount of time that the task will wait for the event flag
*   						 bit(s) to be set.
*
* Returns    : none
*
* Called by  : OSFlagPend()  OS_FLAG.C
*
* Note(s)    : This function is INTERNAL to uC/OS-II and your application should not call it.
*********************************************************************************************************
*/

static  void OS_FlagBlock(OS_FLAG_GRP *pgrp, OS_FLAG_NODE *pnode, OS_FLAGS flags, INT8U wait_type, INT16U timeout)
{
	OS_FLAG_NODE  *pnode_next;


	OSTCBCur->OSTCBStat |= OS_STAT_FLAG;
	OSTCBCur->OSTCBDly = timeout;   		   /* Store timeout in task's TCB                   */
#if OS_TASK_DEL_EN > 0
	OSTCBCur->OSTCBFlagNode = pnode;				/* TCB to link to node  						 */
#endif
	pnode->OSFlagNodeFlags = flags; 			   /* Save the flags that we need to wait for   	*/
	pnode->OSFlagNodeWaitType = wait_type;  		  /* Save the type of wait we are doing 		   */
	pnode->OSFlagNodeTCB = (void *) OSTCBCur;     /* Link to task's TCB                            */
	pnode->OSFlagNodeNext = pgrp->OSFlagWaitList; /* Add node at beginning of event flag wait list */
	pnode->OSFlagNodePrev = (void *) 0;
	pnode->OSFlagNodeFlagGrp = (void *) pgrp;   	  /* Link to Event Flag Group   				   */
	pnode_next = (OS_FLAG_NODE *) pgrp->OSFlagWaitList;
	if (pnode_next != (void *) 0)
	{
		/* Is this the first NODE to insert?			 */
		pnode_next->OSFlagNodePrev = pnode; 		  /* No, link in doubly linked list 			   */
	}
	pgrp->OSFlagWaitList = (void *) pnode;
	/* Suspend current task until flag(s) received   */
	if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0)
	{
		OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
	}
}

/*$PAGE*/
/*
*********************************************************************************************************
*   								 INITIALIZE THE EVENT FLAG MODULE
*
* Description: This function is called by uC/OS-II to initialize the event flag module.  Your application
*   		   MUST NOT call this function.  In other words, this function is internal to uC/OS-II.
*
* Arguments  : none
*
* Returns    : none
*
* WARNING    : You MUST NOT call this function from your code.  This is an INTERNAL function to uC/OS-II.
*********************************************************************************************************
*/

void OS_FlagInit(void)
{
#if OS_MAX_FLAGS == 1
	OSFlagFreeList = (OS_FLAG_GRP *) &OSFlagTbl[0];  /* Only ONE event flag group!  	*/
	OSFlagFreeList->OSFlagType = OS_EVENT_TYPE_UNUSED;
	OSFlagFreeList->OSFlagWaitList = (void *) 0;
#endif

#if OS_MAX_FLAGS >= 2
	INT8U   	 i;
	OS_FLAG_GRP *pgrp1;
	OS_FLAG_GRP *pgrp2;


	pgrp1 = &OSFlagTbl[0];
	pgrp2 = &OSFlagTbl[1];
	for (i = 0; i < (OS_MAX_FLAGS - 1); i++)
	{
		/* Init. list of free EVENT FLAGS  */
		pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED;
		pgrp1->OSFlagWaitList = (void *) pgrp2;
		pgrp1++;
		pgrp2++;
	}
	pgrp1->OSFlagWaitList = (void *) 0;
	OSFlagFreeList = (OS_FLAG_GRP *) &OSFlagTbl[0];
#endif
}

/*$PAGE*/
/*
*********************************************************************************************************
*   						   MAKE TASK READY-TO-RUN, EVENT(s) OCCURRED
*
* Description: This function is internal to uC/OS-II and is used to make a task ready-to-run because the
*   		   desired event flag bits have been set.
*
* Arguments  : pnode		 is a pointer to a structure which contains data about the task waiting for
*   						 event flag bit(s) to be set.
*
*   		   flags_rdy	 contains the bit pattern of the event flags that cause the task to become
*   						 ready-to-run.
*
* Returns    : none
*
* Called by  : OSFlagsPost() OS_FLAG.C
*
* Note(s)    : 1) This function assumes that interrupts are disabled.
*   		   2) This function is INTERNAL to uC/OS-II and your application should not call it.
*********************************************************************************************************
*/

static  BOOLEAN OS_FlagTaskRdy(OS_FLAG_NODE *pnode, OS_FLAGS flags_rdy)
{
	OS_TCB   *ptcb;
	BOOLEAN   sched;


	ptcb = (OS_TCB *) pnode->OSFlagNodeTCB;  /* Point to TCB of waiting task			 */
	ptcb->OSTCBDly = 0;
	ptcb->OSTCBFlagsRdy = flags_rdy;
	ptcb->OSTCBStat &= ~OS_STAT_FLAG;
	if (ptcb->OSTCBStat == OS_STAT_RDY)
	{
		/* Put task into ready list 				*/
		OSRdyGrp |= ptcb->OSTCBBitY;
		OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
		sched = TRUE;
	}
	else
	{
		sched = FALSE;
	}
	OS_FlagUnlink(pnode);
	return (sched);
}

/*$PAGE*/
/*
*********************************************************************************************************
*   							   UNLINK EVENT FLAG NODE FROM WAITING LIST
*
* Description: This function is internal to uC/OS-II and is used to unlink an event flag node from a
*   		   list of tasks waiting for the event flag.
*
* Arguments  : pnode		 is a pointer to a structure which contains data about the task waiting for
*   						 event flag bit(s) to be set.
*
* Returns    : none
*
* Called by  : OS_FlagTaskRdy() OS_FLAG.C
*   		   OSFlagPend() 	OS_FLAG.C
*   		   OSTaskDel()  	OS_TASK.C
*
* Note(s)    : 1) This function assumes that interrupts are disabled.
*   		   2) This function is INTERNAL to uC/OS-II and your application should not call it.
*********************************************************************************************************
*/

void OS_FlagUnlink(OS_FLAG_NODE *pnode)
{
#if OS_TASK_DEL_EN > 0
	OS_TCB  	 *ptcb;
#endif
	OS_FLAG_GRP  *pgrp;
	OS_FLAG_NODE *pnode_prev;
	OS_FLAG_NODE *pnode_next;


	pnode_prev = (OS_FLAG_NODE *) pnode->OSFlagNodePrev;
	pnode_next = (OS_FLAG_NODE *) pnode->OSFlagNodeNext;
	if (pnode_prev == (OS_FLAG_NODE *) 0)
	{
		/* Is it first node in wait list?      */
		pgrp = (OS_FLAG_GRP *) pnode->OSFlagNodeFlagGrp;
		pgrp->OSFlagWaitList = (void *) pnode_next; 			 /* 	 Update list for new 1st node   */
		if (pnode_next != (OS_FLAG_NODE *) 0)
		{
			pnode_next->OSFlagNodePrev = (OS_FLAG_NODE *) 0;	 /* 	 Link new 1st node PREV to NULL */
		}
	}
	else
	{
		/* No,  A node somewhere in the list   */
		pnode_prev->OSFlagNodeNext = pnode_next;				/*  	Link around the node to unlink */
		if (pnode_next != (OS_FLAG_NODE *) 0)
		{
			/*  	Was this the LAST node? 	   */
			pnode_next->OSFlagNodePrev = pnode_prev;			/*  	No, Link around current node   */
		}
	}
#if OS_TASK_DEL_EN > 0
	ptcb = (OS_TCB *) pnode->OSFlagNodeTCB;
	ptcb->OSTCBFlagNode = (OS_FLAG_NODE *) 0;
#endif
}
#endif

⌨️ 快捷键说明

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