@@ -878,6 +878,134 @@ 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(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(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
+ #define DOMAIN_A 1
968
+ #include "common.h"
969
+
970
+ /* Set up proxy agent and add channels for forwarding */
971
+ ZBUS_PROXY_AGENT_DEFINE(proxy_agent, ZBUS_MULTIDOMAIN_TYPE_IPC, ipc_instance);
972
+ ZBUS_PROXY_ADD_CHANNEL(proxy_agent, request_channel);
973
+
974
+ void response_listener_cb(const struct zbus_channel *chan) {
975
+ const struct response_data *resp = zbus_chan_const_msg(chan);
976
+ LOG_INF("Received response: ...");
977
+ }
978
+ ZBUS_LISTENER_DEFINE(response_listener, response_listener_cb);
979
+ ZBUS_CHAN_ADD_OBS(response_channel, response_listener, 0);
980
+
981
+ int main(void)
982
+ {
983
+ struct request_data req = { /* ... */ };
984
+ zbus_chan_pub(&request_channel, &req, K_MSEC(100));
985
+ return 0;
986
+ }
987
+
988
+ **Domain B ** - Responder setup:
989
+
990
+ .. code-block :: c
991
+
992
+ #define DOMAIN_B 1
993
+ #include "common.h"
994
+
995
+ /* Set up proxy agent and add channels for forwarding */
996
+ ZBUS_PROXY_AGENT_DEFINE(proxy_agent, ZBUS_MULTIDOMAIN_TYPE_IPC, ipc_instance);
997
+ ZBUS_PROXY_ADD_CHANNEL(proxy_agent, response_channel);
998
+
999
+ /* Observe requests and publish responses */
1000
+ void request_listener_cb(const struct zbus_channel *chan) {
1001
+ const struct request_data *req = zbus_chan_const_msg(chan);
1002
+ struct response_data resp = { /* ... */ };
1003
+ zbus_chan_pub(&response_channel, &resp, K_MSEC(100));
1004
+ LOG_INF("Processed request ...");
1005
+ }
1006
+ ZBUS_LISTENER_DEFINE(request_listener, request_listener_cb);
1007
+ ZBUS_CHAN_ADD_OBS(request_channel, request_listener, 0);
1008
+
881
1009
Samples
882
1010
*******
883
1011
@@ -901,7 +1029,8 @@ available:
901
1029
observer registration feature;
902
1030
* :zephyr:code-sample: `zbus-confirmed-channel ` implements a way of implement confirmed channel only
903
1031
with subscribers;
904
- * :zephyr:code-sample: `zbus-benchmark ` implements a benchmark with different combinations of inputs.
1032
+ * :zephyr:code-sample: `zbus-ipc-forwarder ` demonstrates multi-core communication using IPC forwarders;
1033
+ * :zephyr:code-sample: `zbus-uart-forwarder ` demonstrates inter-device communication using UART forwarders.
905
1034
906
1035
Suggested Uses
907
1036
**************
@@ -913,6 +1042,13 @@ subscribers (if you need a thread) or listeners (if you need to be lean and fast
913
1042
the listener, another asynchronous message processing mechanism (like :ref: `message queues
914
1043
<message_queues_v2>`) may be necessary to retain the pending message until it gets processed.
915
1044
1045
+ For multi-domain scenarios, use zbus to enable communication across execution boundaries:
1046
+
1047
+ * **Multi-core systems **: Use IPC backend to coordinate between application and network processors,
1048
+ or distribute workloads across multiple CPU cores.
1049
+ * **Distributed devices **: Use UART backend to create distributed applications where multiple
1050
+ connected devices participate in the same logical message bus over serial connections.
1051
+
916
1052
.. note ::
917
1053
ZBus can be used to transfer streams from the producer to the consumer. However, this can
918
1054
increase zbus' communication latency. So maybe consider a Pipe a good alternative for this
@@ -954,6 +1090,30 @@ Related configuration options:
954
1090
observers to statically allocate.
955
1091
* :kconfig:option: `CONFIG_ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_NONE ` use user-provided runtime
956
1092
observers nodes;
1093
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN ` enable multi-domain communication support.
1094
+
1095
+ Multi-domain Configuration Options
1096
+ ==================================
1097
+
1098
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_IPC ` enable IPC backend for multi-domain communication;
1099
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_UART ` enable UART backend for multi-domain communication;
1100
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_LOG_LEVEL ` set the log level for multi-domain operations;
1101
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_MESSAGE_SIZE ` maximum message size for multi-domain
1102
+ channels;
1103
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_CHANNEL_NAME_SIZE ` maximum size of channel names in
1104
+ multi-domain communication;
1105
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_PROXY_STACK_SIZE ` stack size for proxy agent threads;
1106
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_PROXY_PRIORITY ` priority of proxy agent threads;
1107
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_SENT_MSG_POOL_SIZE ` number of sent messages to track for
1108
+ acknowledgments;
1109
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_MAX_TRANSMIT_ATTEMPTS ` maximum retry attempts for message
1110
+ transmission;
1111
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_SENT_MSG_ACK_TIMEOUT ` initial acknowledgment timeout for
1112
+ sent messages;
1113
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_SENT_MSG_ACK_TIMEOUT_MAX ` maximum acknowledgment timeout
1114
+ for exponential backoff;
1115
+ * :kconfig:option: `CONFIG_ZBUS_MULTIDOMAIN_UART_BUF_COUNT ` number of UART buffers for multi-domain
1116
+ communication;
957
1117
958
1118
API Reference
959
1119
*************
0 commit comments