This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

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
  • If the master task only start one slave task at a time, and don't start a new task before the previous task is done, then you don't need multiple child tasks. It's enough with a single "worker" tasks that waits for a job to be handed out. The worker task checks what to do, performs the task and then report back before starting to wait for next thing to do.

    The main reason for a program to consist of 4 tasks is that the individual tasks are likely to need to run concurrently with each other. Things that can be handled in sequence shouldn't be splitted into separate tasks unless you work on a hyperthreaded or multicore processor and wants to process multiple, non-related work blocks, concurrently.

    So an image-processing program may have multiple tasks to get a quad-core processor to process a large 20Mpix image four times faster - or to process four images concurrently.

    But an image-processing program running on a single-threaded processor would add complexity while slowing down the program, by having multiple threads to try to concurrently work with same image or concurrently work on multiple images.

    In the end, you should make some form of sequence diagram where you show what things that needs to be performed concurrently by having multiple threads time-slicing through the work or where a higher-priority thread must be able to interrupt and perform a more important task before releasing the processor to lower-priority threads.

    And that sequence diagram should also concern itself with how a higher-prio thread can lock up a lower-prio thread. Or how a lower-prio thread taking a resource lock can lock up a higher prio thread.

    In the end - programs should be written as well-defined modules. So functionality is broken down into small and easy-to-understand functions. But these functions shouldn't be run by individual threads unless there is needs for concurrency. Or the sequence diagram becomes too complex if the work isn't split into multiple threads interacting using simple, and easy to overview, signaling, messaging, ... mechanisms.

Reply
  • If the master task only start one slave task at a time, and don't start a new task before the previous task is done, then you don't need multiple child tasks. It's enough with a single "worker" tasks that waits for a job to be handed out. The worker task checks what to do, performs the task and then report back before starting to wait for next thing to do.

    The main reason for a program to consist of 4 tasks is that the individual tasks are likely to need to run concurrently with each other. Things that can be handled in sequence shouldn't be splitted into separate tasks unless you work on a hyperthreaded or multicore processor and wants to process multiple, non-related work blocks, concurrently.

    So an image-processing program may have multiple tasks to get a quad-core processor to process a large 20Mpix image four times faster - or to process four images concurrently.

    But an image-processing program running on a single-threaded processor would add complexity while slowing down the program, by having multiple threads to try to concurrently work with same image or concurrently work on multiple images.

    In the end, you should make some form of sequence diagram where you show what things that needs to be performed concurrently by having multiple threads time-slicing through the work or where a higher-priority thread must be able to interrupt and perform a more important task before releasing the processor to lower-priority threads.

    And that sequence diagram should also concern itself with how a higher-prio thread can lock up a lower-prio thread. Or how a lower-prio thread taking a resource lock can lock up a higher prio thread.

    In the end - programs should be written as well-defined modules. So functionality is broken down into small and easy-to-understand functions. But these functions shouldn't be run by individual threads unless there is needs for concurrency. Or the sequence diagram becomes too complex if the work isn't split into multiple threads interacting using simple, and easy to overview, signaling, messaging, ... mechanisms.

Children