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

📄 os_sem.c

📁 MCB2300_ucgui_LCD320240.rar LPC2368的uc/gui的移植
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* See if called with scheduler locked ...  	 */
		*perr = OS_ERR_PEND_LOCKED; 				  /* ... can't PEND when locked                    */
		return;
	}
	OS_ENTER_CRITICAL();
	if (pevent->OSEventCnt > 0)
	{
		/* If sem. is positive, resource available ...   */
		pevent->OSEventCnt--;   					  /* ... decrement semaphore only if positive.     */
		OS_EXIT_CRITICAL();
		*perr = OS_ERR_NONE;
		return;
	}
	/* Otherwise, must wait until event occurs  	 */
	OSTCBCur->OSTCBStat |= OS_STAT_SEM; 		  /* Resource not available, pend on semaphore     */
	OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;
	OSTCBCur->OSTCBDly = timeout;   			/* Store pend timeout in TCB					 */
	OS_EventTaskWait(pevent);   					  /* Suspend task until event or timeout occurs    */
	OS_EXIT_CRITICAL();
	OS_Sched(); 									  /* Find next highest priority task ready  	   */
	OS_ENTER_CRITICAL();
	if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK)
	{
		/* See if we timed-out or aborted   			 */
		pend_stat = OSTCBCur->OSTCBStatPend;
		OS_EventTOAbort(pevent);
		OS_EXIT_CRITICAL();
		switch (pend_stat)
		{
			case OS_STAT_PEND_TO:
			default:
				*perr = OS_ERR_TIMEOUT; 			 /* Indicate that didn't get event within TO      */
				break;

			case OS_STAT_PEND_ABORT:
				*perr = OS_ERR_PEND_ABORT;  		 /* Indicate that we aborted					  */
				break;
		}
		return;
	}
	OSTCBCur->OSTCBEventPtr = (OS_EVENT *) 0;
	OS_EXIT_CRITICAL();
	*perr = OS_ERR_NONE;
}

/*$PAGE*/
/*
*********************************************************************************************************
*   								   ABORT WAITING ON A SEMAPHORE
*
* Description: This function aborts & readies any tasks currently waiting on a semaphore.  This function 
*   		   should be used to fault-abort the wait on the semaphore, rather than to normally signal
*   		   the semaphore via OSSemPost().
*
* Arguments  : pevent   	 is a pointer to the event control block associated with the desired
*   						 semaphore.
*
*   		   opt  		 determines the type of ABORT performed:
*   						 OS_PEND_OPT_NONE   	  ABORT wait for a single task (HPT) waiting on the
*   												  semaphore
*   						 OS_PEND_OPT_BROADCAST    ABORT wait for ALL tasks that are  waiting on the
*   												  semaphore
*
*   		   perr 		 is a pointer to where an error message will be deposited.  Possible error
*   						 messages are:
*
*   						 OS_ERR_NONE		 No tasks were     waiting on the semaphore.
*   						 OS_ERR_PEND_ABORT   At least one task waiting on the semaphore was readied
*   											 and informed of the aborted wait; check return value 
*   											 for the number of tasks whose wait on the semaphore 
*   											 was aborted.
*   						 OS_ERR_EVENT_TYPE   If you didn't pass a pointer to a semaphore.
*   						 OS_ERR_PEVENT_NULL  If 'pevent' is a NULL pointer.
*
* Returns    : == 0 		 if no tasks were waiting on the semaphore, or upon error.
*   		   >  0 		 if one or more tasks waiting on the semaphore are now readied and informed.
*********************************************************************************************************
*/

#if OS_SEM_PEND_ABORT_EN > 0
INT8U OSSemPendAbort(OS_EVENT *pevent, INT8U opt, INT8U *perr)
{
	INT8U      nbr_tasks;
#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)
	{
		/* Validate 'pevent'							 */
		*perr = OS_ERR_PEVENT_NULL;
		return (0);
	}
#endif
	if (pevent->OSEventType != OS_EVENT_TYPE_SEM)
	{
		/* Validate event block type					 */
		*perr = OS_ERR_EVENT_TYPE;
		return (0);
	}
	OS_ENTER_CRITICAL();
	if (pevent->OSEventGrp != 0)
	{
		/* See if any task waiting on semaphore?		 */
		nbr_tasks = 0;
		switch (opt)
		{
			case OS_PEND_OPT_BROADCAST:
				/* Do we need to abort ALL waiting tasks?   	 */
				while (pevent->OSEventGrp != 0)
				{
					/* Yes, ready ALL tasks waiting on semaphore	 */
					(void) OS_EventTaskRdy(pevent, (void *) 0, OS_STAT_SEM, OS_STAT_PEND_ABORT);
					nbr_tasks++;
				}
				break;

			case OS_PEND_OPT_NONE:
				/* No,  ready HPT   	waiting on semaphore	 */
			default:
				(void) OS_EventTaskRdy(pevent, (void *) 0, OS_STAT_SEM, OS_STAT_PEND_ABORT);
				nbr_tasks++;
				break;
		}
		OS_EXIT_CRITICAL();
		OS_Sched(); 								  /* Find HPT ready to run  					   */
		*perr = OS_ERR_PEND_ABORT;
		return (nbr_tasks);
	}
	OS_EXIT_CRITICAL();
	*perr = OS_ERR_NONE;
	return (0); 									  /* No tasks waiting on semaphore  			   */
}
#endif

/*$PAGE*/
/*
*********************************************************************************************************
*   									  POST TO A SEMAPHORE
*
* Description: This function signals a semaphore
*
* Arguments  : pevent   	 is a pointer to the event control block associated with the desired
*   						 semaphore.
*
* Returns    : OS_ERR_NONE  	   The call was successful and the semaphore was signaled.
*   		   OS_ERR_SEM_OVF      If the semaphore count exceeded its limit.  In other words, you have
*   							   signalled the semaphore more often than you waited on it with either
*   							   OSSemAccept() or OSSemPend().
*   		   OS_ERR_EVENT_TYPE   If you didn't pass a pointer to a semaphore
*   		   OS_ERR_PEVENT_NULL  If 'pevent' is a NULL pointer.
*********************************************************************************************************
*/

INT8U OSSemPost(OS_EVENT *pevent)
{
#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 (pevent == (OS_EVENT *) 0)
	{
		/* Validate 'pevent'							 */
		return (OS_ERR_PEVENT_NULL);
	}
#endif
	if (pevent->OSEventType != OS_EVENT_TYPE_SEM)
	{
		/* Validate event block type					 */
		return (OS_ERR_EVENT_TYPE);
	}
	OS_ENTER_CRITICAL();
	if (pevent->OSEventGrp != 0)
	{
		/* See if any task waiting for semaphore		 */
		/* Ready HPT waiting on event   				 */
		(void) OS_EventTaskRdy(pevent, (void *) 0, OS_STAT_SEM, OS_STAT_PEND_OK);
		OS_EXIT_CRITICAL();
		OS_Sched(); 								  /* Find HPT ready to run  					   */
		return (OS_ERR_NONE);
	}
	if (pevent->OSEventCnt < 65535u)
	{
		/* Make sure semaphore will not overflow		 */
		pevent->OSEventCnt++;   					  /* Increment semaphore count to register event   */
		OS_EXIT_CRITICAL();
		return (OS_ERR_NONE);
	}
	OS_EXIT_CRITICAL(); 							  /* Semaphore value has reached its maximum	   */
	return (OS_ERR_SEM_OVF);
}

/*$PAGE*/
/*
*********************************************************************************************************
*   									   QUERY A SEMAPHORE
*
* Description: This function obtains information about a semaphore
*
* Arguments  : pevent   	 is a pointer to the event control block associated with the desired
*   						 semaphore
*
*   		   p_sem_data    is a pointer to a structure that will contain information about the
*   						 semaphore.
*
* Returns    : OS_ERR_NONE  	   The call was successful and the message was sent
*   		   OS_ERR_EVENT_TYPE   If you are attempting to obtain data from a non semaphore.
*   		   OS_ERR_PEVENT_NULL  If 'pevent'     is a NULL pointer.
*   		   OS_ERR_PDATA_NULL   If 'p_sem_data' is a NULL pointer
*********************************************************************************************************
*/

#if OS_SEM_QUERY_EN > 0
INT8U OSSemQuery(OS_EVENT *pevent, OS_SEM_DATA *p_sem_data)
{
#if OS_LOWEST_PRIO <= 63
	INT8U     *psrc;
	INT8U     *pdest;
#else
	INT16U    *psrc;
	INT16U    *pdest;
#endif
	INT8U      i;
#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 (pevent == (OS_EVENT *) 0)
	{
		/* Validate 'pevent'						*/
		return (OS_ERR_PEVENT_NULL);
	}
	if (p_sem_data == (OS_SEM_DATA *) 0)
	{
		/* Validate 'p_sem_data'					*/
		return (OS_ERR_PDATA_NULL);
	}
#endif
	if (pevent->OSEventType != OS_EVENT_TYPE_SEM)
	{
		/* Validate event block type				*/
		return (OS_ERR_EVENT_TYPE);
	}
	OS_ENTER_CRITICAL();
	p_sem_data->OSEventGrp = pevent->OSEventGrp;		   /* Copy message mailbox wait list		   */
	psrc = &pevent->OSEventTbl[0];
	pdest = &p_sem_data->OSEventTbl[0];
	for (i = 0; i < OS_EVENT_TBL_SIZE; i++)
	{
		*pdest++ = *psrc++;
	}
	p_sem_data->OSCnt = pevent->OSEventCnt; 			   /* Get semaphore count   				   */
	OS_EXIT_CRITICAL();
	return (OS_ERR_NONE);
}
#endif  												   /* OS_SEM_QUERY_EN   					   */

/*$PAGE*/
/*
*********************************************************************************************************
*   										   SET SEMAPHORE
*
* Description: This function sets the semaphore count to the value specified as an argument.  Typically,
*   		   this value would be 0.
*
*   		   You would typically use this function when a semaphore is used as a signaling mechanism
*   		   and, you want to reset the count value.
*
* Arguments  : pevent     is a pointer to the event control block
*
*   		   cnt  	  is the new value for the semaphore count.  You would pass 0 to reset the
*   					  semaphore count.
*
*   		   perr 	  is a pointer to an error code returned by the function as follows:
*
*   						 OS_ERR_NONE		  The call was successful and the semaphore value was set.
*   						 OS_ERR_EVENT_TYPE    If you didn't pass a pointer to a semaphore.
*   						 OS_ERR_PEVENT_NULL   If 'pevent' is a NULL pointer.
*   						 OS_ERR_TASK_WAITING  If tasks are waiting on the semaphore.
*********************************************************************************************************
*/

#if OS_SEM_SET_EN > 0
void OSSemSet(OS_EVENT *pevent, INT16U cnt, INT8U *perr)
{
#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)
	{
		/* Validate 'pevent'							 */
		*perr = OS_ERR_PEVENT_NULL;
		return;
	}
#endif
	if (pevent->OSEventType != OS_EVENT_TYPE_SEM)
	{
		/* Validate event block type					 */
		*perr = OS_ERR_EVENT_TYPE;
		return;
	}
	OS_ENTER_CRITICAL();
	*perr = OS_ERR_NONE;
	if (pevent->OSEventCnt > 0)
	{
		/* See if semaphore already has a count 		 */
		pevent->OSEventCnt = cnt;   				  /* Yes, set it to the new value specified.	   */
	}
	else
	{
		/* No   										 */
		if (pevent->OSEventGrp == 0)
		{
			/*  	See if task(s) waiting? 				 */
			pevent->OSEventCnt = cnt;   			  /*	  No, OK to set the value   			   */
		}
		else
		{
			*perr = OS_ERR_TASK_WAITING;
		}
	}
	OS_EXIT_CRITICAL();
}
#endif

#endif  											  /* OS_SEM_EN  								   */

⌨️ 快捷键说明

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