@@ -878,6 +878,132 @@ illustrates the runtime registration usage.
878
878
the channel observer it was first associated with through :c:func: `zbus_chan_rm_obs `.
879
879
880
880
881
+ Multi-domain Communication
882
+ ***************************
883
+
884
+ ZBus supports multi-domain communication, enabling message passing between different execution
885
+ domains such as CPU cores or separate devices. This is achieved through proxy agents that
886
+ forward messages between domains.
887
+
888
+ .. figure :: images/zbus_proxy_agent.png
889
+ :alt: ZBus publish processing detail
890
+ :width: 75%
891
+
892
+ ..
893
+ Temporary image illustrating zbus multi-domain communication with proxy agents.
894
+
895
+ Concepts
896
+ ========
897
+
898
+ Multi-domain zbus introduces several key concepts:
899
+
900
+ * **Master channels **: Channels where messages are published locally within a domain
901
+ * **Shadow channels **: Read-only channels that mirror master channels from other domains
902
+ * **Proxy agents **: Background services that synchronize channel data between domains
903
+ * **Transport backends **: Communication mechanisms (IPC, UART) used by proxy agents
904
+
905
+ The :c:macro: `ZBUS_MULTIDOMAIN_CHAN_DEFINE ` macro enables conditional compilation to create
906
+ master channels in one domain and corresponding shadow channels in other domains.
907
+
908
+ Transport Backends
909
+ ==================
910
+
911
+ ZBus multi-domain communication relies on transport backends to forward messages between different
912
+ execution domains.
913
+
914
+ IPC Backend
915
+ -----------
916
+
917
+ The IPC backend facilitates communication between CPU cores within the same system using
918
+ Inter-Process Communication mechanisms.
919
+
920
+ See the :zephyr:code-sample: `zbus-ipc-forwarder ` sample for a complete implementation.
921
+
922
+ UART Backend
923
+ ------------
924
+
925
+ The UART backend enables communication between physically separate devices over serial connections.
926
+ This backend extends zbus messaging across device boundaries, allowing distributed systems to
927
+ maintain a unified message bus architecture.
928
+
929
+ See the :zephyr:code-sample: `zbus-uart-forwarder ` sample for a complete implementation.
930
+
931
+ Usage
932
+ =====
933
+
934
+ Multi-domain zbus requires defining shared channels and setting up proxy agents. Here's a typical setup:
935
+
936
+ **common.h ** - Shared channel definitions:
937
+
938
+ .. code-block :: c
939
+
940
+ #include <zephyr/zbus/zbus.h>
941
+ #include <zephyr/zbus/multidomain/zbus_multidomain.h>
942
+
943
+ struct request_data {
944
+ // ...
945
+ };
946
+
947
+ struct response_data {
948
+ // ...
949
+ };
950
+
951
+ ZBUS_MULTIDOMAIN_CHAN_DEFINE(request_channel, struct request_data,
952
+ NULL, NULL, ZBUS_OBSERVERS_EMPTY,
953
+ ZBUS_MSG_INIT(0),
954
+ IS_ENABLED(CONFIG_DOMAIN_A), /* Master on domain A */
955
+ 1 /* Include on both domains */);
956
+
957
+ ZBUS_MULTIDOMAIN_CHAN_DEFINE(response_channel, struct response_data,
958
+ NULL, NULL, ZBUS_OBSERVERS_EMPTY,
959
+ ZBUS_MSG_INIT(0),
960
+ IS_ENABLED(CONFIG_DOMAIN_B), /* Master on domain B */
961
+ 1 /* Include on both domains */);
962
+
963
+ **Domain A ** - Requester setup:
964
+
965
+ .. code-block :: c
966
+
967
+ #include "common.h"
968
+
969
+ /* Set up proxy agent and add channels for forwarding */
970
+ ZBUS_PROXY_AGENT_DEFINE(proxy_agent, ZBUS_MULTIDOMAIN_TYPE_IPC, ipc_instance);
971
+ ZBUS_PROXY_ADD_CHANNEL(proxy_agent, request_channel);
972
+
973
+ void response_listener_cb(const struct zbus_channel *chan) {
974
+ const struct response_data *resp = zbus_chan_const_msg(chan);
975
+ LOG_INF("Received response: ...");
976
+ }
977
+ ZBUS_LISTENER_DEFINE(response_listener, response_listener_cb);
978
+ ZBUS_CHAN_ADD_OBS(response_channel, response_listener, 0);
979
+
980
+ int main(void)
981
+ {
982
+ struct request_data req = { /* ... */ };
983
+ zbus_chan_pub(&request_channel, &req, K_MSEC(100));
984
+ return 0;
985
+ }
986
+
987
+ **Domain B ** - Responder setup:
988
+
989
+ .. code-block :: c
990
+
991
+ #include "common.h"
992
+
993
+ /* Set up proxy agent and add channels for forwarding */
994
+ ZBUS_PROXY_AGENT_DEFINE(proxy_agent, ZBUS_MULTIDOMAIN_TYPE_IPC, ipc_instance);
995
+ ZBUS_PROXY_ADD_CHANNEL(proxy_agent, response_channel);
996
+
997
+ /* Observe requests and publish responses */
998
+ void request_listener_cb(const struct zbus_channel *chan) {
999
+ const struct request_data *req = zbus_chan_const_msg(chan);
1000
+ struct response_data resp = { /* ... */ };
1001
+ zbus_chan_pub(&response_channel, &resp, K_MSEC(100));
1002
+ LOG_INF("Processed request ...");
1003
+ }
1004
+ ZBUS_LISTENER_DEFINE(request_listener, request_listener_cb);
1005
+ ZBUS_CHAN_ADD_OBS(request_channel, request_listener, 0);
1006
+
881
1007
Samples
882
1008
*******
883
1009
@@ -901,7 +1027,8 @@ available:
901
1027
observer registration feature;
902
1028
* :zephyr:code-sample: `zbus-confirmed-channel ` implements a way of implement confirmed channel only
903
1029
with subscribers;
904
- * :zephyr:code-sample: `zbus-benchmark ` implements a benchmark with different combinations of inputs.
1030
+ * :zephyr:code-sample: `zbus-ipc-forwarder ` demonstrates multi-core communication using IPC forwarders;
1031
+ * :zephyr:code-sample: `zbus-uart-forwarder ` demonstrates inter-device communication using UART forwarders.
905
1032
906
1033
Suggested Uses
907
1034
**************
@@ -913,6 +1040,13 @@ subscribers (if you need a thread) or listeners (if you need to be lean and fast
913
1040
the listener, another asynchronous message processing mechanism (like :ref: `message queues
914
1041
<message_queues_v2>`) may be necessary to retain the pending message until it gets processed.
915
1042
1043
+ For multi-domain scenarios, use zbus to enable communication across execution boundaries:
1044
+
1045
+ * **Multi-core systems **: Use IPC backend to coordinate between application and network processors,
1046
+ or distribute workloads across multiple CPU cores.
1047
+ * **Distributed devices **: Use UART backend to create distributed applications where multiple
1048
+ connected devices participate in the same logical message bus over serial connections.
1049
+
916
1050
.. note ::
917
1051
ZBus can be used to transfer streams from the producer to the consumer. However, this can
918
1052
increase zbus' communication latency. So maybe consider a Pipe a good alternative for this
@@ -954,6 +1088,30 @@ Related configuration options:
954
1088
observers to statically allocate.
955
1089
* :kconfig:option: `CONFIG_ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_NONE ` use user-provided runtime
956
1090
observers nodes;
1091
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN ` enable multi-domain communication support.
1092
+
1093
+ Multi-domain Configuration Options
1094
+ ==================================
1095
+
1096
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_IPC ` enable IPC backend for multi-domain communication;
1097
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_UART ` enable UART backend for multi-domain communication;
1098
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_LOG_LEVEL ` set the log level for multi-domain operations;
1099
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_MESSAGE_SIZE ` maximum message size for multi-domain
1100
+ channels;
1101
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_CHANNEL_NAME_SIZE ` maximum size of channel names in
1102
+ multi-domain communication;
1103
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_PROXY_STACK_SIZE ` stack size for proxy agent threads;
1104
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_PROXY_PRIORITY ` priority of proxy agent threads;
1105
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_SENT_MSG_POOL_SIZE ` number of sent messages to track for
1106
+ acknowledgments;
1107
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_MAX_TRANSMIT_ATTEMPTS ` maximum retry attempts for message
1108
+ transmission;
1109
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_SENT_MSG_ACK_TIMEOUT ` initial acknowledgment timeout for
1110
+ sent messages;
1111
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_SENT_MSG_ACK_TIMEOUT_MAX ` maximum acknowledgment timeout
1112
+ for exponential backoff;
1113
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_UART_BUF_COUNT ` number of UART buffers for multi-domain
1114
+ communication;
957
1115
958
1116
API Reference
959
1117
*************
0 commit comments