【VxWorks系列】任务间同步与通信之事件

从VxWorks 5.5开始,提供了新的任务间同步通信的机制----事件,事件可用于任务和中断服务程序ISR之间、任务和任务之间、任务和VxWorks资源之间进行通信。 任务用函数eventReceive()来接收它关心的事件,用eventSend()来向另一个任务发送事件。(是否看似简单?)
先来看第一个例子:
void eventRoute1(void* param)
{
     int task_id = (int)param;
     eventSend(task_id , VXEV01);
    
}
void tryEvent()
{
     int id = taskIdSelf();
     taskSpawn("vxEvent1", 150, VX_FP_TASK, 30000, (FUNCPTR)eventRoute1, id,0,0,0,0,0,0,0,0,0 );
     eventReceive(VXEV01, EVENTS_WAIT_ALL, WAIT_FOREVER, 0);
}
tryEvent中启动一个任务,然后调用 eventReceive 通过设置 EVENTS_WAIT_ALL来 等待 VXEV01 事件的 发生,子任务中调用 eventSend向 初始任务 发送 事件 VXEV01 ,从而触发初始任务继续执行。
从这个例子,很多人也许会觉得事件跟信号量功能一样,没有太多意义。其实上面体现的功能只是事件的冰山一角,让我们慢慢来一窥全貌吧。
那么,事件有哪些特点呢?
第一,从上面的例子已经可以看出,使用事件时不需要创建任何对象,所以它是一种更轻量级的同步通信机制。因为每一个任务都有一个32位事件寄存器,其中高8位由VxWorks系统保留,开发者可以使用低24位(VXEV01~VXEV24),每一位表示一种事件。

第二,使用事件可以等待多个事件的发生,这里的多个事件发生的关系,可以是“与”也可以是“或”,在eventReceive方法中可以指定EVENTS_WAIT_ANYEVENTS_WAIT_ALL,比如等待VXEV01或VXEV02之一的发生:
eventReceive(VXEV01 | VXEV02, EVENTS_WAIT_ANY, WAIT_FOREVER, 0);
个人认为这是非常有用的一点,毕竟如果要自己实现多事件结合并可控制超时时间的话,可以说并非那么简单,而且性能也会有问题。

第三,除了上述例子中eventReceive和eventSend的使用外,事件还可用于任务跟VxWorks资源之间进行通信,这里所谓的资源有信号量,消息队列等。
比如再看第二个例子(假设已创建了sem_ev1和sem_ev2两个信号量):
void eventRoute1(void* param)
{
     semGive(sem_ev1);
}

void eventRoute2(void* param)
{
     semGive(sem_ev2);
}
void tryEvent()
{
     semEvStart(sem_ev1, VXEV01, EVENTS_SEND_ONCE);
     semEvStart(sem_ev2, VXEV02, EVENTS_SEND_ONCE);

     taskSpawn("vxEvent1", 150, VX_FP_TASK, 30000, (FUNCPTR)eventRoute1, 0,0,0,0,0,0,0,0,0,0 );
     taskSpawn("vxEvent2", 150, VX_FP_TASK, 30000, (FUNCPTR)eventRoute2, 0,0,0,0,0,0,0,0,0,0 );

     eventReceive(VXEV01 | VXEV02, EVENTS_WAIT_ALL, WAIT_FOREVER, 0);

     semEvStop(sem_ev1);
     semEvStop(sem_ev2);
}
跟资源通信,需要把对应资源注册到特定事件,如上例中是通过 semEvStart 把信号量 sem_ev1和sem_ev2分别 注册到事件 VXEV01和VXEV02,然后semGive信号量被释放且可用时,对应注册的事件会被触发。

第四,前面说到semGive信号量被释放且可用时,对应注册的事件会被触发,这里所谓可用的含义是,semGive释放信号量同时没有其他任务正在锁定该资源,也就是该时间点该资源可用时,才会触发事件。但不能保证该资源在事件被触发后还可用,因为后续有可能又被其他任务锁定。

第五,如果相关被注册到事件的资源被删除时,通过eventReceive等待该事件的任务会自动被触发,也就是说semDelete和msgQDelete会触发该资源注册过事件。但是需要注意的是,当调用semDelete时,任务执行于semEvStart和eventReceive之间的话,则后续eventReceive会被阻塞。

总上所述,VxWorks中,事件提供了非常丰富的功能,在实际应用场景中它的一些特性可以使很多复杂的事情变得极其简单。


  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值