信号量有两种类型:一种是只有0和1两种值的信号量,称为二值信号量;另一种是可以有多种值的信号量,称为计数式信号量。计数式信号量的值的大小取决于信号量的数据类型,如若是8位整型变量,则其值可以是0~255;若是16位整型变量,则其值可以是0~65 535。
µC/OS-Ⅱ的信号量由两个部分组成:一个是信号量的计数值,范围是0~65 535;另一个是由等待该信号量的任务组成的等待任务列表。
信号量可以使用在如下场合:
- 允许一个任务与其它任务或中断同步;
- 取得共享资源的使用权;
- 标志事件的发生。
对µC/OS-Ⅱ信号量初始值的赋值方法如下:
- 信号量的初始值为0~65 535;
- 如果表示一个或者多个事件的发生,那么初始值应设为0;
- 如果是用于对共享资源的访问,那么该初始值应设为1。例如,把它当作二值信号量使用;
- 如果是用来表示允许任务访问n个相同的资源,那么该初始值应该是n,并把该信号量作为可计数的信号量使用。
µC/OS-Ⅱ提供了6种对信号量进行管理的函数,所属文件是OS_SEM.C。
OSSemDel()
函数用于删除一个信号量,调用者只能是任务在使用OSSemDel()
函数时应注意如下事项:
- 由于其它函数可能还会用到这个信号量,因此在删除信号量之前,必须首先删除等待该信号量的所有任务。
- 当挂起的任务进入就绪状态时,中断是关闭的,这就是说中断延迟与等待信号量的任务的数量密切相关。
- opt:定义信号量删除条件的选项。它有两个选择:①
OS_DEL_NO_PEND
:规定只能在已经没有任何任务等待信号量时,才能删除该信号量。②OS_DEL_ALWAYS
:规定不管有没有任务在等待,都立即删除这个信号量,删除后所有等待该信号量的任务立即进入就绪状态,并执行一次任务调度。 - 如果信号量删除成功,则返回空指针;若信号量没有能被删除,则返回pevent,这时应该检查出错代码,以查明原因。
OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *perr)
{
BOOLEAN tasks_waiting;
OS_EVENT *pevent_return;
#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 (pevent);
}
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*perr = OS_ERR_PEVENT_NULL;
return (pevent);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
*perr = OS_ERR_EVENT_TYPE;
return (pevent);
}
if (OSIntNesting > 0) { /* See if called fro