Discussion Forum
Multiple mailbox
Next Thread | Thread List | Previous Thread
Start a Thread | Settings
| Details |
Message |
|
Read-Only
Author Rafael Risson
Posted 5-Jun-2012 20:02 GMT
Toolset ARM
|
 Multiple mailbox
Rafael Risson
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?
|
|
|
Read-Only
Author Per Westermark
Posted 6-Jun-2012 09:56 GMT
Toolset ARM
|
 RE: Multiple mailbox
Per Westermark
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.
|
|
|
Read-Only
Author Rafael Risson
Posted 6-Jun-2012 13:10 GMT
Toolset ARM
|
 RE: Multiple mailbox
Rafael Risson
Ok, thanks for the reply.
I'll explain my application (on the concept that tasks should be
small and well defined, with specific functions):
com_dev_status_task - Task to monitor device status. This task will trigger other tasks.
com_dev_block_task - Task responsible for locking the device.
com_dev_get_info - Task that will request information from the device.
com_dev_reset_task - Task to restart the device.
Thus, the task status is sending messages to other tasks,
depending on what should be done with the device. These messages
between tasks is basically it
struct com_dev_internal_msg {
u8 cmd, id;
u8 pack[10];
u8 ok;
};
So, as I have a "master task" that triggers messages to other
tasks, must esssa "master task" know when "slave tasks" executed the
request. Such confirmation would also be a Mailbox.
In this case, I will always have only one "slave task" running,
others would be waiting for requests from the "master task".
I had thought to use events, but I need to send various
information tasks, I opted for the mailbox.
There is another way to structure this application? Or should a
single task that will process all commands device?
|
|
|
Read-Only
Author Per Westermark
Posted 6-Jun-2012 13:25 GMT
Toolset ARM
|
 RE: Multiple mailbox
Per Westermark
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.
|
|
|
Read-Only
Author Rafael Risson
Posted 6-Jun-2012 14:16 GMT
Toolset ARM
|
 RE: Multiple mailbox
Rafael Risson
Ok, as my processor is LPC2478 and the best option is to do a
single task with sequential requests.
Other tasks of my application would be:
display_update_task - Driven by update event or os_dly_wait
log_save_task - Driven by mailbox for burning logs on the memory card
Thanks for the help.
|
|
|
Read-Only
Author Per Westermark
Posted 6-Jun-2012 16:33 GMT
Toolset ARM
|
 RE: Multiple mailbox
Per Westermark
That looks like reasonable tasks - thinks that is valuable to do
concurrently.
|
|
Next Thread | Thread List | Previous Thread
Start a Thread | Settings
|