ucos-iii v3.03信号量小结
ucos-iiv2.52毕竟是老版本,现在ucosiii都已经出来很久了,而且马上就可以免费使用了,除了ucgui,因为ucgui是segger的,因此有必要分析一下。源码参考V3.03.00的版本。
解压出来后,是这个结构\Micrium\Software\uCOS-III,
信号量创建函数如下:是不是可读性比较好,这是ucos的大优点
/*
************************************************************************************************************************
* CREATE A SEMAPHORE
*
* Description: This function creates a semaphore.
*
* Arguments : p_sem is a pointer to the semaphore to initialize. Your application is responsible for
* allocating storage for the semaphore.
*
* p_name is a pointer to the name you would like to give the semaphore.
*
* cnt is the initial value for the semaphore.
* If used to share resources, you should initialize to the number of resources available.
* If used to signal the occurrence of event(s) then you should initialize to 0.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE if the call was successful
* OS_ERR_CREATE_ISR if you called this function from an ISR
* OS_ERR_ILLEGAL_CREATE_RUN_TIME if you are trying to create the semaphore after you
* called OSSafetyCriticalStart().
* OS_ERR_NAME if 'p_name' is a NULL pointer
* OS_ERR_OBJ_CREATED if the semaphore has already been created
* OS_ERR_OBJ_PTR_NULL if 'p_sem' is a NULL pointer
* OS_ERR_OBJ_TYPE if 'p_sem' has already been initialized to a different
* object type
*
* Returns : none
************************************************************************************************************************
*/
void OSSemCreate (OS_SEM *p_sem,
CPU_CHAR *p_name,
OS_SEM_CTR cnt,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#ifdef OS_SAFETY_CRITICAL_IEC61508
if (OSSafetyCriticalStartFlag == DEF_TRUE) {
*p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to be called from an ISR */
*p_err = OS_ERR_CREATE_ISR;
return;
}
#endif
#if OS_CFG_ARG_CHK_EN > 0u
if (p_sem == (OS_SEM *)0) { /* Validate 'p_sem' */
*p_err = OS_ERR_OBJ_PTR_NULL;
return;
}
#endif
OS_CRITICAL_ENTER();
p_sem->Type = OS_OBJ_TYPE_SEM; /* Mark the data structure as a semaphore */
p_sem->Ctr = cnt; /* Set semaphore value */
p_sem->TS = (CPU_TS)0;
p_sem->NamePtr = p_name; /* Save the name of the semaphore */
OS_PendListInit(&p_sem->PendList); /* Initialize the waiting list */
#if OS_CFG_DBG_EN > 0u
OS_SemDbgListAdd(p_sem);
#endif
OSSemQty++;
OS_CRITICAL_EXIT_NO_SCHED();
*p_err = OS_ERR_NONE;
}
p_sem->Ctr = cnt; 这个语句是关键点地方,名称和ucos -ii有所区别,但本质是一样的。
请求信号量函数,函数名称都没变过,所以版本过度很简单。
OS_SEM_CTR OSSemPend (OS_SEM *p_sem,
OS_TICK timeout,
OS_OPT opt,
CPU_TS *p_ts,
OS_ERR *p_err)
可以看出参数中,OS_EVENT *pevent已经转变为OS_SEM *p_sem,说明ucosiii的信号量已经和ucos ii的数据结构不一样了。
其中:如果有信号量,就会p_sem->Ctr--; (类似于ucos ii的pevent->OSEventCnt--)。
发送信号量函数
OS_SEM_CTR OSSemPost (OS_SEM *p_sem,
OS_OPT opt,
OS_ERR *p_err)
函数名称也没变过,所以版本过度简单。然而不同的是,函数再次调用下面的函数来进行ctr的更新,说明已经比ucosii更加强大了。
OS_SEM_CTR OS_SemPost (OS_SEM *p_sem,
OS_OPT opt,
CPU_TS ts,
OS_ERR *p_err)
这个函数里面,分别对很多种情况进行判断,当然也有这个语句:p_sem->Ctr++;
总结,就是ucos iii的代码其实已经是一个新的rtos了,这个作者也曾经在书籍中说过的,很多功能是ucos ii所没有的,当然ucos iii也是在更新中,很多一开始加入的特性都在后期的版本中去掉了,相当于优化了,但是基本的特性还是保留的。
正如这个信号量,肯定是保留的,他的基本原理和ucos ii是一样的,好freertos也是差不多的。
有信号量(Ctr>0),任务就执行,如果没有信号量(Ctr=0),就一直等待或等待一段时间就继续执行后续程序。
释放信号量,就把Ctr增加。