This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Mailboxes and events

Other Parts Discussed in Thread: SYSBIOS

Hi,

I am currently using TI-RTOS 2.11.01.09 with Sysbios 6.41.02.41.

It is not clear to me how the events are managed if two messages are queued in the mailbox before the task can process them. I tried looking at the source code, but I don't references to events in the file mailbox.c.

Here is a snippet of code (don't mind the typos):

while (1)
{
   // Wait for a new event
   UInt events = Event_pend(mNetworkEvent, QUEUE_EVENT_NONE, (QUEUE_EVENT_COMMAND | QUEUE_EVENT_MESSAGE), BIOS_WAIT_FOREVER);

   if (event & QUEUE_EVENT_COMMAND)
   {
      Mailbox_pend(mCommandQueue, &command, BIOS_NO_WAIT);
      // do stuff here
   }

   if (event & QUEUE_EVENT_MESSAGE)
   {
      Mailbox_pend(mCommandQueue, &message, BIOS_NO_WAIT);
      //do other stuff here
   }
}

So what happens to events if I have two messages waiting in one of those mailboxes and I read only once as illustrated in the code above?

Will the event be triggered only once for both events or will the event be "re-triggered" a second time after I dequeue the first message?

Thank you

  • The internal Event_post() call occurs within the Semaphore_post() call which occurs for each Mailbox_post() call. Event_post() will only be called within Semaphore_post() if there are NO tasks currently blocked waiting for the semaphore.

    Assuming your code only calls Mailbox_pend() when Event_pend() returns, then there will never be a task blocked on the internal semaphore because the semaphore will always be available after Event_pend() returns. Therefore, in your application, Event_post() will be called each time Mailbox_post() is called.

    Depending on system dynamics and task priorities, more than one Mailbox_post() call may occur before the task that is currently blocked on the Event object returns from Event_pend(). However, upon returning from Event_pend(), no memory of the number of times Mailbox_post() has been called persists within the Event object.

    It is the duty of the code following Event_pend() to completely drain the Mailbox prior to calling Event_pend() again to insure that messages don't get stuck in the Mailbox. Mailbox_pend(mbx, msg, BIOS_NO_WAIT) should be employed to drain the Mailbox prior to calling Event_pend().

    Alan
  • OK.

    Following the Event_pend, I disable task switching with software interrupts (since the Mailbox_post occurs inside a Swi). I read the number of messages with Mailbox_getNumPendingMessages(). Inside that same critical section, I call Event_pend again with BIOS_NO_WAIT timeout to remove any pending events that could have occurred between the previous Event_pend and the getNumPendingMessages.

    Once, I have the number of messages, I restore task switching and I fetch the messages. Any other message that arrives after the critical section will trigger another event and will cause the Event_pend to return automatically.

    Here is the code snippet:

    while(1)
    {
      UInt events = Event_pend(mEvent,
                               MAILBOX_EVENT_NONE,      // AND events
                              (MAILBOX_EVENT_COMMAND | MAILBOX_EVENT_MESSAGE), // OR events
                              BIOS_WAIT_FOREVER);
    
    
      if (events & MAILBOX_EVENT_COMMAND)
      {
        Int numberOfCommands;
        UInt key;
        key = Swi_disable();
        {
          // Get the number of commands waiting
          numberOfCommands = Mailbox_getNumPendingMsgs(mCommandMailbox);
          // Clear pending command events
          Event_pend(mEvent,
                     MAILBOX_EVENT_COMMAND,     // AND mask
                     MAILBOX_EVENT_NONE,        // OR mask
                     BIOS_NO_WAIT);
        }
        Swi_restore(key);
             
        while (numberOfCommands)
        {
           Mailbox_pend(mCommandMailbox, &command, BIOS_NO_WAIT);
    
           // Do stuff here
    
           --numberOfCommands;
        }
      }
      if (events & MAILBOX_EVENT_MESSAGE)
      {
        // SAME LOGIC HERE AS COMMAND
      }
    }

    Is it correct? Or have I missed something?

  • Yes. That looks like it should work as long as you use the BIOS_NO_WAIT timeout while you have Swis disabled.

    I'd hoped that it would be less complex.

    Alan