Zephyr API Documentation 4.3.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
zbus.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Rodrigo Peixoto <rodrigopex@gmail.com>
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#ifndef ZEPHYR_INCLUDE_ZBUS_H_
7#define ZEPHYR_INCLUDE_ZBUS_H_
8
9#include <string.h>
10
11#include <zephyr/kernel.h>
12#include <zephyr/sys/check.h>
14
15#ifdef __cplusplus
16extern "C" {
17#endif
18
27
38
43
47 struct k_sem sem;
48
49#if defined(CONFIG_ZBUS_PRIORITY_BOOST)
53 int highest_observer_priority;
54#endif /* CONFIG_ZBUS_PRIORITY_BOOST */
55
56#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
61#endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */
62
63#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION) || defined(__DOXYGEN__)
68#endif /* ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION */
69
70#if defined(CONFIG_ZBUS_CHANNEL_PUBLISH_STATS) || defined(__DOXYGEN__)
75#endif /* CONFIG_ZBUS_CHANNEL_PUBLISH_STATS */
76};
77
85#if defined(CONFIG_ZBUS_CHANNEL_NAME) || defined(__DOXYGEN__)
87 const char *name;
88#endif
89#if defined(CONFIG_ZBUS_CHANNEL_ID) || defined(__DOXYGEN__)
92#endif
96 void *message;
97
100
105
110 bool (*validator)(const void *msg, size_t msg_size);
111
114};
115
127
131
132#if defined(CONFIG_ZBUS_PRIORITY_BOOST)
134 int priority;
135#endif /* CONFIG_ZBUS_PRIORITY_BOOST */
136};
137
154#if defined(CONFIG_ZBUS_OBSERVER_NAME) || defined(__DOXYGEN__)
156 const char *name;
157#endif
160
163
164 union {
166 struct k_msgq *queue;
167
169 void (*callback)(const struct zbus_channel *chan);
170
171#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) || defined(__DOXYGEN__)
176#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */
177
178#if defined(CONFIG_ZBUS_ASYNC_LISTENER) || defined(__DOXYGEN__)
182 struct k_work *work;
183#endif /* CONFIG_ZBUS_ASYNC_LISTENER */
184 };
185};
186
188struct zbus_channel_observation_mask {
189 bool enabled;
190};
191
195struct zbus_channel_observation {
196 const struct zbus_channel *chan;
197 const struct zbus_observer *obs;
198};
199
200#ifdef __cplusplus
201#define _ZBUS_CPP_EXTERN extern
202#else
203#define _ZBUS_CPP_EXTERN
204#endif /* __cplusplus */
205
206#define ZBUS_MIN_THREAD_PRIORITY (CONFIG_NUM_PREEMPT_PRIORITIES - 1)
207
208#if defined(CONFIG_ZBUS_ASSERT_MOCK)
209#define _ZBUS_ASSERT(_cond, _fmt, ...) \
210 do { \
211 if (!(_cond)) { \
212 printk("ZBUS ASSERT: "); \
213 printk(_fmt, ##__VA_ARGS__); \
214 printk("\n"); \
215 return -EFAULT; \
216 } \
217 } while (0)
218#else
219#define _ZBUS_ASSERT(_cond, _fmt, ...) __ASSERT(_cond, _fmt, ##__VA_ARGS__)
220#endif
221
222#if defined(CONFIG_ZBUS_CHANNEL_NAME)
223#define ZBUS_CHANNEL_NAME_INIT(_name) .name = #_name,
224#define _ZBUS_CHAN_NAME(_chan) (_chan)->name
225#else
226#define ZBUS_CHANNEL_NAME_INIT(_name)
227#define _ZBUS_CHAN_NAME(_chan) ""
228#endif
229
230#if defined(CONFIG_ZBUS_OBSERVER_NAME)
231#define ZBUS_OBSERVER_NAME_INIT(_name) .name = #_name,
232#define _ZBUS_OBS_NAME(_obs) (_obs)->name
233#else
234#define ZBUS_OBSERVER_NAME_INIT(_name)
235#define _ZBUS_OBS_NAME(_obs) ""
236#endif
237
238#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS)
239#define ZBUS_RUNTIME_OBSERVERS_LIST_DECL(_slist_name) static sys_slist_t _slist_name
240#define ZBUS_RUNTIME_OBSERVERS_LIST_INIT(_slist_name) .runtime_observers = &_slist_name,
241#else
242#define ZBUS_RUNTIME_OBSERVERS_LIST_DECL(_slist_name)
243#define ZBUS_RUNTIME_OBSERVERS_LIST_INIT(_slist_name) /* No runtime observers */
244#endif
245
246#define _ZBUS_OBS_EXTERN(_name) extern const struct zbus_observer _name
247
248#define _ZBUS_CHAN_EXTERN(_name) extern const struct zbus_channel _name
249
250#define ZBUS_REF(_value) &(_value)
251
252#define FOR_EACH_FIXED_ARG_NONEMPTY_TERM(F, sep, fixed_arg, ...) \
253 COND_CODE_0(/* are there zero non-empty arguments ? */ \
254 NUM_VA_ARGS_LESS_1( \
255 LIST_DROP_EMPTY(__VA_ARGS__, _)), /* if so, expand to nothing */ \
256 (), /* otherwise, expand to: */ \
257 (FOR_EACH_IDX_FIXED_ARG( \
258 F, sep, fixed_arg, \
259 LIST_DROP_EMPTY(__VA_ARGS__)) /* plus a final terminator */ \
260 __DEBRACKET sep))
261
262#define _ZBUS_OBSERVATION_PREFIX(_idx) \
263 GET_ARG_N(_idx, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, \
264 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, \
265 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, \
266 58, 59, 60, 61, 62, 63)
267
268#define _ZBUS_CHAN_OBSERVATION(_idx, _obs, _chan) \
269 const STRUCT_SECTION_ITERABLE( \
270 zbus_channel_observation, \
271 _CONCAT(_chan, _ZBUS_OBSERVATION_PREFIX(UTIL_INC(_idx)))) = {.chan = &_chan, \
272 .obs = &_obs}; \
273 STRUCT_SECTION_ITERABLE(zbus_channel_observation_mask, \
274 _CONCAT(_CONCAT(_chan, _ZBUS_OBSERVATION_PREFIX(UTIL_INC(_idx))), \
275 _mask)) = {.enabled = false};
276
277#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
278#define _ZBUS_RUNTIME_OBSERVERS(_name) .observers = &(_CONCAT(_observers_, _name)),
279#define _ZBUS_RUNTIME_OBSERVERS_DECL(_name) static sys_slist_t _CONCAT(_observers_, _name);
280#else
281#define _ZBUS_RUNTIME_OBSERVERS(_name)
282#define _ZBUS_RUNTIME_OBSERVERS_DECL(_name)
283#endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */
284
285#define _ZBUS_MESSAGE_NAME(_name) _CONCAT(_zbus_message_, _name)
286
287/* clang-format off */
288#define _ZBUS_CHAN_DEFINE(_name, _id, _type, _validator, _user_data) \
289 static struct zbus_channel_data _CONCAT(_zbus_chan_data_, _name) = { \
290 .observers_start_idx = -1, \
291 .observers_end_idx = -1, \
292 .sem = Z_SEM_INITIALIZER(_CONCAT(_zbus_chan_data_, _name).sem, 1, 1), \
293 IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, \
294 (.highest_observer_priority = ZBUS_MIN_THREAD_PRIORITY,)) \
295 IF_ENABLED(CONFIG_ZBUS_RUNTIME_OBSERVERS, \
296 (.observers = SYS_SLIST_STATIC_INIT( \
297 &_CONCAT(_zbus_chan_data_, _name).observers),)) \
298 }; \
299 _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_channel, _name) = { \
300 ZBUS_CHANNEL_NAME_INIT(_name) /* Maybe removed */ \
301 IF_ENABLED(CONFIG_ZBUS_CHANNEL_ID, (.id = _id,)) \
302 .message = &_ZBUS_MESSAGE_NAME(_name), \
303 .message_size = sizeof(_type), \
304 .user_data = _user_data, \
305 .validator = _validator, \
306 .data = &_CONCAT(_zbus_chan_data_, _name), \
307 IF_ENABLED(ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION, \
308 (.msg_subscriber_pool = &_zbus_msg_subscribers_pool,)) \
309 }
310/* clang-format on */
311
313
314/* clang-format off */
315
327#define ZBUS_CHAN_ADD_OBS_WITH_MASK(_chan, _obs, _masked, _prio) \
328 const STRUCT_SECTION_ITERABLE(zbus_channel_observation, \
329 _CONCAT(_CONCAT(_chan, zz), _CONCAT(_prio, _obs))) = { \
330 .chan = &_chan, \
331 .obs = &_obs, \
332 }; \
333 STRUCT_SECTION_ITERABLE(zbus_channel_observation_mask, \
334 _CONCAT(_CONCAT(_CONCAT(_chan, zz), _CONCAT(_prio, _obs)), \
335 _mask)) = {.enabled = _masked}
336/* clang-format on */
337
348#define ZBUS_CHAN_ADD_OBS(_chan, _obs, _prio) ZBUS_CHAN_ADD_OBS_WITH_MASK(_chan, _obs, false, _prio)
349
355#define ZBUS_OBS_DECLARE(...) FOR_EACH_NONEMPTY_TERM(_ZBUS_OBS_EXTERN, (;), __VA_ARGS__)
356
362#define ZBUS_CHAN_DECLARE(...) FOR_EACH(_ZBUS_CHAN_EXTERN, (;), __VA_ARGS__)
363
368#define ZBUS_OBSERVERS_EMPTY
369
375#define ZBUS_OBSERVERS(...) __VA_ARGS__
376
381#define ZBUS_CHAN_ID_INVALID UINT32_MAX
382
398#define ZBUS_CHAN_DEFINE(_name, _type, _validator, _user_data, _observers, _init_val) \
399 static _type _ZBUS_MESSAGE_NAME(_name) = _init_val; \
400 _ZBUS_CHAN_DEFINE(_name, ZBUS_CHAN_ID_INVALID, _type, _validator, _user_data); \
401 /* Extern declaration of observers */ \
402 ZBUS_OBS_DECLARE(_observers); \
403 /* Create all channel observations from observers list */ \
404 FOR_EACH_FIXED_ARG_NONEMPTY_TERM(_ZBUS_CHAN_OBSERVATION, (;), _name, _observers)
405
422#define ZBUS_CHAN_DEFINE_WITH_ID(_name, _id, _type, _validator, _user_data, _observers, _init_val) \
423 static _type _ZBUS_MESSAGE_NAME(_name) = _init_val; \
424 _ZBUS_CHAN_DEFINE(_name, _id, _type, _validator, _user_data); \
425 /* Extern declaration of observers */ \
426 ZBUS_OBS_DECLARE(_observers); \
427 /* Create all channel observations from observers list */ \
428 FOR_EACH_FIXED_ARG_NONEMPTY_TERM(_ZBUS_CHAN_OBSERVATION, (;), _name, _observers)
429
439#define ZBUS_MSG_INIT(_val, ...) {_val, ##__VA_ARGS__}
440
441/* clang-format off */
442
454#define ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, _enable) \
455 K_MSGQ_DEFINE(_zbus_observer_queue_##_name, \
456 sizeof(struct zbus_channel *), \
457 _queue_size, sizeof(struct zbus_channel *) \
458 ); \
459 static struct zbus_observer_data _CONCAT(_zbus_obs_data_, _name) = { \
460 .enabled = _enable, \
461 IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
462 .priority = ZBUS_MIN_THREAD_PRIORITY, \
463 )) \
464 }; \
465 _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \
466 ZBUS_OBSERVER_NAME_INIT(_name) /* Name field */ \
467 .type = ZBUS_OBSERVER_SUBSCRIBER_TYPE, \
468 .data = &_CONCAT(_zbus_obs_data_, _name), \
469 .queue = &_zbus_observer_queue_##_name, \
470 }
471/* clang-format on */
472
484#define ZBUS_SUBSCRIBER_DEFINE(_name, _queue_size) \
485 ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, true)
486
487/* clang-format off */
488
500#define ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable) \
501 static struct zbus_observer_data _CONCAT(_zbus_obs_data_, _name) = { \
502 .enabled = _enable, \
503 IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
504 .priority = ZBUS_MIN_THREAD_PRIORITY, \
505 )) \
506 }; \
507 _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \
508 ZBUS_OBSERVER_NAME_INIT(_name) /* Name field */ \
509 .type = ZBUS_OBSERVER_LISTENER_TYPE, \
510 .data = &_CONCAT(_zbus_obs_data_, _name), \
511 .callback = (_cb) \
512 }
513/* clang-format on */
514
525#define ZBUS_LISTENER_DEFINE(_name, _cb) ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, true)
526
527/* clang-format off */
528
539#define ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _enable) \
540 static K_FIFO_DEFINE(_zbus_observer_fifo_##_name); \
541 static struct zbus_observer_data _CONCAT(_zbus_obs_data_, _name) = { \
542 .enabled = _enable, \
543 IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
544 .priority = ZBUS_MIN_THREAD_PRIORITY, \
545 )) \
546 }; \
547 _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \
548 ZBUS_OBSERVER_NAME_INIT(_name) /* Name field */ \
549 .type = ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE, \
550 .data = &_CONCAT(_zbus_obs_data_, _name), \
551 .message_fifo = &_zbus_observer_fifo_##_name, \
552 }
553/* clang-format on */
554
566#define ZBUS_MSG_SUBSCRIBER_DEFINE(_name) ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, true)
567
568#if defined(CONFIG_ZBUS_ASYNC_LISTENER)
570struct zbus_async_listener_work {
571 struct k_work work;
572 struct k_fifo *message_fifo;
573 struct k_work_q *queue;
574 void (*callback)(const struct zbus_channel *chan, const void *msg);
575};
576
577void async_listener_work_handler(struct k_work *item);
579
580/* clang-format off */
594#define ZBUS_ASYNC_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable) \
595 static K_FIFO_DEFINE(_zbus_observer_work_fifo_##_name); \
596 static struct zbus_async_listener_work _zbus_observer_work_##_name = { \
597 .work = Z_WORK_INITIALIZER(async_listener_work_handler), \
598 .message_fifo = &_CONCAT(_zbus_observer_work_fifo_, _name), \
599 .queue = &k_sys_work_q, \
600 .callback = _cb, \
601 }; \
602 static struct zbus_observer_data _CONCAT(_zbus_obs_data_, _name) = { \
603 .enabled = _enable, \
604 IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
605 .priority = ZBUS_MIN_THREAD_PRIORITY, \
606 )) \
607 }; \
608 _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \
609 ZBUS_OBSERVER_NAME_INIT(_name) /* Name field */ \
610 .type = ZBUS_OBSERVER_ASYNC_LISTENER_TYPE, \
611 .data = &_CONCAT(_zbus_obs_data_, _name), \
612 .work = &_CONCAT(_zbus_observer_work_, _name).work, \
613 }
614
627#define ZBUS_ASYNC_LISTENER_DEFINE(_name, _cb) \
628 ZBUS_ASYNC_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, true)
629/* clang-format on */
630
647static inline int zbus_async_listener_set_work_queue(const struct zbus_observer *obs,
648 struct k_work_q *queue)
649{
650 CHECKIF(obs == NULL) {
651 return -EINVAL;
652 }
653
655 return -EINVAL;
656 }
657
658 CHECKIF(queue == NULL) {
659 return -EINVAL;
660 }
661
662 static struct k_spinlock zbus_async_listener_slock;
663
664 K_SPINLOCK(&zbus_async_listener_slock) {
665 struct zbus_async_listener_work *async_listener =
666 CONTAINER_OF(obs->work, struct zbus_async_listener_work, work);
667
668 async_listener->queue = queue;
669 }
670 return 0;
671}
672
673#endif /* CONFIG_ZBUS_ASYNC_LISTENER */
674
696int zbus_chan_pub(const struct zbus_channel *chan, const void *msg, k_timeout_t timeout);
697
715int zbus_chan_read(const struct zbus_channel *chan, void *msg, k_timeout_t timeout);
716
738int zbus_chan_claim(const struct zbus_channel *chan, k_timeout_t timeout);
739
754int zbus_chan_finish(const struct zbus_channel *chan);
755
774int zbus_chan_notify(const struct zbus_channel *chan, k_timeout_t timeout);
775
776#if defined(CONFIG_ZBUS_CHANNEL_NAME) || defined(__DOXYGEN__)
777
787static inline const char *zbus_chan_name(const struct zbus_channel *chan)
788{
789 __ASSERT(chan != NULL, "chan is required");
790
791 return chan->name;
792}
793
794#endif
795
796#if defined(CONFIG_ZBUS_CHANNEL_ID) || defined(__DOXYGEN__)
797
806const struct zbus_channel *zbus_chan_from_id(uint32_t channel_id);
807
808#endif
809
810#if defined(CONFIG_ZBUS_CHANNEL_NAME) || defined(__DOXYGEN__)
811
820const struct zbus_channel *zbus_chan_from_name(const char *name);
821
822#endif
823
836static inline void *zbus_chan_msg(const struct zbus_channel *chan)
837{
838 __ASSERT(chan != NULL, "chan is required");
839
840 return chan->message;
841}
842
857static inline const void *zbus_chan_const_msg(const struct zbus_channel *chan)
858{
859 __ASSERT(chan != NULL, "chan is required");
860
861 return chan->message;
862}
863
873static inline uint16_t zbus_chan_msg_size(const struct zbus_channel *chan)
874{
875 __ASSERT(chan != NULL, "chan is required");
876
877 return chan->message_size;
878}
879
889static inline void *zbus_chan_user_data(const struct zbus_channel *chan)
890{
891 __ASSERT(chan != NULL, "chan is required");
892
893 return chan->user_data;
894}
895
896#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION) || defined(__DOXYGEN__)
897
904static inline void zbus_chan_set_msg_sub_pool(const struct zbus_channel *chan,
905 struct net_buf_pool *pool)
906{
907 __ASSERT(chan != NULL, "chan is required");
908 __ASSERT(pool != NULL, "pool is required");
909
910 chan->data->msg_subscriber_pool = pool;
911}
912
913#endif /* ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION */
914
915#if defined(CONFIG_ZBUS_CHANNEL_PUBLISH_STATS) || defined(__DOXYGEN__)
916
928static inline void zbus_chan_pub_stats_update(const struct zbus_channel *chan)
929{
930 __ASSERT(chan != NULL, "chan is required");
931
933 chan->data->publish_count += 1;
934}
935
945static inline k_ticks_t zbus_chan_pub_stats_last_time(const struct zbus_channel *chan)
946{
947 __ASSERT(chan != NULL, "chan is required");
948
949 return chan->data->publish_timestamp;
950}
951
961static inline uint32_t zbus_chan_pub_stats_count(const struct zbus_channel *chan)
962{
963 __ASSERT(chan != NULL, "chan is required");
964
965 return chan->data->publish_count;
966}
967
977static inline uint32_t zbus_chan_pub_stats_avg_period(const struct zbus_channel *chan)
978{
979 __ASSERT(chan != NULL, "chan is required");
980
981 /* Not yet published, period = 0ms */
982 if (chan->data->publish_count == 0) {
983 return 0;
984 }
985 /* Average period across application runtime */
986 return k_uptime_get() / chan->data->publish_count;
987}
988
997static inline uint64_t zbus_chan_pub_stats_msg_age(const struct zbus_channel *chan)
998{
999 if (zbus_chan_pub_stats_count(chan) == 0) {
1000 return UINT64_MAX;
1001 }
1003}
1004
1005#else
1006
1007static inline void zbus_chan_pub_stats_update(const struct zbus_channel *chan)
1008{
1009 (void)chan;
1010}
1011
1012#endif /* CONFIG_ZBUS_CHANNEL_PUBLISH_STATS */
1013
1014#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
1015
1022 const struct zbus_observer *obs;
1023#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_NONE)
1024 const struct zbus_channel *chan;
1025#endif
1026};
1027
1028#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_NONE) || defined(__DOXYGEN__)
1048int zbus_chan_add_obs_with_node(const struct zbus_channel *chan, const struct zbus_observer *obs,
1049 struct zbus_observer_node *node, k_timeout_t timeout);
1050#else
1051static inline int zbus_chan_add_obs_with_node(const struct zbus_channel *chan,
1052 const struct zbus_observer *obs,
1053 struct zbus_observer_node *node, k_timeout_t timeout)
1054{
1055 ARG_UNUSED(chan);
1056 ARG_UNUSED(obs);
1057 ARG_UNUSED(node);
1058 ARG_UNUSED(timeout);
1059
1060 return -ENOTSUP;
1061}
1062#endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_NONE */
1063
1064#if !defined(CONFIG_ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_NONE) || defined(__DOXYGEN__)
1085int zbus_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observer *obs,
1086 k_timeout_t timeout);
1087#else
1088static inline int zbus_chan_add_obs(const struct zbus_channel *chan,
1089 const struct zbus_observer *obs, k_timeout_t timeout)
1090{
1091 ARG_UNUSED(chan);
1092 ARG_UNUSED(obs);
1093 ARG_UNUSED(timeout);
1094
1095 return -ENOTSUP;
1096}
1097
1098#endif /* !CONFIG_ZBUS_RUNTIME_OBSERVERS_NODE_ALLOC_NONE */
1114int zbus_chan_rm_obs(const struct zbus_channel *chan, const struct zbus_observer *obs,
1115 k_timeout_t timeout);
1116
1117#endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */
1118
1132int zbus_obs_set_enable(const struct zbus_observer *obs, bool enabled);
1133
1144static inline int zbus_obs_is_enabled(const struct zbus_observer *obs, bool *enable)
1145{
1146 _ZBUS_ASSERT(obs != NULL, "obs is required");
1147 _ZBUS_ASSERT(enable != NULL, "enable is required");
1148
1149 *enable = obs->data->enabled;
1150
1151 return 0;
1152}
1153
1169 const struct zbus_channel *chan, bool masked);
1170
1184 const struct zbus_channel *chan, bool *masked);
1185
1186#if defined(CONFIG_ZBUS_OBSERVER_NAME) || defined(__DOXYGEN__)
1187
1197static inline const char *zbus_obs_name(const struct zbus_observer *obs)
1198{
1199 __ASSERT(obs != NULL, "obs is required");
1200
1201 return obs->name;
1202}
1203
1204#endif
1205
1206#if defined(CONFIG_ZBUS_PRIORITY_BOOST) || defined(__DOXYGEN__)
1207
1218
1229
1230#endif /* CONFIG_ZBUS_PRIORITY_BOOST */
1231
1250int zbus_sub_wait(const struct zbus_observer *sub, const struct zbus_channel **chan,
1251 k_timeout_t timeout);
1252
1253#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) || defined(__DOXYGEN__)
1254
1273int zbus_sub_wait_msg(const struct zbus_observer *sub, const struct zbus_channel **chan, void *msg,
1274 k_timeout_t timeout);
1275
1276#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */
1277
1291bool zbus_iterate_over_channels(bool (*iterator_func)(const struct zbus_channel *chan));
1307 bool (*iterator_func)(const struct zbus_channel *chan, void *user_data), void *user_data);
1308
1322bool zbus_iterate_over_observers(bool (*iterator_func)(const struct zbus_observer *obs));
1338 bool (*iterator_func)(const struct zbus_observer *obs, void *user_data), void *user_data);
1339
1343
1344#ifdef __cplusplus
1345}
1346#endif
1347
1348#endif /* ZEPHYR_INCLUDE_ZBUS_H_ */
#define CHECKIF(expr)
Definition check.h:21
int64_t k_uptime_ticks(void)
Get system uptime, in system ticks.
uint32_t k_ticks_t
Tick precision used in timeout APIs.
Definition clock.h:48
static int64_t k_uptime_get(void)
Get system uptime.
Definition kernel.h:2083
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 K_SPINLOCK(lck)
Guards a code block with the given spinlock, automatically acquiring the lock before executing the co...
Definition spinlock.h:441
#define CONTAINER_OF(ptr, type, field)
Get a pointer to a structure containing the element.
Definition util.h:281
#define EINVAL
Invalid argument.
Definition errno.h:60
#define ENOTSUP
Unsupported value.
Definition errno.h:114
#define k_ticks_to_ms_floor64(t)
Convert ticks to milliseconds.
Definition time_units.h:1723
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:787
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:977
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:1144
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:904
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.
const struct zbus_channel * zbus_chan_from_name(const char *name)
Retrieve a zbus channel from its name string.
static uint64_t zbus_chan_pub_stats_msg_age(const struct zbus_channel *chan)
Get the age of a message in a channel.
Definition zbus.h:997
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:961
static const char * zbus_obs_name(const struct zbus_observer *obs)
Get the observer's name.
Definition zbus.h:1197
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:121
static uint16_t zbus_chan_msg_size(const struct zbus_channel *chan)
Get the channel's message size.
Definition zbus.h:873
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:836
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:889
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:945
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:928
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:857
@ ZBUS_OBSERVER_LISTENER_TYPE
Definition zbus.h:122
@ ZBUS_OBSERVER_ASYNC_LISTENER_TYPE
Definition zbus.h:125
@ ZBUS_OBSERVER_SUBSCRIBER_TYPE
Definition zbus.h:123
@ ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE
Definition zbus.h:124
#define NULL
Definition iar_missing_defs.h:20
Public kernel APIs.
#define bool
Definition stdbool.h:13
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__UINT64_TYPE__ uint64_t
Definition stdint.h:91
#define UINT64_MAX
Definition stdint.h:30
__UINT16_TYPE__ uint16_t
Definition stdint.h:89
__INT16_TYPE__ int16_t
Definition stdint.h:73
Definition kernel.h:2806
Message Queue Structure.
Definition kernel.h:5004
Semaphore structure.
Definition kernel.h:3541
Kernel Spin Lock.
Definition spinlock.h:45
Kernel timeout type.
Definition clock.h:65
A structure used to hold work until it can be processed.
Definition kernel.h:4599
A structure used to submit work.
Definition kernel.h:4437
Network buffer pool representation.
Definition net_buf.h:1079
Type used to represent a channel mutable data.
Definition zbus.h:33
k_ticks_t publish_timestamp
Kernel timestamp of the last publish action on this channel.
Definition zbus.h:72
struct net_buf_pool * msg_subscriber_pool
Net buf pool for message subscribers and async listeners.
Definition zbus.h:67
uint32_t publish_count
Number of times data has been published to this channel.
Definition zbus.h:74
int16_t observers_end_idx
Static channel observer list end index.
Definition zbus.h:42
int16_t observers_start_idx
Static channel observer list start index.
Definition zbus.h:37
struct k_sem sem
Access control semaphore.
Definition zbus.h:47
sys_slist_t observers
Channel observer list.
Definition zbus.h:60
Type used to represent a channel.
Definition zbus.h:84
void * user_data
User data available to extend zbus features.
Definition zbus.h:104
uint32_t id
Unique numeric channel identifier.
Definition zbus.h:91
struct zbus_channel_data * data
Mutable channel data struct.
Definition zbus.h:113
bool(* validator)(const void *msg, size_t msg_size)
Message validator.
Definition zbus.h:110
size_t message_size
Message size.
Definition zbus.h:99
const char * name
Channel name.
Definition zbus.h:87
void * message
Message reference.
Definition zbus.h:96
Definition zbus.h:128
bool enabled
Enabled flag.
Definition zbus.h:130
Structure used to register runtime observers.
Definition zbus.h:1020
const struct zbus_observer * obs
Definition zbus.h:1022
sys_snode_t node
Definition zbus.h:1021
Type used to represent an observer.
Definition zbus.h:153
enum zbus_observer_type type
Type indication.
Definition zbus.h:159
struct k_fifo * message_fifo
Observer message FIFO.
Definition zbus.h:175
void(* callback)(const struct zbus_channel *chan)
Observer callback function.
Definition zbus.h:169
struct zbus_observer_data * data
Mutable observer data struct.
Definition zbus.h:162
struct k_msgq * queue
Observer message queue.
Definition zbus.h:166
const char * name
Observer name.
Definition zbus.h:156
struct k_work * work
Observer work.
Definition zbus.h:182