μC/OS-II---信号量管理2(os_sem.c)

目录

  • 信号量管理
    • 信号量获取/无等待
    • 信号量状态查询
    • 信号量计数设置
    • 信号量中断等待
    • 其他
      • 关中断
      • 开中断
      • 关闭内核Task调度
      • 恢复内核Task调度

信号量管理

在这里插入图片描述

信号量获取/无等待

#if OS_SEM_ACCEPT_EN > 0u
INT16U  OSSemAccept (OS_EVENT *pevent)
{
	INT16U     cnt;
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */
	OS_CPU_SR  cpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0u
	
	if (pevent == (OS_EVENT *)0)                      /* Validate 'pevent'                             */
	{
		return (0u);
	}
	
#endif
	
	if (pevent->OSEventType != OS_EVENT_TYPE_SEM)     /* Validate event block type                     */
	{
		return (0u);
	}
	
	OS_ENTER_CRITICAL();
	cnt = pevent->OSEventCnt;
	
	if (cnt > 0u)                                     /* See if resource is available                  */
	{
		pevent->OSEventCnt--;                         /* Yes, decrement semaphore and notify caller    */
	}
	
	OS_EXIT_CRITICAL();
	return (cnt);                                     /* Return semaphore count                        */
}
#endif

信号量状态查询

#if OS_SEM_QUERY_EN > 0u
INT8U  OSSemQuery (OS_EVENT     *pevent,
									 OS_SEM_DATA  *p_sem_data)
{
	INT8U       i;
	OS_PRIO    *psrc;
	OS_PRIO    *pdest;
#if OS_CRITICAL_METHOD == 3u                               /* Allocate storage for CPU status register */
	OS_CPU_SR   cpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0u
	
	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 = 0u; 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 

信号量计数设置

#if OS_SEM_SET_EN > 0u
void  OSSemSet (OS_EVENT  *pevent,
								INT16U     cnt,
								INT8U     *perr)
{
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */
	OS_CPU_SR  cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICAL
	
	if (perr == (INT8U *)0)
	{
		OS_SAFETY_CRITICAL_EXCEPTION();
		return;
	}
	
#endif
#if OS_ARG_CHK_EN > 0u
	
	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 > 0u)                      /* See if semaphore already has a count          */
	{
		pevent->OSEventCnt = cnt;                     /* Yes, set it to the new value specified.       */
	}
	
	else                                              /* No                                            */
	{
		if (pevent->OSEventGrp == 0u)                 /*      See if task(s) waiting?                  */
		{
			pevent->OSEventCnt = cnt;                 /*      No, OK to set the value                  */
		}
		
		else
		{
			*perr              = OS_ERR_TASK_WAITING;
		}
	}
	
	OS_EXIT_CRITICAL();
}
#endif

信号量中断等待

#if OS_SEM_PEND_ABORT_EN > 0u
INT8U  OSSemPendAbort (OS_EVENT  *pevent,
											 INT8U      opt,
											 INT8U     *perr)
{
	INT8U      nbr_tasks;
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */
	OS_CPU_SR  cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICAL
	
	if (perr == (INT8U *)0)
	{
		OS_SAFETY_CRITICAL_EXCEPTION();
		return (0u);
	}
	
#endif
#if OS_ARG_CHK_EN > 0u
	
	if (pevent == (OS_EVENT *)0)                      /* Validate 'pevent'                             */
	{
		*perr = OS_ERR_PEVENT_NULL;
		return (0u);
	}
	
#endif
	
	if (pevent->OSEventType != OS_EVENT_TYPE_SEM)     /* Validate event block type                     */
	{
		*perr = OS_ERR_EVENT_TYPE;
		return (0u);
	}
	
	OS_ENTER_CRITICAL();
	
	if (pevent->OSEventGrp != 0u)                     /* See if any task waiting on semaphore?         */
	{
		nbr_tasks = 0u;
		
		switch (opt)
		{
			case OS_PEND_OPT_BROADCAST:               /* Do we need to abort ALL waiting tasks?        */
				while (pevent->OSEventGrp != 0u)     /* 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:
			default:                                  /* No,  ready HPT       waiting on semaphore     */
				(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 (0u);                                      /* No tasks waiting on semaphore                 */
}
#endif

其他

关中断

开中断

关闭内核Task调度

恢复内核Task调度

你可能感兴趣的:(μC/OS-II学习,c语言)