VxWorks主要提供如下API进行信号量的创建、获取和释放:
(1)semBCreate( ):分配并初始化一个二进制信号量,函数原型为:
SEM_ID semBCreate
(
int options, /*信号量选项*/
SEM_B_STATE initialState /*信号量初始化状态值*/
) ;
(2)semMCreate( ):分配并初始化一个互斥信号量,函数原型为:
SEM_ID semBCreate
(
int options, /*信号量选项*/
SEM_B_STATE initialState /*信号量初始化状态值*/
);
(3)semCCreate( ):分配并初始化一个计数信号量,函数原型为:
SEM_ID semCCreate
(
int options, /*信号量选项*/
int initialCount /*信号量初始计数值*/
) ;
当一个信号量被创建时,它的队列(queue)类型需要被确定。等待信号量的任务队列可以以优先级顺序 (SEM_Q_PRIORITY)或者先到先得方式(SEM_Q_FIFO)排列。
(4)semDelete( ):删除一个自由的信号量,函数原型为:
STATUS semDelete
(
SEM_ID semId /*要删除的信号量ID号*/
);
(5)semTake( ):占有一个信号量,函数原型为:
STATUS semTake
(
SEM_ID semId /*所要得到的信号量ID号*/
int timeout /*等待时间*/
);
(6)semGive( ):释放一个信号量,函数原型为:
STATUS semGive
(
SEM_ID semId /*所给出的信号量ID号*/
);
(7)semFlush( ):解锁所有等待信号量的任务,函数原型为:
STATUS semFlush
(
SEM_ID semId /*要解锁的信号量ID号*/
);
二进制信号量:
要创建一个发挥互斥作用的二进制信号量一般使用semBCreat(xxx, SEM_FULL)调用,其中的SEM_FULL暗示该信号量用于任务间的互斥(最开始二进制信号量可获得)。对临界区域(critical region)的访问需以semTake和semGive加以保护:
semTake (semMutex, WAIT_FOREVER);
. . /*critical region, only accessible by a single task at a time*/
semGive (semMutex);
要创建一个发挥同步作用的二进制信号量一般使用semBCreat(xxx, SEM_EMPTY) 调用,其中的SEM_EMPTY 暗示该信号量用于任务间的同步(即最开始二进制信号量不可获得)。
二进制信号量使用最广泛的一种情况是中断与任务间通信。中断服务程序一般以二进制信号量“通知”对应的任务进行中断后的处理工作,例如:
SEM_ID syncSem;/* ID of sync semaphore */
myTask(void)
{
semTake(syncSem, WAIT_FOREVER); /* wait for event to occur */
printf("my Task got the semaphore\n");
... /* process event */
}
eventInterruptSvcRout(void)
{
semGive(syncSem); /* let my Task process event */
...
}
互斥信号量
互斥信号量可以看作一种特殊的二进制信号量,其支持普通二进制信号量不支持的一些特性,提供优先级继承、安全删除和回归能力。互斥信号量的使用方法和二进制信号量基本类似,但有如下区别:
(1)仅仅被用做互斥,不能提供同步机制;
(2)只能被使用它的任务释放;
(3)中断服务程序(ISR)不能释放它;
(4)不能使用函数semFlush( );
(5)支持使用二进制信号量进行互斥时所不支持的优先级“翻转”。
任务的优先级翻转是指高优先级任务因等待低优先级任务占用的互斥资源而被较低优先级(高于低优先级但低于高优先级)的任务不断抢占的情况。VxWorks操作系统提供优先级继承机制对优先级翻转进行预防。占用互斥资源但优先级较低的任务被暂时地提高到等待该资源的最高优先级任务的优先级。这样,中等优先级的任务将无法抢占原本低优先级的任务,使得低优先级任务能尽快执行,释放出优先级较高的任务所需要的资源。
为了使互斥信号量支持优先级继承支持,我们在调用semMCreate时应使用SEM_Q_PRIORITY和SEM_INVERSION_SAFE选项。互斥信号量提供互斥也需要对临界区域进行保护:
semTake (semMutex, WAIT_FOREVER);
. . //critical region, only accessible by a single task at a time .
semGive (semMutex);
阅读(13027) | 评论(1) | 转发(1) |