Multiple mailbox

I'm trying to use multiple maibox for communication between a parent task to other tasks daughters.
But my parent task can only communicate with a single child task, after which the system seems to stop.

/* Struct messages */
struct mbx_messages {
  u8 cmd, ok;
  u8 pack[10];
};
/* Mailbox declarations */
os_mbx_declare(mbx_task_master, 1);
os_mbx_declare(mbx_task_slave_1, 1);
os_mbx_declare(mbx_task_slave_2, 1);
/* Memory pool */
_declare_box(mbx_pool, sizeof(struct mbx_messages), 6);

/* Master task */
__task void master_task(void)
{
  struct mbx_messages *snd_msg, *rcv_msg;
  os_dly_wait(4);
  while(1)
  {
    os_dly_wait(4);
    if(uart_2_read_byte() == 'S')
    {
      if(os_mbx_check(&mbx_qtotalizer_sweepfp) != 0)
      {
        snd_msg = _alloc_box(mbx_pool);
        snd_msg->cmd = 1;
        os_mbx_send(&mbx_task_slave_1, snd_msg, 10);
        if(os_mbx_wait(&mbx_task_master, (void *)&rcv_msg, 10) != OS_R_TMO)
        {
          if(rcv_msg->cmd == 2)
          {
            snd_msg = _alloc_box(mbx_pool);
            snd_msg->cmd = 3;
            os_mbx_send(&mbx_task_slave_2, snd_msg, 10);
            if(os_mbx_wait(&mbx_task_master, (void *)&rcv_msg, 10) != OS_R_TMO)
            {
              if(rcv_msg->cmd == 4)
              {
                uart_2_write_str("cmd = 4\n");
              }
            }
          }
          else
          {
            uart_2_write_str("cmd != 2\n");
          }
        }
        _free_box(pool_sweepfp, rcv_msg);
      }
    }
  }
}

/* Slave 1 task */
__task void slave_1_task(void)
{
  struct mbx_messages *snd_msg, *rcv_msg;
  os_dly_wait(4);
  while(1)
  {
    if(os_mbx_wait(&mbx_task_slave_1, (void *)&rcv_msg, 10) != OS_R_TMO)
    {
      snd_msg = _alloc_box(mbx_pool);
      if(rcv_msg->cmd == 1)
        snd_msg->cmd = 2;
      else
        uart_2_write_str("cmd != 1\n");
      os_mbx_send(&mbx_task_master, snd_msg, 10);
    }
    _free_box(pool_sweepfp, rcv_msg);
  }
}

/* Slave 2 task */
__task void slave_2_task(void)
{
  struct mbx_messages *snd_msg, *rcv_msg;
  os_dly_wait(4);
  while(1)
  {
    if(os_mbx_wait(&mbx_task_slave_2, (void *)&rcv_msg, 10) != OS_R_TMO)
    {
      snd_msg = _alloc_box(mbx_pool);
      if(rcv_msg->cmd == 3)
        snd_msg->cmd = 4;
      else
        uart_2_write_str("cmd != 4\n");
      os_mbx_send(&mbx_task_master, snd_msg, 10);
    }
    _free_box(pool_sweepfp, rcv_msg);
  }
}

/* Boot task */
__task void boot_task(void)
{
  uart_2_open(9600);
  _init_box(mbx_pool, sizeof(mbx_pool), sizeof(struct mbx_messages));
  os_mbx_init(&mbx_task_master, sizeof(mbx_task_master));
  os_mbx_init(&mbx_task_slave_1, sizeof(mbx_task_slave_1));
  os_mbx_init(&mbx_task_slave_2, sizeof(mbx_task_slave_2));
  os_tsk_create(master_task, 11);
  os_tsk_create(slave_1_task, 12);
  os_tsk_create(slave_2_task, 13);
}

/* Main */
int main(void)
{
  os_sys_init(boot_task);
}

That a call will be _free_box is not clearing the message sent recently?
Message allocated by _alloc_box is automatically removed by os_mbx_wait?

Parents
  • You can send information using many mailboxes. But be very careful about a main thread that only waits and listens for a single mailbox queue. If you don't just make an instant poll there, but allows the thread to wait actual time, then an empty mailbox means that your thread will stay and wait there - and during that time will not check if anything happens on another mailbox.

    When multithreaded applications for some reason are non-responsive, you - as developer - must make some form of flowchart where you analyze all points all the different threads can stop and wait for events, or waits for resource locks. And how these stops interacts with other threads.

    If you feel it's too much work setting up a description of such inter-thread timing relations, then you have to consider not using threads in the first place. Threads can be fun, exciting, and a nice way to structure a program. But incorrectly implemented, they are good sources for deadlocks or concurrent updates (and hence destruction) of shared data. So threads must be used with discipline.

Reply
  • You can send information using many mailboxes. But be very careful about a main thread that only waits and listens for a single mailbox queue. If you don't just make an instant poll there, but allows the thread to wait actual time, then an empty mailbox means that your thread will stay and wait there - and during that time will not check if anything happens on another mailbox.

    When multithreaded applications for some reason are non-responsive, you - as developer - must make some form of flowchart where you analyze all points all the different threads can stop and wait for events, or waits for resource locks. And how these stops interacts with other threads.

    If you feel it's too much work setting up a description of such inter-thread timing relations, then you have to consider not using threads in the first place. Threads can be fun, exciting, and a nice way to structure a program. But incorrectly implemented, they are good sources for deadlocks or concurrent updates (and hence destruction) of shared data. So threads must be used with discipline.

Children
More questions in this forum