designing a message "bus"


yshragai.firmware@...
 

Hi,
I'm wanting to design a firmware, for a small low-power embedded system, with an architecture that features a "bus" over which the firmware modules communicate. I'm wondering how to design this "bus".
 
Basically what I'm envisioning is modules sending messages over this bus that contain an address or module ID of some sort or another; the module that matches this address or ID would pick up the message off the bus.
 
One brute-force way to design this is a queue (such as a FIFO) per target module. This is not the most elegant or scalable solution, but it'll work... Is there a way to design this that's more scalable, and maybe even elegant?
 
I wish there were a mechanism in Zephyr by which a thread could subscribe to messages in a given queue not by sender ID (as is possible with a mailbox) but by some identifying characteristic of the message (e.g., by the value in the "info" field).
 
Thanks!


Jason Bens <jason.bens@...>
 

I’m sure you’ll get a slew of possible implementations, but have you considered implementing the observer pattern?  https://en.wikipedia.org/wiki/Observer_pattern .  If I were to implement this, I’d give each module an event queue to receive messages on, and a list containing pointers to the event queues of other interested modules (the observers).  Observers are notified by iterating over the list and sending the event to each one.  Unfortunately, the granularity of this approach is only to the module level, and so may not meet your needs as described.

 

  • Jason

 

From: users@... <users@...> On Behalf Of yshragai.firmware@...
Sent: May 3, 2022 11:20 PM
To: users@...
Subject: [Zephyr-users] designing a message "bus"

 

External Email:

Hi,

I'm wanting to design a firmware, for a small low-power embedded system, with an architecture that features a "bus" over which the firmware modules communicate. I'm wondering how to design this "bus".

 

Basically what I'm envisioning is modules sending messages over this bus that contain an address or module ID of some sort or another; the module that matches this address or ID would pick up the message off the bus.

 

One brute-force way to design this is a queue (such as a FIFO) per target module. This is not the most elegant or scalable solution, but it'll work... Is there a way to design this that's more scalable, and maybe even elegant?

 

I wish there were a mechanism in Zephyr by which a thread could subscribe to messages in a given queue not by sender ID (as is possible with a mailbox) but by some identifying characteristic of the message (e.g., by the value in the "info" field).

 

Thanks!


Guy Morand
 

Hi Yshragai,

Have you looked at 'k_mbox' data structure? It seems you can set a destination thread or broadcast messages with 'K_ANY':
https://docs.zephyrproject.org/latest/kernel/services/data_passing/mailboxes.html

Hope this helps,
regards,

Guy

On 5/3/22 23:20, yshragai.firmware@... wrote:
Hi,
I'm wanting to design a firmware, for a small low-power embedded system, with an architecture that features a "bus" over which the firmware modules communicate. I'm wondering how to design this "bus".
Basically what I'm envisioning is modules sending messages over this bus that contain an address or module ID of some sort or another; the module that matches this address or ID would pick up the message off the bus.
One brute-force way to design this is a queue (such as a FIFO) per target module. This is not the most elegant or scalable solution, but it'll work... Is there a way to design this that's more scalable, and maybe even elegant?
I wish there were a mechanism in Zephyr by which a thread could subscribe to messages in a given queue not by sender ID (as is possible with a mailbox) but by some identifying characteristic of the message (e.g., by the value in the "info" field).
Thanks!
--
bytes at work
Technoparkstrasse 7
CH-8406 Winterthur
Switzerland

phone: +41 52 213 79 79


Guy Morand
 

Hi Yshragai,

Small correction on my previous statement. As stated in the documentation, broadcasting is not possible:

Each message may be received by only one thread (i.e.
point-to- multipoint and broadcast messaging is not supported).
We had a small internal discussion about a similar topic this morning and for this reason, we decided to implement our own observer pattern by sending events to a dispatcher using message queue.

Anyway, if you have a better approach, I'm eager to hear more!

Best regards,

Guy


On 5/4/22 09:31, Guy Morand via lists.zephyrproject.org wrote:
Hi Yshragai,
Have you looked at 'k_mbox' data structure? It seems you can set a destination thread or broadcast messages with 'K_ANY':
https://docs.zephyrproject.org/latest/kernel/services/data_passing/mailboxes.html Hope this helps,
regards,
Guy
On 5/3/22 23:20, yshragai.firmware@... wrote:
Hi,
I'm wanting to design a firmware, for a small low-power embedded system, with an architecture that features a "bus" over which the firmware modules communicate. I'm wondering how to design this "bus".
Basically what I'm envisioning is modules sending messages over this bus that contain an address or module ID of some sort or another; the module that matches this address or ID would pick up the message off the bus.
One brute-force way to design this is a queue (such as a FIFO) per target module. This is not the most elegant or scalable solution, but it'll work... Is there a way to design this that's more scalable, and maybe even elegant?
I wish there were a mechanism in Zephyr by which a thread could subscribe to messages in a given queue not by sender ID (as is possible with a mailbox) but by some identifying characteristic of the message (e.g., by the value in the "info" field).
Thanks!
--
bytes at work
Technoparkstrasse 7
CH-8406 Winterthur
Switzerland

phone: +41 52 213 79 79