UCOS II-信号量源码

1、INT16U OSSemAccept (OS_EVENT *pevent)

宏:OS_SEM_EN > 0u,OS_SEM_ACCEPT_EN > 0u

功能描述:尝试获取信号量。与OSSemPend()不同,如果信号量资源不可用,OSSemAccept()不会挂起调用任务。

参数 pevent:指向事件控制块

返回值:>  0 信号量资源数量(调用此函数之前信号量值)。

              ==0 信号量资源不可用

INT16U OSSemAccept (OS_EVENT *pevent)
{
	INT16U cnt;
#if OS_CRITICAL_METHOD == 3u /* 为CPU状态分配存储 */
	OS_CPU_SR cpu_sr = 0u; /* cpu_sr用于存储CPU状态 */
#endif

#if OS_ARG_CHK_EN > 0u /* 使能参数检查 */
	if (pevent == (OS_EVENT *)0) { /* 'pevent'是否为空指针 */
		return (0u);
	}
#endif
	if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* 'pevent'的事件类型是否为信号量事件*/
		return (0u);
	}
	OS_ENTER_CRITICAL(); /* 进入临界区 */
	cnt = pevent->OSEventCnt;
	if (cnt > 0u) {	/*  信号量资源是否可用 */
		pevent->OSEventCnt--; /* 信号量计数减一 */
	}
	OS_EXIT_CRITICAL();/* 退出临界区 */
	return (cnt); /* 返回信号量计数 */
}

2、OS_EVENT  *OSSemCreate (INT16U cnt)

宏:OS_SEM_EN > 0u

功能描述:创建信号量。

参数 cnt:信号量的初始值。将信号量初始化为非零值,以指定有多少资源可用(例如,如果有10个资源,则将信号量初始化为10)。如果值为0,则没有信号量资源可用。

返回值:!= (void *)0 指向创建的信号量相关联的事件控制块。

              == (void *)0 没有可用的事件控制块

OS_EVENT  *OSSemCreate (INT16U cnt)
{
	OS_EVENT  *pevent;
#if OS_CRITICAL_METHOD == 3u /* 为CPU状态分配存储 */
	OS_CPU_SR  cpu_sr = 0u; /* cpu_sr用于存储CPU状态 */
#endif

#ifdef OS_SAFETY_CRITICAL_IEC61508 /* 用于IEC61508认证 */
    if (OSSafetyCriticalStartFlag == OS_TRUE) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return ((OS_EVENT *)0);
    }
#endif

	if (OSIntNesting > 0u) { /* 是否从ISR中调用 */
		return ((OS_EVENT *)0);	/* 返回空指针 */
	}
	OS_ENTER_CRITICAL(); /* 进入临界区 */
	pevent = OSEventFreeList; /* 获取下一个可用的事件控制块 */
	if (OSEventFreeList != (OS_EVENT *)0) {	/* OSEventFreeList是否为空指针 */
		OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; /* OSEventFreeList指向下一个事件控制块 */
	}
	OS_EXIT_CRITICAL(); /* 退出临界区 */
	if (pevent != (OS_EVENT *)0) { /* pevent是否为空指针 */
		pevent->OSEventType    = OS_EVENT_TYPE_SEM; /* pevent的事件类型设置为信号量事件 */
		pevent->OSEventCnt     = cnt; /* 设置信号量的值 */
		pevent->OSEventPtr     = (void *)0; /*断开与可用事件控制块的链接 */
#if OS_EVENT_NAME_EN > 0u /* 使能事件命名功能 */
		pevent->OSEventName    = (INT8U *)(void *)"?"; /* 将事件名初始化为‘?’ */
#endif
		OS_EventWaitListInit(pevent); /* 初始化事件控制块的OSEventGrp,OSEventTbl[]变量 */
	}
	return (pevent);
}

3、OS_EVENT  *OSSemDel (OS_EVENT  *pevent, INT8U opt,INT8U *perr)

宏:OS_SEM_EN > 0u,OS_SEM_DEL_EN> 0u

功能描述:该函数删除一个信号量并就绪该信号量上所有挂起的任务。

参数 pevent:指向与所需信号量关联的事件控制块的指针。

        opt:删除选项

                 opt == OS_DEL_NO_PEND 只有在没有任务挂起时才删除信号量

                 opt == OS_DEL_ALWAYS 即使有任务正在等待,也会删除信号量。在这种情况下,所有未完成的任务都将就绪。

       perr:是指向错误码的指针,该错误码可以包含以下值之一:

                OS_ERR_NONE                   调用成功,信号量被删除
                OS_ERR_DEL_ISR              试图从ISR中删除信号量
                OS_ERR_INVALID_OPT      无效的opt选项
                OS_ERR_TASK_WAITING   一个或多个任务正在等待信号量
                OS_ERR_EVENT_TYPE      未传递一个指向信号量的指针
                OS_ERR_PEVENT_NULL    'pevent'是空指针.

返回值:pevent   若成功删除信号量,则返回(OS_EVENT *)0

注:1、此函数必须小心使用。通常期望信号量存在的任务必须检查OSSemPend()的返回值。

       2、除非检查“pevent”是否为空指针,否则OSSemAccept()调用者将不知道预期的信号量已被删除。

       3、该调用可能会在很长一段时间内禁用中断。中断禁用时间与等待信号量的任务数量成正比。

       4、因为信号量上所有挂起的任务都将被就绪,所以在使用信号量进行互斥的应用程序中必须小心,因为信号量将不再保护资源。

       5、如果OSSemDel()被OS_DEL_ALWAYS调用,那么等待信号量的所有任务都将被就绪并返回一个OS_ERR_PEND_ABORT

OS_EVENT  *OSSemDel (OS_EVENT  *pevent,
						INT8U      opt,
						INT8U     *perr)
{
	BOOLEAN    tasks_waiting; /* 是否有任务在等待此信号量的标志 */
    OS_EVENT  *pevent_return;
#if OS_CRITICAL_METHOD == 3u /* 为CPU状态分配存储 */
	OS_CPU_SR  cpu_sr = 0u; /* cpu_sr用于存储CPU状态 */
#endif



#ifdef OS_SAFETY_CRITICAL /* 用于认证 */
    if (perr == (INT8U *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return ((OS_EVENT *)0);
    }
#endif

#if OS_ARG_CHK_EN > 0u /* 使能参数检查 */
	if (pevent == (OS_EVENT *)0) { /* 'pevent'是否为空指针 */
		*perr = OS_ERR_PEVENT_NULL; /* 将perr赋值为OS_ERR_PEVENT_NULL */
		return (pevent);
	}
#endif
	if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* 事件类型是否为信号量事件 */
		*perr = OS_ERR_EVENT_TYPE; /* 将perr赋值为OS_ERR_EVENT_TYPE */
		return (pevent);
	}
	if (OSIntNesting > 0u) { /* 是否从ISR中调用 */
		*perr = OS_ERR_DEL_ISR;	/* 将perr赋值为OS_ERR_PEVENT_NULL */							
		return (pevent);
	}
	OS_ENTER_CRITICAL(); /* 进入临界区 */
	if (pevent->OSEventGrp != 0u) { /* 是否有任务在等待此信号量 */
		tasks_waiting = OS_TRUE; /* 是*/
	} else {
		tasks_waiting = OS_FALSE; /* 否 */
	}
	switch (opt) {
		case OS_DEL_NO_PEND: /* 只有在没有任务挂起时才删除信号量 */
			if (tasks_waiting == OS_FALSE) { /* 没有任务在等待此信号量 */
#if OS_EVENT_NAME_EN > 0u /* 使能事件命名功能 */
				pevent->OSEventName    = (INT8U *)(void *)"?"; /* 将事件名设置为‘?’ */
#endif
				pevent->OSEventType    = OS_EVENT_TYPE_UNUSED; /* 将事件类型设置为未使用 */
				pevent->OSEventPtr     = OSEventFreeList; /* 将事件控制块链接到可用事件控制链表 */
				pevent->OSEventCnt     = 0u; /* 将信号量数量设置为0 */
				OSEventFreeList        = pevent; /* 获取下一个可用的事件控制块 */
				OS_EXIT_CRITICAL(); /* 退出临界区 */
				*perr                  = OS_ERR_NONE; /* 将perr赋值为OS_ERR_NONE*/	
				pevent_return          = (OS_EVENT *)0; /* 信号量已被删除 */
			} else { /* 有任务在等待此信号量 */
				OS_EXIT_CRITICAL(); /* 退出临界区 */
				*perr                  = OS_ERR_TASK_WAITING; /* 将perr赋值为OS_ERR_TASK_WAITING */
				pevent_return          = pevent; /* 信号量未删除 */
			}
			break;

		case OS_DEL_ALWAYS:	/* 即使有任务正在等待,也会删除信号量 */
			while (pevent->OSEventGrp != 0u) {/* 就绪所有等待此信号量的任务 */
                 (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT);/
			}
#if OS_EVENT_NAME_EN > 0u /* 使能事件命名功能 */
			pevent->OSEventName    = (INT8U *)(void *)"?"; /* 将事件名设置为‘?’ */
#endif
			pevent->OSEventType    = OS_EVENT_TYPE_UNUSED; /* 将事件类型设置为未使用 */
			pevent->OSEventPtr     = OSEventFreeList; /* 将事件控制块链接到可用事件控制链表 */
			pevent->OSEventCnt     = 0u; /* 信号量已被删除 */
			OSEventFreeList        = pevent; /* 获取下一个可用的事件控制块 */
			OS_EXIT_CRITICAL(); /* 退出临界区 */
			if (tasks_waiting == OS_TRUE) { /* 如果有任务在等待信号量,需重新调度 */
				OS_Sched(); /* 查找运行就绪的最高优先级任务 */
			}
			*perr                  = OS_ERR_NONE; /* 将perr赋值为OS_ERR_NONE */
			pevent_return          = (OS_EVENT *)0;	/* 信号量已被删除 */
			break;

		default:
			OS_EXIT_CRITICAL(); /* 退出临界区 */
			*perr                  = OS_ERR_INVALID_OPT; /* 将perr赋值为OS_ERR_INVALID_OPT*/
			pevent_return          = pevent; /* 信号量未删除 */
			break;
	}
	return (pevent_return);
}

4、void  OSSemPend (OS_EVENT  *pevent, INT32U     timeout,INT8U     *perr)

宏:OS_SEM_EN > 0u,OS_SEM_DEL_EN> 0u

功能描述:等待信号量。

参数 pevent:指向与所需信号量关联的事件控制块的指针。

        timeout:一个可选的超时时间(单位以时钟滴答)。如果非零,则任务将等待信号量资源直到此参数指定的时间量为止。但是,如果为0,那么任务将永远在指定的信号量处等待,直到信号量资源变得可用。

       perr:指向将存放错误消息的指针。可能的错误信息有:

                    OS_ERR_NONE        调用成功,任务拥有了信号量资源,或者,正在等待的事件发生了。
                    OS_ERR_TIMEOUT  在指定的“超时时间”内没有接收到信号量信号量。
                    OS_ERR_PEND_ABORT   对信号量的等待被终止。
                    OS_ERR_EVENT_TYPE   未传递一个指向信号量的指针。
                    OS_ERR_PEND_ISR    从ISR中调用.
                    OS_ERR_PEVENT_NULL  'pevent'是空指针.
                    OS_ERR_PEND_LOCKED  在锁定调度程序时调用此函数

void  OSSemPend (OS_EVENT  *pevent,
					INT32U     timeout,
					INT8U     *perr)
{
#if OS_CRITICAL_METHOD == 3u /* 为CPU状态分配存储 */
	OS_CPU_SR  cpu_sr = 0u; /* cpu_sr用于存储CPU状态 */
#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) { /* 'pevent'为空指针 */
		*perr = OS_ERR_PEVENT_NULL; /* 将perr赋值为OS_ERR_PEVENT_NULL */
		return;
 	}
#endif
	if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* pevent事件类型是否为信号量事件 */
		*perr = OS_ERR_EVENT_TYPE;  /* 将perr赋值为OS_ERR_EVENT_TYPE */
		return;
	}
	if (OSIntNesting > 0u) { /* 是否从ISR中调用 */
		*perr = OS_ERR_PEND_ISR; /* 将perr赋值为OS_ERR_PEND_ISR*/
		return;
	}
	if (OSLockNesting > 0u) { /* 是否在调度器锁定时调用 */
		*perr = OS_ERR_PEND_LOCKED; /* 将perr赋值为OS_ERR_EVENT_TYPE */
		return;
	}
	OS_ENTER_CRITICAL(); /* 进入临界区 */
	if (pevent->OSEventCnt > 0u) { /*如果信号量计数为正,说明有可用的信号量资源 */
		pevent->OSEventCnt--; /* 信号量减一 */
		OS_EXIT_CRITICAL(); /* 退出临界区 */
		*perr = OS_ERR_NONE; /* 将perr赋值为OS_ERR_NONE */
		return;
	}
	/* 否则,必须等到事件发生 */
	OSTCBCur->OSTCBStat     |= OS_STAT_SEM;			/* Resource not available, pend on semaphore */
	OSTCBCur->OSTCBStatPend  = OS_STAT_PEND_OK;
	OSTCBCur->OSTCBDly       = timeout; /* 在TCB中存储挂起超时时间 */
	OS_EventTaskWait(pevent); /* 挂起任务,直到事件或超时发生    */
	OS_EXIT_CRITICAL(); /* 退出临界区 */
	OS_Sched();	/* 任务调度 */
	OS_ENTER_CRITICAL();  /* 进入临界区 */
	switch (OSTCBCur->OSTCBStatPend) { /* 超时或终止 */ 
		case OS_STAT_PEND_OK: /* 获取到信号量 */
			*perr = OS_ERR_NONE;/* 将perr赋值为OS_ERR_NONE*/
			break;

		case OS_STAT_PEND_ABORT: /* 终止 */
			*perr = OS_ERR_PEND_ABORT; /* 将perr赋值为OS_ERR_PEND_ABORT */
			break;

		case OS_STAT_PEND_TO: /* 超时 */
		default:
			OS_EventTaskRemove(OSTCBCur, pevent);
			*perr = OS_ERR_TIMEOUT;  /* 将perr赋值为OS_ERR_TIMEOUT */
			break;
	}
	OSTCBCur->OSTCBStat          =  OS_STAT_RDY; /* 设置当前TCB的任务状态为就绪 */
	OSTCBCur->OSTCBStatPend      =  OS_STAT_PEND_OK;  /* 清除当前TCB的挂起状态 */                      
	OSTCBCur->OSTCBEventPtr      = (OS_EVENT  *)0;    /* 清除事件指针 */                         
#if (OS_EVENT_MULTI_EN > 0u)
	OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0;
#endif
	OS_EXIT_CRITICAL(); /* 退出临界区 */
}

5、INT8U  OSSemPendAbort (OS_EVENT  *pevent,INT8U      opt,INT8U     *perr)

宏:OS_SEM_EN > 0u,OS_SEM_PEND_ABORT_EN> 0u

功能描述:此函数将中止并就绪正在等待信号量的任意任务。该函数应用于故障中止对信号量的等待,而不是通常通过OSSemPost()来对信号量发出信号。

参数 pevent:指向与所需信号量关联的事件控制块的指针。

        opt:决定执行终止的类型

                OS_PEND_OPT_NONE  中止等待最高优先级任务对信号量的等待                    
                OS_PEND_OPT_BROADCAST  中止等待正在等待信号量的所有任务

      perr:指向将消息的指针。可能的错误信息有:

               OS_ERR_NONE    信号量上没有任务等待.
               OS_ERR_PEND_ABORT   至少有一个等待信号量的任务已经就绪,并被告知等待失败;检查对信号量的等待被中止的任务数量的返回值。
              OS_ERR_EVENT_TYPE   未传递一个指向信号量的指针。
              OS_ERR_PEVENT_NULL  'pevent'是空指针。

返回值:== 0  如果信号量上没有任务等待,或者出现错误。

             >  0    如果等待信号量的一个或多个任务现在已经就绪并得到通知

INT8U  OSSemPendAbort (OS_EVENT  *pevent,
							INT8U      opt,
							INT8U     *perr)
{
	INT8U nbr_tasks; /* 终止的任务数量 */
#if OS_CRITICAL_METHOD == 3u /* 为CPU状态分配存储 */
	OS_CPU_SR  cpu_sr = 0u; /* cpu_sr用于存储CPU状态 */
#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) { /* 'pevent'为空指针 */
		*perr = OS_ERR_PEVENT_NULL; /* 将perr赋值为OS_ERR_PEVENT_NULL */
		return (0u);
	}
#endif
	if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {	/* pevent事件是否为信号量事件 */
		*perr = OS_ERR_EVENT_TYPE; /* 将perr赋值为OS_ERR_EVENT_TYPE */
		return (0u);
	}
	OS_ENTER_CRITICAL(); /* 进入临界区 */
	if (pevent->OSEventGrp != 0u) { /* 是否有任务在等待信号量 */
		nbr_tasks = 0u;
		switch (opt) {
			case OS_PEND_OPT_BROADCAST: /* 终止所有等待的任务 */
				while (pevent->OSEventGrp != 0u) { /* 就绪等待信号量的所有任务 */
					(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT); /* 就绪等待信号量的最高优先级任务 */
					nbr_tasks++; /* 终止的任务数量加一 */
				}
				break;

			case OS_PEND_OPT_NONE:
			default: /* 就绪等待信号量的最高优先级任务 */
				(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT);
				nbr_tasks++;
				break;
		}
		OS_EXIT_CRITICAL(); /* 退出临界区 */
		OS_Sched();  /* 任务调度 */
		*perr = OS_ERR_PEND_ABORT; /* 将perr赋值为OS_ERR_PEND_ABORT */
		return (nbr_tasks); /* 返回终止的任务数量 */
	}
	OS_EXIT_CRITICAL(); /* 退出临界区 */
	*perr = OS_ERR_NONE; /* 将perr赋值为OS_ERR_NONE */
	return (0u); /* 没有任务在等待信号量 */
}

6、INT8U  OSSemPost (OS_EVENT *pevent)

宏:OS_SEM_EN > 0u

功能描述:释放信号量。

参数 pevent:指向与所需信号量关联的事件控制块的指针。

返回值:

     OS_ERR_NONE       调用成功,释放信号量
     OS_ERR_SEM_OVF 如果信号量计数超过其限制。换句话说,与使用OSSemAccept()或OSSemPend()等待的信号量相比,发出信号的频率更高。
     OS_ERR_EVENT_TYPE   未传递一个指向信号量的指针
     OS_ERR_PEVENT_NULL   'pevent'是空指针.

INT8U  OSSemPost (OS_EVENT *pevent)
{
#if OS_CRITICAL_METHOD == 3u /* 为CPU状态分配存储 */
	OS_CPU_SR  cpu_sr = 0u; /* cpu_sr用于存储CPU状态 */
#endif

#if OS_ARG_CHK_EN > 0u /* 是否使能了参数检查 */
	if (pevent == (OS_EVENT *)0) { /* 'pevent'是否为空指针 */
		return (OS_ERR_PEVENT_NULL);
	}
#endif
	if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {	/* pevent事件是否为信号量事件 */
		return (OS_ERR_EVENT_TYPE);
	}
	OS_ENTER_CRITICAL(); /* 进入临界区 */
	if (pevent->OSEventGrp != 0u) {	/* 是否有任务在等待此信号量 */
		/* 就绪等待事件的最高优先级的任务 */
		(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK);
		OS_EXIT_CRITICAL(); /* 退出临界区 */
		OS_Sched();	/* 任务调度 */
		return (OS_ERR_NONE);
	}
	if (pevent->OSEventCnt < 65535u) { /* 确保信号量不会溢出 */
		pevent->OSEventCnt++; /* 注册事件的信号量计数器加一 */
		OS_EXIT_CRITICAL(); /* 退出临界区 */
		return (OS_ERR_NONE);
	}
	OS_EXIT_CRITICAL(); /* 退出临界区 */
	return (OS_ERR_SEM_OVF);
}

7、OSSemQuery (OS_EVENT     *pevent, OS_SEM_DATA  *p_sem_data)

宏:OS_SEM_EN > 0u,OS_SEM_QUERY_EN>0u

功能描述:获得关于信号量的信息。

参数 pevent:指向与所需信号量关联的事件控制块的指针。

        p_sem_data:是指向包含有关信号量信息的指针。

返回值:

    OS_ERR_NONE       调用成功,
    OS_ERR_EVENT_TYPE   试图从获取非信号量的数据。
    OS_ERR_PEVENT_NULL  'pevent' 是空指针。
    OS_ERR_PDATA_NULL    'p_sem_data'是空指针。

INT8U  OSSemQuery (OS_EVENT     *pevent,
						OS_SEM_DATA  *p_sem_data)
{
	INT8U       i;
	OS_PRIO    *psrc;
	OS_PRIO    *pdest;
#if OS_CRITICAL_METHOD == 3u /* 为CPU状态分配存储 */
	OS_CPU_SR   cpu_sr = 0u; /* cpu_sr用于存储CPU状态 */
#endif

#if OS_ARG_CHK_EN > 0u /* 是否使能了参数检查功能 */
	if (pevent == (OS_EVENT *)0) { /* 'pevent'是否为空指针 */
		return (OS_ERR_PEVENT_NULL);
	}
	if (p_sem_data == (OS_SEM_DATA *)0) {/* 'p_sem_data'是否为空指针 */
		return (OS_ERR_PDATA_NULL);
	}
#endif
	if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {	/* pevent事件类型是否为信号量事件 */
		return (OS_ERR_EVENT_TYPE);
	}
	OS_ENTER_CRITICAL(); /* 进入临界区 */

    /* 拷贝信号量等待列表 */
	p_sem_data->OSEventGrp = pevent->OSEventGrp; 
	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;	/* 获取信号量计数 */
	OS_EXIT_CRITICAL(); /* 退出临界区 */
	return (OS_ERR_NONE);
}

8、void  OSSemSet (OS_EVENT  *pevent,INT16U  cnt,INT8U     *perr)

宏:OS_SEM_EN > 0u,OS_SEM_SET_EN>0u

功能描述:此函数将信号量计数设置为作为参数指定的值。通常,这个值是0。当信号量用作信号机制并希望重置计数值时,通常会使用此函数。

参数 pevent:指向与所需信号量关联的事件控制块的指针。

        cnt: 信号量计数的新值。可以传递0来重置信号量计数。

        perr:函数返回的错误码的指针,如下所示:

              OS_ERR_NONE    调用成功,并设置了信号量值。
              OS_ERR_EVENT_TYPE   未传递一个指向信号量的指针。
              OS_ERR_PEVENT_NULL   'pevent' 为空指针。
              OS_ERR_TASK_WAITING  如果任务正在等待信号量。

void  OSSemSet (OS_EVENT  *pevent,
					INT16U     cnt,
					INT8U     *perr)
{
#if OS_CRITICAL_METHOD == 3u /* 为CPU状态分配存储 */
	OS_CPU_SR  cpu_sr = 0u; /* cpu_sr用于存储CPU状态 */
#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) { /* 'pevent'是否为空指针 */
		*perr = OS_ERR_PEVENT_NULL; /* 将perr赋值为OS_ERR_PEVENT_NULL */
		return;
	}
#endif
	if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* pevent事件类型是否为信号量事件 */
		*perr = OS_ERR_EVENT_TYPE; /* 将perr赋值为OS_ERR_EVENT_TYPE */
		return;
	}
	OS_ENTER_CRITICAL(); /* 进入临界区 */
	*perr = OS_ERR_NONE;
	if (pevent->OSEventCnt > 0u) { /* 信号量值是否大于0 */
		pevent->OSEventCnt = cnt; /* 设置为指定的值 */
	} else {										
		if (pevent->OSEventGrp == 0u) {	/* 是否有任务在等待信号量 */
			pevent->OSEventCnt = cnt; /* 没有任务在等待信号量 ,设置为指定的值*/
		} else {
			*perr = OS_ERR_TASK_WAITING; /* 将perr赋值为OS_ERR_TASK_WAITING */
		}
	}
	OS_EXIT_CRITICAL(); /* 退出临界区 */
}

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
\SOFTWARE The main directory from the root where all software-related files are placed. \SOFTWARE\BLOCKS The main directory where all ‘Building Blocks’ are located. With μC/OS-II, I included a ‘building block’ that handles DOS-type compatible functions that are used by the example code. \SOFTWARE\BLOCKS\TO This directory contains the files for the TO utility (see Appendix E, TO). The source file is TO.C and is found in the \SOFTWARE\TO\SOURCE directory. The DOS executable file (TO.EXE) is found in the \SOFTWARE\TO\EXE directory. Note that TO requires a file called TO.TBL which must reside on your root directory. An example of TO.TBL is also found in the \SOFTWARE\TO\EXE directory. You will need to move TO.TBL to the root directory if you are to use TO.EXE. \SOFTWARE\uCOS-II The main directory where all μC/OS-II files are located. \SOFTWARE\uCOS-II\EX1_x86L This directory contains the source code for EXAMPLE #1 (see section 1.07, Example #1) which is intended to run under DOS (or a DOS window under Windows 95). \SOFTWARE\uCOS-II\EX2_x86L This directory contains the source code for EXAMPLE #2 (see section 1.08, Example #2) which is intended to run under DOS (or a DOS window under Windows 95). \SOFTWARE\uCOS-II\EX3_x86L This directory contains the source code for EXAMPLE #3 (see section 1.09, Example #3) which is intended to run under DOS (or a DOS window under Windows 95). \SOFTWARE\uCOS-II\Ix86L This directory contains the source code for the processor dependent code (a.k.a. the port) of μC/OS-II for an 80x86 Real-Mode, Large Model processor. \SOFTWARE\uCOS-II\SOURCE This directory contains the source code for processor independent portion of μC/OS-II. This code is fully portable to other processor architectures.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值