6#ifndef ZEPHYR_INCLUDE_ZBUS_H_
7#define ZEPHYR_INCLUDE_ZBUS_H_
46#if defined(CONFIG_ZBUS_PRIORITY_BOOST)
50 int highest_observer_priority;
53#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
60#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION) || defined(__DOXYGEN__)
66#if defined(CONFIG_ZBUS_CHANNEL_PUBLISH_STATS) || defined(__DOXYGEN__)
81#if defined(CONFIG_ZBUS_CHANNEL_NAME) || defined(__DOXYGEN__)
85#if defined(CONFIG_ZBUS_CHANNEL_ID) || defined(__DOXYGEN__)
127#if defined(CONFIG_ZBUS_PRIORITY_BOOST)
149#if defined(CONFIG_ZBUS_OBSERVER_NAME) || defined(__DOXYGEN__)
166#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) || defined(__DOXYGEN__)
176struct zbus_channel_observation_mask {
183struct zbus_channel_observation {
189#define _ZBUS_CPP_EXTERN extern
191#define _ZBUS_CPP_EXTERN
194#define ZBUS_MIN_THREAD_PRIORITY (CONFIG_NUM_PREEMPT_PRIORITIES - 1)
196#if defined(CONFIG_ZBUS_ASSERT_MOCK)
197#define _ZBUS_ASSERT(_cond, _fmt, ...) \
200 printk("ZBUS ASSERT: "); \
201 printk(_fmt, ##__VA_ARGS__); \
207#define _ZBUS_ASSERT(_cond, _fmt, ...) __ASSERT(_cond, _fmt, ##__VA_ARGS__)
210#if defined(CONFIG_ZBUS_CHANNEL_NAME)
211#define ZBUS_CHANNEL_NAME_INIT(_name) .name = #_name,
212#define _ZBUS_CHAN_NAME(_chan) (_chan)->name
214#define ZBUS_CHANNEL_NAME_INIT(_name)
215#define _ZBUS_CHAN_NAME(_chan) ""
218#if defined(CONFIG_ZBUS_OBSERVER_NAME)
219#define ZBUS_OBSERVER_NAME_INIT(_name) .name = #_name,
220#define _ZBUS_OBS_NAME(_obs) (_obs)->name
222#define ZBUS_OBSERVER_NAME_INIT(_name)
223#define _ZBUS_OBS_NAME(_obs) ""
226#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS)
227#define ZBUS_RUNTIME_OBSERVERS_LIST_DECL(_slist_name) static sys_slist_t _slist_name
228#define ZBUS_RUNTIME_OBSERVERS_LIST_INIT(_slist_name) .runtime_observers = &_slist_name,
230#define ZBUS_RUNTIME_OBSERVERS_LIST_DECL(_slist_name)
231#define ZBUS_RUNTIME_OBSERVERS_LIST_INIT(_slist_name)
234#define _ZBUS_OBS_EXTERN(_name) extern const struct zbus_observer _name
236#define _ZBUS_CHAN_EXTERN(_name) extern const struct zbus_channel _name
238#define ZBUS_REF(_value) &(_value)
240#define FOR_EACH_FIXED_ARG_NONEMPTY_TERM(F, sep, fixed_arg, ...) \
242 NUM_VA_ARGS_LESS_1( \
243 LIST_DROP_EMPTY(__VA_ARGS__, _)), \
245 (FOR_EACH_IDX_FIXED_ARG( \
247 LIST_DROP_EMPTY(__VA_ARGS__)) \
250#define _ZBUS_OBSERVATION_PREFIX(_idx) \
251 GET_ARG_N(_idx, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, \
252 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, \
253 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, \
254 58, 59, 60, 61, 62, 63)
256#define _ZBUS_CHAN_OBSERVATION(_idx, _obs, _chan) \
257 const STRUCT_SECTION_ITERABLE( \
258 zbus_channel_observation, \
259 _CONCAT(_chan, _ZBUS_OBSERVATION_PREFIX(UTIL_INC(_idx)))) = {.chan = &_chan, \
261 STRUCT_SECTION_ITERABLE(zbus_channel_observation_mask, \
262 _CONCAT(_CONCAT(_chan, _ZBUS_OBSERVATION_PREFIX(UTIL_INC(_idx))), \
263 _mask)) = {.enabled = false};
265#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
266#define _ZBUS_RUNTIME_OBSERVERS(_name) .observers = &(_CONCAT(_observers_, _name)),
267#define _ZBUS_RUNTIME_OBSERVERS_DECL(_name) static sys_slist_t _CONCAT(_observers_, _name);
269#define _ZBUS_RUNTIME_OBSERVERS(_name)
270#define _ZBUS_RUNTIME_OBSERVERS_DECL(_name)
273#define _ZBUS_MESSAGE_NAME(_name) _CONCAT(_zbus_message_, _name)
276#define _ZBUS_CHAN_DEFINE(_name, _id, _type, _validator, _user_data) \
277 static struct zbus_channel_data _CONCAT(_zbus_chan_data_, _name) = { \
278 .observers_start_idx = -1, \
279 .observers_end_idx = -1, \
280 .sem = Z_SEM_INITIALIZER(_CONCAT(_zbus_chan_data_, _name).sem, 1, 1), \
281 IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, \
282 (.highest_observer_priority = ZBUS_MIN_THREAD_PRIORITY,)) \
283 IF_ENABLED(CONFIG_ZBUS_RUNTIME_OBSERVERS, \
284 (.observers = SYS_SLIST_STATIC_INIT( \
285 &_CONCAT(_zbus_chan_data_, _name).observers),)) \
287 static K_MUTEX_DEFINE(_CONCAT(_zbus_mutex_, _name)); \
288 _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_channel, _name) = { \
289 ZBUS_CHANNEL_NAME_INIT(_name) \
290 IF_ENABLED(CONFIG_ZBUS_CHANNEL_ID, (.id = _id,)) \
291 .message = &_ZBUS_MESSAGE_NAME(_name), \
292 .message_size = sizeof(_type), \
293 .user_data = _user_data, \
294 .validator = _validator, \
295 .data = &_CONCAT(_zbus_chan_data_, _name), \
296 IF_ENABLED(ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION, \
297 (.msg_subscriber_pool = &_zbus_msg_subscribers_pool,)) \
316#define ZBUS_CHAN_ADD_OBS_WITH_MASK(_chan, _obs, _masked, _prio) \
317 const STRUCT_SECTION_ITERABLE(zbus_channel_observation, \
318 _CONCAT(_CONCAT(_chan, zz), _CONCAT(_prio, _obs))) = { \
322 STRUCT_SECTION_ITERABLE(zbus_channel_observation_mask, \
323 _CONCAT(_CONCAT(_CONCAT(_chan, zz), _CONCAT(_prio, _obs)), \
324 _mask)) = {.enabled = _masked}
316#define ZBUS_CHAN_ADD_OBS_WITH_MASK(_chan, _obs, _masked, _prio) \ …
337#define ZBUS_CHAN_ADD_OBS(_chan, _obs, _prio) ZBUS_CHAN_ADD_OBS_WITH_MASK(_chan, _obs, false, _prio)
344#define ZBUS_OBS_DECLARE(...) FOR_EACH_NONEMPTY_TERM(_ZBUS_OBS_EXTERN, (;), __VA_ARGS__)
351#define ZBUS_CHAN_DECLARE(...) FOR_EACH(_ZBUS_CHAN_EXTERN, (;), __VA_ARGS__)
357#define ZBUS_OBSERVERS_EMPTY
364#define ZBUS_OBSERVERS(...) __VA_ARGS__
370#define ZBUS_CHAN_ID_INVALID UINT32_MAX
387#define ZBUS_CHAN_DEFINE(_name, _type, _validator, _user_data, _observers, _init_val) \
388 static _type _ZBUS_MESSAGE_NAME(_name) = _init_val; \
389 _ZBUS_CHAN_DEFINE(_name, ZBUS_CHAN_ID_INVALID, _type, _validator, _user_data); \
391 ZBUS_OBS_DECLARE(_observers); \
393 FOR_EACH_FIXED_ARG_NONEMPTY_TERM(_ZBUS_CHAN_OBSERVATION, (;), _name, _observers)
387#define ZBUS_CHAN_DEFINE(_name, _type, _validator, _user_data, _observers, _init_val) \ …
411#define ZBUS_CHAN_DEFINE_WITH_ID(_name, _id, _type, _validator, _user_data, _observers, _init_val) \
412 static _type _ZBUS_MESSAGE_NAME(_name) = _init_val; \
413 _ZBUS_CHAN_DEFINE(_name, _id, _type, _validator, _user_data); \
415 ZBUS_OBS_DECLARE(_observers); \
417 FOR_EACH_FIXED_ARG_NONEMPTY_TERM(_ZBUS_CHAN_OBSERVATION, (;), _name, _observers)
411#define ZBUS_CHAN_DEFINE_WITH_ID(_name, _id, _type, _validator, _user_data, _observers, _init_val) \ …
428#define ZBUS_MSG_INIT(_val, ...) {_val, ##__VA_ARGS__}
443#define ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, _enable) \
444 K_MSGQ_DEFINE(_zbus_observer_queue_##_name, \
445 sizeof(struct zbus_channel *), \
446 _queue_size, sizeof(struct zbus_channel *) \
448 static struct zbus_observer_data _CONCAT(_zbus_obs_data_, _name) = { \
449 .enabled = _enable, \
450 IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
451 .priority = ZBUS_MIN_THREAD_PRIORITY, \
454 _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \
455 ZBUS_OBSERVER_NAME_INIT(_name) \
456 .type = ZBUS_OBSERVER_SUBSCRIBER_TYPE, \
457 .data = &_CONCAT(_zbus_obs_data_, _name), \
458 .queue = &_zbus_observer_queue_##_name, \
443#define ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, _enable) \ …
473#define ZBUS_SUBSCRIBER_DEFINE(_name, _queue_size) \
474 ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, true)
473#define ZBUS_SUBSCRIBER_DEFINE(_name, _queue_size) \ …
489#define ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable) \
490 static struct zbus_observer_data _CONCAT(_zbus_obs_data_, _name) = { \
491 .enabled = _enable, \
492 IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
493 .priority = ZBUS_MIN_THREAD_PRIORITY, \
496 _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \
497 ZBUS_OBSERVER_NAME_INIT(_name) \
498 .type = ZBUS_OBSERVER_LISTENER_TYPE, \
499 .data = &_CONCAT(_zbus_obs_data_, _name), \
489#define ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable) \ …
514#define ZBUS_LISTENER_DEFINE(_name, _cb) ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, true)
528#define ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _enable) \
529 static K_FIFO_DEFINE(_zbus_observer_fifo_##_name); \
530 static struct zbus_observer_data _CONCAT(_zbus_obs_data_, _name) = { \
531 .enabled = _enable, \
532 IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
533 .priority = ZBUS_MIN_THREAD_PRIORITY, \
536 _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \
537 ZBUS_OBSERVER_NAME_INIT(_name) \
538 .type = ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE, \
539 .data = &_CONCAT(_zbus_obs_data_, _name), \
540 .message_fifo = &_zbus_observer_fifo_##_name, \
528#define ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _enable) \ …
555#define ZBUS_MSG_SUBSCRIBER_DEFINE(_name) ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, true)
657#if defined(CONFIG_ZBUS_CHANNEL_NAME) || defined(__DOXYGEN__)
670 __ASSERT(chan !=
NULL,
"chan is required");
677#if defined(CONFIG_ZBUS_CHANNEL_ID) || defined(__DOXYGEN__)
705 __ASSERT(chan !=
NULL,
"chan is required");
726 __ASSERT(chan !=
NULL,
"chan is required");
742 __ASSERT(chan !=
NULL,
"chan is required");
758 __ASSERT(chan !=
NULL,
"chan is required");
763#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION) || defined(__DOXYGEN__)
774 __ASSERT(chan !=
NULL,
"chan is required");
775 __ASSERT(pool !=
NULL,
"pool is required");
782#if defined(CONFIG_ZBUS_CHANNEL_PUBLISH_STATS) || defined(__DOXYGEN__)
797 __ASSERT(chan !=
NULL,
"chan is required");
814 __ASSERT(chan !=
NULL,
"chan is required");
830 __ASSERT(chan !=
NULL,
"chan is required");
846 __ASSERT(chan !=
NULL,
"chan is required");
865#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
874#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_NONE)
879#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_NONE) || defined(__DOXYGEN__)
915#if !defined(CONFIG_ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_NONE) || defined(__DOXYGEN__)
997 _ZBUS_ASSERT(obs !=
NULL,
"obs is required");
998 _ZBUS_ASSERT(enable !=
NULL,
"enable is required");
1037#if defined(CONFIG_ZBUS_OBSERVER_NAME) || defined(__DOXYGEN__)
1050 __ASSERT(obs !=
NULL,
"obs is required");
1057#if defined(CONFIG_ZBUS_PRIORITY_BOOST) || defined(__DOXYGEN__)
1104#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) || defined(__DOXYGEN__)
int64_t k_uptime_ticks(void)
Get system uptime, in system ticks.
uint32_t k_ticks_t
Tick precision used in timeout APIs.
Definition sys_clock.h:48
static int64_t k_uptime_get(void)
Get system uptime.
Definition kernel.h:1883
struct _slist sys_slist_t
Single-linked list structure.
Definition slist.h:49
struct _snode sys_snode_t
Single-linked list node structure.
Definition slist.h:39
#define ENOTSUP
Unsupported value.
Definition errno.h:114
int zbus_chan_claim(const struct zbus_channel *chan, k_timeout_t timeout)
Claim a channel.
static const char * zbus_chan_name(const struct zbus_channel *chan)
Get the channel's name.
Definition zbus.h:668
static uint32_t zbus_chan_pub_stats_avg_period(const struct zbus_channel *chan)
Get the average period between publishes to a channel.
Definition zbus.h:844
bool zbus_iterate_over_observers_with_user_data(bool(*iterator_func)(const struct zbus_observer *obs, void *user_data), void *user_data)
Iterate over observers with user data.
bool zbus_iterate_over_observers(bool(*iterator_func)(const struct zbus_observer *obs))
Iterate over observers.
static int zbus_obs_is_enabled(const struct zbus_observer *obs, bool *enable)
Get the observer state.
Definition zbus.h:995
static void zbus_chan_set_msg_sub_pool(const struct zbus_channel *chan, struct net_buf_pool *pool)
Set the channel's msg subscriber net_buf pool.
Definition zbus.h:771
int zbus_obs_is_chan_notification_masked(const struct zbus_observer *obs, const struct zbus_channel *chan, bool *masked)
Get the notifications masking state from a channel to an observer.
int zbus_obs_detach_from_thread(const struct zbus_observer *obs)
Clear the observer thread priority by detaching it from a thread.
static uint32_t zbus_chan_pub_stats_count(const struct zbus_channel *chan)
Get the number of times a channel has been published to.
Definition zbus.h:828
static const char * zbus_obs_name(const struct zbus_observer *obs)
Get the observer's name.
Definition zbus.h:1048
bool zbus_iterate_over_channels(bool(*iterator_func)(const struct zbus_channel *chan))
Iterate over channels.
int zbus_chan_notify(const struct zbus_channel *chan, k_timeout_t timeout)
Force a channel notification.
int zbus_chan_add_obs_with_node(const struct zbus_channel *chan, const struct zbus_observer *obs, struct zbus_observer_node *node, k_timeout_t timeout)
Add an observer to a channel.
int zbus_chan_finish(const struct zbus_channel *chan)
Finish a channel claim.
int zbus_chan_read(const struct zbus_channel *chan, void *msg, k_timeout_t timeout)
Read a channel.
int zbus_sub_wait(const struct zbus_observer *sub, const struct zbus_channel **chan, k_timeout_t timeout)
Wait for a channel notification.
zbus_observer_type
Type used to represent an observer type.
Definition zbus.h:117
static uint16_t zbus_chan_msg_size(const struct zbus_channel *chan)
Get the channel's message size.
Definition zbus.h:740
int zbus_obs_set_chan_notification_mask(const struct zbus_observer *obs, const struct zbus_channel *chan, bool masked)
Mask notifications from a channel to an observer.
int zbus_obs_set_enable(const struct zbus_observer *obs, bool enabled)
Change the observer state.
static void * zbus_chan_msg(const struct zbus_channel *chan)
Get the reference for a channel message directly.
Definition zbus.h:703
bool zbus_iterate_over_channels_with_user_data(bool(*iterator_func)(const struct zbus_channel *chan, void *user_data), void *user_data)
Iterate over channels with user data.
int zbus_obs_attach_to_thread(const struct zbus_observer *obs)
Set the observer thread priority by attaching it to a thread.
static void * zbus_chan_user_data(const struct zbus_channel *chan)
Get the channel's user data.
Definition zbus.h:756
static k_ticks_t zbus_chan_pub_stats_last_time(const struct zbus_channel *chan)
Get the time a channel was last published to.
Definition zbus.h:812
const struct zbus_channel * zbus_chan_from_id(uint32_t channel_id)
Retrieve a zbus channel from its numeric identifier.
int zbus_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observer *obs, k_timeout_t timeout)
Add an observer to a channel.
int zbus_chan_pub(const struct zbus_channel *chan, const void *msg, k_timeout_t timeout)
Publish to a channel.
int zbus_chan_rm_obs(const struct zbus_channel *chan, const struct zbus_observer *obs, k_timeout_t timeout)
Remove an observer from a channel.
static void zbus_chan_pub_stats_update(const struct zbus_channel *chan)
Update the publishing statistics for a channel.
Definition zbus.h:795
int zbus_sub_wait_msg(const struct zbus_observer *sub, const struct zbus_channel **chan, void *msg, k_timeout_t timeout)
Wait for a channel message.
static const void * zbus_chan_const_msg(const struct zbus_channel *chan)
Get a constant reference for a channel message directly.
Definition zbus.h:724
@ ZBUS_OBSERVER_LISTENER_TYPE
Definition zbus.h:118
@ ZBUS_OBSERVER_SUBSCRIBER_TYPE
Definition zbus.h:119
@ ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE
Definition zbus.h:120
#define NULL
Definition iar_missing_defs.h:20
#define bool
Definition stdbool.h:13
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__UINT16_TYPE__ uint16_t
Definition stdint.h:89
__INT16_TYPE__ int16_t
Definition stdint.h:73
Message Queue Structure.
Definition kernel.h:4597
Kernel timeout type.
Definition sys_clock.h:65
Network buffer pool representation.
Definition net_buf.h:1078
Type used to represent a channel mutable data.
Definition zbus.h:30
k_ticks_t publish_timestamp
Kernel timestamp of the last publish action on this channel.
Definition zbus.h:68
struct net_buf_pool * msg_subscriber_pool
Net buf pool for message subscribers.
Definition zbus.h:63
uint32_t publish_count
Number of times data has been published to this channel.
Definition zbus.h:70
int16_t observers_end_idx
Static channel observer list end index.
Definition zbus.h:39
int16_t observers_start_idx
Static channel observer list start index.
Definition zbus.h:34
struct k_sem sem
Access control semaphore.
Definition zbus.h:44
sys_slist_t observers
Channel observer list.
Definition zbus.h:57
Type used to represent a channel.
Definition zbus.h:80
void * user_data
User data available to extend zbus features.
Definition zbus.h:100
uint32_t id
Unique numeric channel identifier.
Definition zbus.h:87
struct zbus_channel_data * data
Mutable channel data struct.
Definition zbus.h:109
bool(* validator)(const void *msg, size_t msg_size)
Message validator.
Definition zbus.h:106
size_t message_size
Message size.
Definition zbus.h:95
const char * name
Channel name.
Definition zbus.h:83
void * message
Message reference.
Definition zbus.h:92
bool enabled
Enabled flag.
Definition zbus.h:125
Structure used to register runtime obeservers.
Definition zbus.h:871
const struct zbus_observer * obs
Definition zbus.h:873
sys_snode_t node
Definition zbus.h:872
Type used to represent an observer.
Definition zbus.h:148
enum zbus_observer_type type
Type indication.
Definition zbus.h:154
struct k_fifo * message_fifo
Observer message FIFO.
Definition zbus.h:170
struct zbus_observer_data * data
Mutable observer data struct.
Definition zbus.h:157
struct k_msgq * queue
Observer message queue.
Definition zbus.h:161
const char * name
Observer name.
Definition zbus.h:151