ucos-ii 2.52信号量的小结
这里结合任哲的书籍+源代码来分析信号量
1、在任哲的书中,提到信号量只有普通的信号量,没有区分freertos所谓的二值信号量和计数信号量。可以看看源代码,ucos的代码风格是很不错的,个人认为这个风格比freertos好,看起来很舒服,不像freertos一大堆宏定义。
可以看到,OSSemCreate函数中的cnt变量如果是0,就没有资源,大于0就有资源,所以这个函数等效与freertos的二值信号量和计数信号量,一个函数就顶freertos两个函数的功能。
/*
*********************************************************************************************************
* CREATE A SEMAPHORE
*
* Description: This function creates a semaphore.
*
* Arguments : cnt is the initial value for the semaphore. If the value is 0, no resource is
* available (or no event has occurred). You initialize the semaphore to a
* non-zero value to specify how many resources are available (e.g. if you have
* 10 resources, you would initialize the semaphore to 10).
*
* Returns : != (void *)0 is a pointer to the event control clock (OS_EVENT) associated with the
* created semaphore
* == (void *)0 if no event control blocks were available
*********************************************************************************************************
*/
OS_EVENT *OSSemCreate (INT16U cnt)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_EVENT *pevent;
if (OSIntNesting > 0) { /* See if called from ISR ... */
return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */
}
OS_ENTER_CRITICAL();
pevent = OSEventFreeList; /* Get next free event control block */
if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
}
OS_EXIT_CRITICAL();
if (pevent != (OS_EVENT *)0) { /* Get an event control block */
pevent->OSEventType = OS_EVENT_TYPE_SEM;
pevent->OSEventCnt = cnt; /* Set semaphore value */
pevent->OSEventPtr = (void *)0; /* Unlink from ECB free list */
OS_EventWaitListInit(pevent); /* Initialize to 'nobody waiting' on sem. */
}
return (pevent);
}
重点可以看:pevent->OSEventCnt = cnt; /* Set semaphore value */
书中也有两个实例,一个是资源共享的实例,一个是同步的实例,区别在于初始化信号量的初始值是不一样的,前者是OSSemCreate(1),后者是OSSemCreate(0)。
请求信号量函数,函数原型:void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
可以看出参数中,OS_EVENT *pevent,是最重要的,如果有信号量,就会pevent->OSEventCnt--,没有就一直等待,或者等待一段时间
发送信号量函数
INT8U OSSemPost (OS_EVENT *pevent)
看得出来,参数很简单,只有一个事件的结构体指针,可以看到下面的核心语句:
if (pevent->OSEventCnt < 65535) { /* Make sure semaphore will not overflow */
pevent->OSEventCnt++; /* Increment semaphore count to register event */
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
说明,信号量是uint16类型的,发送信号量会执行pevent->OSEventCnt++
总结,就是ucos ii 2.52的代码比较易读,他的信号量已经包括了freertos的两个信号量,根据初始值不同而有所区别,其本质就是一个计数信号量的功能。

浙公网安备 33010602011771号