基于TI-RTOS的CC2650DK开发(12)---事件模块

4.2 事件模块
事件为线程间的通信和同步提供了一种手段。它和Semaphores类似,除了它们允许你在等待线程返回之前可以指定必须发生的多个条件(“事件”)。

事件实例和Semaphore一样使用“pend”和“post”调用。然而调用Event_pend()需附加指定等待哪个事件,调用Event_post()需指定提交的事件是哪个。

注意:每次只有单个Task可以等待一个事件对象。

单个事件实例可管理最多32个事件,每个事件都用一个事件ID代表。事件ID是简单的比特掩码,对应着一个由事件对象管理的唯一事件。
事件的行为和二元semaphore类似。

Event_pend()有两个参数"andMask"和"orMask"。andMask由所有必须发生的事件的事件ID组成,orMask由所有事件中的必须发生的那个一个事件的事件ID组成。

和Semaphonres一样,调用Event_pend()时携带一个timeout参数,如果调用超时则返回0。如果调用 Event_pend()成功,则返回"消耗"掉的事件掩码-----也就是满足 Event_pend()的调用所发生的事件。然后该任务处理所有消耗掉的事件。

只有Tasks可以调用  Event_pend(),反之,Hwi、Swi和其它Tasks都可以调用Event_post()。
Event_pend()原型如下:
UInt Event_pend(Event_Handle event,
                UInt andMask,
                UInt orMask,
                UInt timeout);

Event_post()原型如下:
Void Event_post(Event_Handle event,
                UInt eventIds);

配置实例:以下配置声明静态地创建了一个事件。事件对象的Event_Handle名称为“myEvent”:
var Event = xdc.useModule( "ti.sysbios.knl.Event");
Program.global.myEvent = Event.create();

运行时实例:以下C代码创建了一个事件对象,Event_Handle名称为“myEvent”:
Event_Handle myEvent;
Error_Block eb;
Error_init(&eb);
/* Default instance configuration params */
myEvent = Event_create( NULL, &eb);
if (myEvent ==  NULL)
{
    System_abort( "Event create failed");
}

运行时实例:以下是一个事件的C代码。它仅在events 0和6都发生时才唤醒task。它设置andMash为Event_Id_00 和Event_Id_06,并设置orMash为Event_Id_NONE。
Event_pend(myEvent, (Event_Id_00 + Event_Id_06), Event_Id_NONE,
           BIOS_WAIT_FOREVER);

运行时实例:以下C代码调用Event_post()来表明发生哪个事件。eventMash应包含被提交的事件的IDs。
Event_post(myEvent, Event_Id_00);

运行时实例:以下C代码演示了task如何为三个中断服务程序提供后台运行的需要:
基于TI-RTOS的CC2650DK开发(12)---事件模块 - 阿巴睇 - 阿巴睇的博客
Event_Handle myEvent;
main()
{
    ...
     /* create an Event object. All events are binary */
    myEvent = Event_create( NULL, &eb);
     if (myEvent ==  NULL)
    {
        System_abort( "Event create failed");
    }
}
isr0()
{
    ...
    Event_post(myEvent, Event_Id_00);
    ...
}
isr1()
{
    ...
    Event_post(myEvent, Event_Id_01);
    ...
}
isr2()
{
    ...
    Event_post(myEvent, Event_Id_02);
    ...
}
task()
{
    UInt events;
     while (TRUE)
    {
         /* Wait for ANY of the ISR events to be posted *
        events = Event_pend(myEvent, Event_Id_NONE,
        Event_Id_00 + Event_Id_01 + Event_Id_02,
        BIOS_WAIT_FOREVER);
        /* Process all the events that have occurred */

         if (events & Event_Id_00)
        {
            processISR0();
        }
         if (events & Event_Id_01)
        {
            processISR1();
        }
         if (events & Event_Id_02)
        {
            processISR2();
        }
    }
}

4.2.1 隐式提交事件
除了支持通过Event_post() API显示提交事件之外,一些SYS/BIOS对象还支持隐式提交它们所关联的事件。例如,Mailbox(邮箱)就可配置为 无论何时,只要获得信息(就是调用了Mailbox_post())都可 提交一个关联事件,这使得task可以阻塞以等待Mailbox信息或其它事件的发生。

Mailbox和Semaphore对象现在支持在所关联的资源可用时提交事件。
支持隐式事件提交的SYS/BIOS对象必须在创建时配置一个事件对象和事件ID。你可以决定将指定资源的可用信号关联到如一个事件ID之上(也就是Mailbox中的信息可用,Mailbox的room可用或Semaphore可用)。

注意:之前曾说过,同一时间只有一个Task可以等待一个事件对象。所以可以得出结论,为隐式提交的事件所配置的SYS/BIOS对象同一时间仅可以等待单个Task。

当Event_pend()用于从隐式提交的对象获取资源时,timeout参数BIOS_NO_WAIT将用于随后从对象接收资源。

运行时实例:以下C代码例程演示了一个task将消息提交到Mailbox消息以及执行一个ISR的提交处理需求。
基于TI-RTOS的CC2650DK开发(12)---事件模块 - 阿巴睇 - 阿巴睇的博客
 
Event_Handle myEvent;
Mailbox_Handle mbox;
typedef  struct msg
{
    UInt id;
    Char buf[ 10];
}
main()
{
    Mailbox_Params mboxParams;
    Error_Block eb;
    Error_init(&eb);
    myEvent = Event_create( NULL, &eb);
     if (myEvent ==  NULL)
    {
        System_abort( "Event create failed");
    }
    Mailbox_Params_init(&mboxParams);
    mboxParams.readerEvent = myEvent;
     /* Assign Event_Id_00 to Mailbox "not empty" event */
    mboxParams.readerEventId = Event_Id_00;
    mbox = Mailbox_create( sizeof(msg),  50, &mboxParams, &eb);
     if (mbox ==  NULL)
    {
        System_abort( "Mailbox create failed");
    }
     /* Mailbox_create() sets Mailbox's readerEvent to
    * counting mode and initial count = 50 */

}
writerTask()
{
    ...
    Mailbox_post(mbox, &msgA, BIOS_WAIT_FOREVER);
     /* implicitly posts Event_Id_00 to myEvent */
    ...
}
isr()
{
    Event_post(myEvent, Event_Id_01);
}
readerTask()
{
     while (TRUE)   /* Wait for either ISR or Mailbox message */
    {
        events = Event_pend(myEvent,
                            Event_Id_NONE,  /* andMask = 0 */
                            Event_Id_00 + Event_Id_01,  /* orMask */
                            BIOS_WAIT_FOREVER);  /* timeout */
         if (events & Event_Id_00)
        {
             /* Get the posted message.
            * Mailbox_pend() will not block since Event_pend()
            * has guaranteed that a message is available.
            * Notice that the special BIOS_NO_WAIT
            * parameter tells Mailbox that Event_pend()
            * was used to acquire the available message.
            */

            Mailbox_pend(mbox, &msgB, BIOS_NO_WAIT);
            processMsg(&msgB);
        }
         if (events & Event_Id_01)
        {
            processISR();
        }
    }
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值