Skip to content

Commit 259c569

Browse files
samples: zbus: add ZBus multidomain IPC forwarder sample
Add sample application demonstrating ZBus multidomain communication over IPC between CPU cores. Shows practical usage of shadow channels and proxy agents for inter-core message forwarding. The sample consists of two applications: - CPUAPP: Acts as request publisher with master request_channel - CPURAD: Acts as request listener/responder with shadow request_channel CPUAPP publishes periodic requests which are automatically forwarded via IPC to CPURAD. CPURAD processes requests and sends responses back through the response_channel, demonstrating bidirectional multidomain zbus communication. Key features demonstrated: - ZBUS_MULTIDOMAIN_CHAN_DEFINE for shared conditional channel definitions - ZBUS_PROXY_AGENT_DEFINE for IPC backend configuration - Shadow vs master channel behavior across CPU cores - Automatic message forwarding via proxy agents - Sysbuild configuration for multi-core applications Supports nRF5340DK and nRF54H20DK platforms with appropriate device tree overlays for IPC configuration. Signed-off-by: Trond F. Christiansen <[email protected]>
1 parent b4cf9b8 commit 259c569

21 files changed

+580
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
cmake_minimum_required(VERSION 3.20.0)
8+
9+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
10+
project(zbus_ipc_forwarder)
11+
12+
zephyr_library_include_directories(
13+
src
14+
common
15+
)
16+
17+
# Define which device this is
18+
zephyr_compile_definitions(ZBUS_DEVICE_A=1)
19+
20+
target_sources(app PRIVATE src/main.c)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
source "Kconfig.zephyr"
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
source "share/sysbuild/Kconfig"
8+
9+
choice
10+
prompt "Remote board target"
11+
default REMOTE_BOARD_NRF54H20_CPURAD if BOARD = "nrf54h20dk"
12+
default REMOTE_BOARD_NRF5340_CPUNET if BOARD = "nrf5340dk"
13+
14+
config REMOTE_BOARD_NRF54H20_CPURAD
15+
bool "nrf54h20dk/nrf54h20/cpurad"
16+
17+
config REMOTE_BOARD_NRF54H20_CPUPPR
18+
bool "nrf54h20dk/nrf54h20/cpuppr"
19+
20+
config REMOTE_BOARD_NRF54H20_CPUPPR_XIP
21+
bool "nrf54h20dk/nrf54h20/cpuppr/xip"
22+
23+
## Do not fit on nRF54H20_CPUFLPR without XIP
24+
25+
config REMOTE_BOARD_NRF54H20_CPUFLPR_XIP
26+
bool "nrf54h20dk/nrf54h20/cpuflpr/xip"
27+
28+
config REMOTE_BOARD_NRF5340_CPUNET
29+
bool "nrf5340dk/nrf5340/cpunet"
30+
31+
endchoice
32+
33+
config REMOTE_BOARD
34+
string "The board used for remote target"
35+
default "nrf54h20dk/nrf54h20/cpurad" if REMOTE_BOARD_NRF54H20_CPURAD
36+
default "nrf54h20dk/nrf54h20/cpuppr" if REMOTE_BOARD_NRF54H20_CPUPPR
37+
default "nrf54h20dk/nrf54h20/cpuppr/xip" if REMOTE_BOARD_NRF54H20_CPUPPR_XIP
38+
default "nrf54h20dk/nrf54h20/cpuflpr/xip" if REMOTE_BOARD_NRF54H20_CPUFLPR_XIP
39+
default "nrf5340dk/nrf5340/cpunet" if REMOTE_BOARD_NRF5340_CPUNET
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright (c) 2025 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
3+
4+
CONFIG_SOC_NRF53_CPUNET_ENABLE=y
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
4+
*/
5+
6+
&cpuapp_bellboard {
7+
status = "okay";
8+
};
9+
10+
/ {
11+
chosen {
12+
/delete-property/ zephyr,bt-hci;
13+
};
14+
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
4+
*/
5+
6+
/* Setup for cpuapp_cpuflpr_ipc */
7+
&cpuapp_bellboard {
8+
status = "okay";
9+
};
10+
11+
/delete-node/ &cpuapp_cpurad_ipc;
12+
13+
ipc0: &cpuapp_cpuflpr_ipc {
14+
status = "okay";
15+
};
16+
17+
&cpuflpr_vevif {
18+
status = "okay";
19+
};
20+
21+
/ {
22+
chosen {
23+
/delete-property/ zephyr,bt-hci;
24+
};
25+
};
26+
27+
/* Necessary for the cpuflpr_xip to work */
28+
&cpuflpr_vpr {
29+
status = "okay";
30+
execution-memory = <&cpuflpr_code_partition>;
31+
/delete-property/ source-memory;
32+
};
33+
34+
&uart120 {
35+
status = "reserved";
36+
interrupt-parent = <&cpuflpr_clic>;
37+
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
4+
*/
5+
6+
/* Setup for cpuapp_cpuppr_ipc */
7+
&cpuapp_bellboard {
8+
status = "okay";
9+
};
10+
11+
/delete-node/ &cpuapp_cpurad_ipc;
12+
13+
ipc0: &cpuapp_cpuppr_ipc {
14+
status = "okay";
15+
};
16+
17+
&cpuppr_vevif {
18+
status = "okay";
19+
};
20+
21+
/ {
22+
chosen {
23+
/delete-property/ zephyr,bt-hci;
24+
};
25+
};
26+
27+
/* Necessary for the cpuppr to work */
28+
&cpuppr_vpr {
29+
status = "okay";
30+
};
31+
32+
&cpuppr_ram3x_region {
33+
status = "okay";
34+
};
35+
36+
&uart135 {
37+
status = "reserved";
38+
};
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
4+
*/
5+
6+
/* Setup for cpuapp_cpuppr_ipc */
7+
&cpuapp_bellboard {
8+
status = "okay";
9+
};
10+
11+
/delete-node/ &cpuapp_cpurad_ipc;
12+
13+
ipc0: &cpuapp_cpuppr_ipc {
14+
status = "okay";
15+
};
16+
17+
&cpuppr_vevif {
18+
status = "okay";
19+
};
20+
21+
/ {
22+
chosen {
23+
/delete-property/ zephyr,bt-hci;
24+
};
25+
};
26+
27+
/* Necessary for the cpuppr_xip to work */
28+
&cpuppr_vpr {
29+
status = "okay";
30+
execution-memory = <&cpuppr_code_partition>;
31+
/delete-property/ source-memory;
32+
};
33+
34+
&cpuppr_ram3x_region {
35+
status = "okay";
36+
};
37+
38+
&uart135 {
39+
status = "reserved";
40+
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#ifndef COMMON_H
2+
#define COMMON_H
3+
4+
#include <zephyr/zbus/zbus.h>
5+
6+
/* Sample data structures for request and response */
7+
struct request_data {
8+
int request_id;
9+
int min_value;
10+
int max_value;
11+
};
12+
13+
struct response_data {
14+
int response_id;
15+
int value;
16+
};
17+
18+
/* Conditional compilation for device-specific code, needed if channels should be included on a
19+
* subset of applications devices
20+
*/
21+
#if defined(ZBUS_DEVICE_A) || defined(ZBUS_DEVICE_B)
22+
#define include_on_device_a_b 1
23+
#else
24+
#define include_on_device_a_b 0
25+
#endif
26+
27+
/* Define shared channels for request and response
28+
* request_channel is master on device A and shadow on device B
29+
* response_channel is shadow on device A and master on device B
30+
*/
31+
ZBUS_MULTIDOMAIN_CHAN_DEFINE(request_channel, struct request_data, NULL, NULL, ZBUS_OBSERVERS_EMPTY,
32+
ZBUS_MSG_INIT(0), IS_ENABLED(ZBUS_DEVICE_A), include_on_device_a_b);
33+
34+
ZBUS_MULTIDOMAIN_CHAN_DEFINE(response_channel, struct response_data, NULL, NULL,
35+
ZBUS_OBSERVERS_EMPTY, ZBUS_MSG_INIT(0), IS_ENABLED(ZBUS_DEVICE_B),
36+
include_on_device_a_b);
37+
38+
#endif /* COMMON_H */
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright (c) 2025 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
3+
4+
5+
CONFIG_LOG=y
6+
# CONFIG_LOG_MODE_MINIMAL=y
7+
CONFIG_LOG_DBG_COLOR_BLUE=y
8+
9+
CONFIG_HEAP_MEM_POOL_SIZE=4096
10+
11+
CONFIG_ZBUS=y
12+
13+
CONFIG_MBOX=y
14+
CONFIG_IPC_SERVICE=y
15+
16+
CONFIG_ZBUS_MULTIDOMAIN=y
17+
CONFIG_ZBUS_MULTIDOMAIN_IPC=y
18+
CONFIG_ZBUS_MULTIDOMAIN_LOG_LEVEL_INF=y
19+
20+
# Increase the size of the receive buffer to accommodate larger messages
21+
CONFIG_PBUF_RX_READ_BUF_SIZE=384

0 commit comments

Comments
 (0)