Line data Source code
1 0 : /*
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/iterable_sections.h>
13 :
14 : #ifdef __cplusplus
15 : extern "C" {
16 : #endif
17 :
18 : /**
19 : * @brief Zbus API
20 : * @defgroup zbus_apis Zbus APIs
21 : * @ingroup os_services
22 : * @{
23 : */
24 :
25 : /**
26 : * @brief Type used to represent a channel mutable data.
27 : *
28 : * Every channel has a zbus_channel_data structure associated.
29 : */
30 1 : struct zbus_channel_data {
31 : /** Static channel observer list start index. Considering the ITERABLE SECTIONS allocation
32 : * order.
33 : */
34 1 : int16_t observers_start_idx;
35 :
36 : /** Static channel observer list end index. Considering the ITERABLE SECTIONS allocation
37 : * order.
38 : */
39 1 : int16_t observers_end_idx;
40 :
41 : /** Access control semaphore. Points to the semaphore used to avoid race conditions
42 : * for accessing the channel.
43 : */
44 1 : struct k_sem sem;
45 :
46 : #if defined(CONFIG_ZBUS_PRIORITY_BOOST)
47 : /** Highest observer priority. Indicates the priority that the VDED will use to boost the
48 : * notification process avoiding preemptions.
49 : */
50 : int highest_observer_priority;
51 : #endif /* CONFIG_ZBUS_PRIORITY_BOOST */
52 :
53 : #if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
54 : /** Channel observer list. Represents the channel's observers list, it can be empty
55 : * or have listeners and subscribers mixed in any sequence. It can be changed in runtime.
56 : */
57 1 : sys_slist_t observers;
58 : #endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */
59 :
60 : #if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION) || defined(__DOXYGEN__)
61 : /** Net buf pool for message subscribers. It can be either the global or a separated one.
62 : */
63 1 : struct net_buf_pool *msg_subscriber_pool;
64 : #endif /* ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION */
65 :
66 : #if defined(CONFIG_ZBUS_CHANNEL_PUBLISH_STATS) || defined(__DOXYGEN__)
67 : /** Kernel timestamp of the last publish action on this channel */
68 1 : k_ticks_t publish_timestamp;
69 : /** Number of times data has been published to this channel */
70 1 : uint32_t publish_count;
71 : #endif /* CONFIG_ZBUS_CHANNEL_PUBLISH_STATS */
72 : };
73 :
74 : /**
75 : * @brief Type used to represent a channel.
76 : *
77 : * Every channel has a zbus_channel structure associated used to control the channel
78 : * access and usage.
79 : */
80 1 : struct zbus_channel {
81 : #if defined(CONFIG_ZBUS_CHANNEL_NAME) || defined(__DOXYGEN__)
82 : /** Channel name. */
83 1 : const char *name;
84 : #endif
85 : #if defined(CONFIG_ZBUS_CHANNEL_ID) || defined(__DOXYGEN__)
86 : /** Unique numeric channel identifier. */
87 1 : uint32_t id;
88 : #endif
89 : /** Message reference. Represents the message's reference that points to the actual
90 : * shared memory region.
91 : */
92 1 : void *message;
93 :
94 : /** Message size. Represents the channel's message size. */
95 1 : size_t message_size;
96 :
97 : /** User data available to extend zbus features. The channel must be claimed before
98 : * using this field.
99 : */
100 1 : void *user_data;
101 :
102 : /** Message validator. Stores the reference to the function to check the message
103 : * validity before actually performing the publishing. No invalid messages can be
104 : * published. Every message is valid when this field is empty.
105 : */
106 1 : bool (*validator)(const void *msg, size_t msg_size);
107 :
108 : /** Mutable channel data struct. */
109 1 : struct zbus_channel_data *data;
110 : };
111 :
112 : /**
113 : * @brief Type used to represent an observer type.
114 : *
115 : * A observer can be a listener or a subscriber.
116 : */
117 0 : enum __packed zbus_observer_type {
118 : ZBUS_OBSERVER_LISTENER_TYPE,
119 : ZBUS_OBSERVER_SUBSCRIBER_TYPE,
120 : ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE,
121 : };
122 :
123 0 : struct zbus_observer_data {
124 : /** Enabled flag. Indicates if observer is receiving notification. */
125 1 : bool enabled;
126 :
127 : #if defined(CONFIG_ZBUS_PRIORITY_BOOST)
128 : /** Subscriber attached thread priority. */
129 : int priority;
130 : #endif /* CONFIG_ZBUS_PRIORITY_BOOST */
131 : };
132 :
133 : /**
134 : * @brief Type used to represent an observer.
135 : *
136 : * Every observer has an representation structure containing the relevant information.
137 : * An observer is a code portion interested in some channel. The observer can be notified
138 : * synchronously or asynchronously and it is called listener and subscriber respectively.
139 : * The observer can be enabled or disabled during runtime by change the enabled boolean
140 : * field of the structure. The listeners have a callback function that is executed by the
141 : * bus with the index of the changed channel as argument when the notification is sent.
142 : * The subscribers have a message queue where the bus enqueues the index of the changed
143 : * channel when a notification is sent.
144 : *
145 : * @see zbus_obs_set_enable function to properly change the observer's enabled field.
146 : *
147 : */
148 1 : struct zbus_observer {
149 : #if defined(CONFIG_ZBUS_OBSERVER_NAME) || defined(__DOXYGEN__)
150 : /** Observer name. */
151 1 : const char *name;
152 : #endif
153 : /** Type indication. */
154 1 : enum zbus_observer_type type;
155 :
156 : /** Mutable observer data struct. */
157 1 : struct zbus_observer_data *data;
158 :
159 : union {
160 : /** Observer message queue. It turns the observer into a subscriber. */
161 1 : struct k_msgq *queue;
162 :
163 : /** Observer callback function. It turns the observer into a listener. */
164 1 : void (*callback)(const struct zbus_channel *chan);
165 :
166 : #if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) || defined(__DOXYGEN__)
167 : /** Observer message FIFO. It turns the observer into a message subscriber. It only
168 : * exists if the @kconfig{CONFIG_ZBUS_MSG_SUBSCRIBER} is enabled.
169 : */
170 1 : struct k_fifo *message_fifo;
171 : #endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */
172 0 : };
173 : };
174 :
175 : /** @cond INTERNAL_HIDDEN */
176 : struct zbus_channel_observation_mask {
177 : bool enabled;
178 : };
179 :
180 : struct zbus_channel_observation {
181 : const struct zbus_channel *chan;
182 : const struct zbus_observer *obs;
183 : };
184 :
185 : #ifdef __cplusplus
186 : #define _ZBUS_CPP_EXTERN extern
187 : #else
188 : #define _ZBUS_CPP_EXTERN
189 : #endif /* __cplusplus */
190 :
191 : #define ZBUS_MIN_THREAD_PRIORITY (CONFIG_NUM_PREEMPT_PRIORITIES - 1)
192 :
193 : #if defined(CONFIG_ZBUS_ASSERT_MOCK)
194 : #define _ZBUS_ASSERT(_cond, _fmt, ...) \
195 : do { \
196 : if (!(_cond)) { \
197 : printk("ZBUS ASSERT: "); \
198 : printk(_fmt, ##__VA_ARGS__); \
199 : printk("\n"); \
200 : return -EFAULT; \
201 : } \
202 : } while (0)
203 : #else
204 : #define _ZBUS_ASSERT(_cond, _fmt, ...) __ASSERT(_cond, _fmt, ##__VA_ARGS__)
205 : #endif
206 :
207 : #if defined(CONFIG_ZBUS_CHANNEL_NAME)
208 : #define ZBUS_CHANNEL_NAME_INIT(_name) .name = #_name,
209 : #define _ZBUS_CHAN_NAME(_chan) (_chan)->name
210 : #else
211 : #define ZBUS_CHANNEL_NAME_INIT(_name)
212 : #define _ZBUS_CHAN_NAME(_chan) ""
213 : #endif
214 :
215 : #if defined(CONFIG_ZBUS_OBSERVER_NAME)
216 : #define ZBUS_OBSERVER_NAME_INIT(_name) .name = #_name,
217 : #define _ZBUS_OBS_NAME(_obs) (_obs)->name
218 : #else
219 : #define ZBUS_OBSERVER_NAME_INIT(_name)
220 : #define _ZBUS_OBS_NAME(_obs) ""
221 : #endif
222 :
223 : #if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS)
224 : #define ZBUS_RUNTIME_OBSERVERS_LIST_DECL(_slist_name) static sys_slist_t _slist_name
225 : #define ZBUS_RUNTIME_OBSERVERS_LIST_INIT(_slist_name) .runtime_observers = &_slist_name,
226 : #else
227 : #define ZBUS_RUNTIME_OBSERVERS_LIST_DECL(_slist_name)
228 : #define ZBUS_RUNTIME_OBSERVERS_LIST_INIT(_slist_name) /* No runtime observers */
229 : #endif
230 :
231 : #define _ZBUS_OBS_EXTERN(_name) extern const struct zbus_observer _name
232 :
233 : #define _ZBUS_CHAN_EXTERN(_name) extern const struct zbus_channel _name
234 :
235 : #define ZBUS_REF(_value) &(_value)
236 :
237 : #define FOR_EACH_FIXED_ARG_NONEMPTY_TERM(F, sep, fixed_arg, ...) \
238 : COND_CODE_0(/* are there zero non-empty arguments ? */ \
239 : NUM_VA_ARGS_LESS_1( \
240 : LIST_DROP_EMPTY(__VA_ARGS__, _)), /* if so, expand to nothing */ \
241 : (), /* otherwise, expand to: */ \
242 : (FOR_EACH_IDX_FIXED_ARG( \
243 : F, sep, fixed_arg, \
244 : LIST_DROP_EMPTY(__VA_ARGS__)) /* plus a final terminator */ \
245 : __DEBRACKET sep))
246 :
247 : #define _ZBUS_OBSERVATION_PREFIX(_idx) \
248 : GET_ARG_N(_idx, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, \
249 : 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, \
250 : 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, \
251 : 58, 59, 60, 61, 62, 63)
252 :
253 : #define _ZBUS_CHAN_OBSERVATION(_idx, _obs, _chan) \
254 : const STRUCT_SECTION_ITERABLE( \
255 : zbus_channel_observation, \
256 : _CONCAT(_chan, _ZBUS_OBSERVATION_PREFIX(UTIL_INC(_idx)))) = {.chan = &_chan, \
257 : .obs = &_obs}; \
258 : STRUCT_SECTION_ITERABLE(zbus_channel_observation_mask, \
259 : _CONCAT(_CONCAT(_chan, _ZBUS_OBSERVATION_PREFIX(UTIL_INC(_idx))), \
260 : _mask)) = {.enabled = false};
261 :
262 : #if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
263 : #define _ZBUS_RUNTIME_OBSERVERS(_name) .observers = &(_CONCAT(_observers_, _name)),
264 : #define _ZBUS_RUNTIME_OBSERVERS_DECL(_name) static sys_slist_t _CONCAT(_observers_, _name);
265 : #else
266 : #define _ZBUS_RUNTIME_OBSERVERS(_name)
267 : #define _ZBUS_RUNTIME_OBSERVERS_DECL(_name)
268 : #endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */
269 :
270 : #define _ZBUS_MESSAGE_NAME(_name) _CONCAT(_zbus_message_, _name)
271 :
272 : /* clang-format off */
273 : #define _ZBUS_CHAN_DEFINE(_name, _id, _type, _validator, _user_data) \
274 : static struct zbus_channel_data _CONCAT(_zbus_chan_data_, _name) = { \
275 : .observers_start_idx = -1, \
276 : .observers_end_idx = -1, \
277 : .sem = Z_SEM_INITIALIZER(_CONCAT(_zbus_chan_data_, _name).sem, 1, 1), \
278 : IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, \
279 : (.highest_observer_priority = ZBUS_MIN_THREAD_PRIORITY,)) \
280 : IF_ENABLED(CONFIG_ZBUS_RUNTIME_OBSERVERS, \
281 : (.observers = SYS_SLIST_STATIC_INIT( \
282 : &_CONCAT(_zbus_chan_data_, _name).observers),)) \
283 : }; \
284 : static K_MUTEX_DEFINE(_CONCAT(_zbus_mutex_, _name)); \
285 : _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_channel, _name) = { \
286 : ZBUS_CHANNEL_NAME_INIT(_name) /* Maybe removed */ \
287 : IF_ENABLED(CONFIG_ZBUS_CHANNEL_ID, (.id = _id,)) \
288 : .message = &_ZBUS_MESSAGE_NAME(_name), \
289 : .message_size = sizeof(_type), \
290 : .user_data = _user_data, \
291 : .validator = _validator, \
292 : .data = &_CONCAT(_zbus_chan_data_, _name), \
293 : IF_ENABLED(ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION, \
294 : (.msg_subscriber_pool = &_zbus_msg_subscribers_pool,)) \
295 : }
296 : /* clang-format on */
297 :
298 : /** @endcond */
299 :
300 : /* clang-format off */
301 :
302 : /**
303 : * @brief Add a static channel observation.
304 : *
305 : * This macro initializes a channel observation by receiving the
306 : * channel and the observer.
307 : *
308 : * @param _chan Channel instance.
309 : * @param _obs Observer instance.
310 : * @param _masked Observation state.
311 : * @param _prio Observer notification sequence priority.
312 : */
313 1 : #define ZBUS_CHAN_ADD_OBS_WITH_MASK(_chan, _obs, _masked, _prio) \
314 : const STRUCT_SECTION_ITERABLE(zbus_channel_observation, \
315 : _CONCAT(_CONCAT(_chan, zz), _CONCAT(_prio, _obs))) = { \
316 : .chan = &_chan, \
317 : .obs = &_obs, \
318 : }; \
319 : STRUCT_SECTION_ITERABLE(zbus_channel_observation_mask, \
320 : _CONCAT(_CONCAT(_CONCAT(_chan, zz), _CONCAT(_prio, _obs)), \
321 : _mask)) = {.enabled = _masked}
322 : /* clang-format on */
323 :
324 : /**
325 : * @brief Add a static channel observation.
326 : *
327 : * This macro initializes a channel observation by receiving the
328 : * channel and the observer.
329 : *
330 : * @param _chan Channel instance.
331 : * @param _obs Observer instance.
332 : * @param _prio Observer notification sequence priority.
333 : */
334 1 : #define ZBUS_CHAN_ADD_OBS(_chan, _obs, _prio) ZBUS_CHAN_ADD_OBS_WITH_MASK(_chan, _obs, false, _prio)
335 :
336 : /**
337 : * @def ZBUS_OBS_DECLARE
338 : * This macro list the observers to be used in a file. Internally, it declares the observers with
339 : * the extern statement. Note it is only necessary when the observers are declared outside the file.
340 : */
341 1 : #define ZBUS_OBS_DECLARE(...) FOR_EACH_NONEMPTY_TERM(_ZBUS_OBS_EXTERN, (;), __VA_ARGS__)
342 :
343 : /**
344 : * @def ZBUS_CHAN_DECLARE
345 : * This macro list the channels to be used in a file. Internally, it declares the channels with the
346 : * extern statement. Note it is only necessary when the channels are declared outside the file.
347 : */
348 1 : #define ZBUS_CHAN_DECLARE(...) FOR_EACH(_ZBUS_CHAN_EXTERN, (;), __VA_ARGS__)
349 :
350 : /**
351 : * @def ZBUS_OBSERVERS_EMPTY
352 : * This macro indicates the channel has no observers.
353 : */
354 1 : #define ZBUS_OBSERVERS_EMPTY
355 :
356 : /**
357 : * @def ZBUS_OBSERVERS
358 : * This macro indicates the channel has listed observers. Note the sequence of observer notification
359 : * will follow the same as listed.
360 : */
361 1 : #define ZBUS_OBSERVERS(...) __VA_ARGS__
362 :
363 : /**
364 : * @def ZBUS_CHAN_ID_INVALID
365 : * This macro indicates the channel does not have a unique ID.
366 : */
367 1 : #define ZBUS_CHAN_ID_INVALID UINT32_MAX
368 :
369 : /**
370 : * @brief Zbus channel definition.
371 : *
372 : * This macro defines a channel.
373 : *
374 : * @param _name The channel's name.
375 : * @param _type The Message type. It must be a struct or union.
376 : * @param _validator The validator function.
377 : * @param _user_data A pointer to the user data.
378 : *
379 : * @see struct zbus_channel
380 : * @param _observers The observers list. The sequence indicates the priority of the observer. The
381 : * first the highest priority.
382 : * @param _init_val The message initialization.
383 : */
384 1 : #define ZBUS_CHAN_DEFINE(_name, _type, _validator, _user_data, _observers, _init_val) \
385 : static _type _ZBUS_MESSAGE_NAME(_name) = _init_val; \
386 : _ZBUS_CHAN_DEFINE(_name, ZBUS_CHAN_ID_INVALID, _type, _validator, _user_data); \
387 : /* Extern declaration of observers */ \
388 : ZBUS_OBS_DECLARE(_observers); \
389 : /* Create all channel observations from observers list */ \
390 : FOR_EACH_FIXED_ARG_NONEMPTY_TERM(_ZBUS_CHAN_OBSERVATION, (;), _name, _observers)
391 :
392 : /**
393 : * @brief Zbus channel definition with numeric identifier.
394 : *
395 : * This macro defines a channel.
396 : *
397 : * @param _name The channel's name.
398 : * @param _id The channel's unique numeric identifier.
399 : * @param _type The Message type. It must be a struct or union.
400 : * @param _validator The validator function.
401 : * @param _user_data A pointer to the user data.
402 : *
403 : * @see struct zbus_channel
404 : * @param _observers The observers list. The sequence indicates the priority of the observer. The
405 : * first the highest priority.
406 : * @param _init_val The message initialization.
407 : */
408 1 : #define ZBUS_CHAN_DEFINE_WITH_ID(_name, _id, _type, _validator, _user_data, _observers, _init_val) \
409 : static _type _ZBUS_MESSAGE_NAME(_name) = _init_val; \
410 : _ZBUS_CHAN_DEFINE(_name, _id, _type, _validator, _user_data); \
411 : /* Extern declaration of observers */ \
412 : ZBUS_OBS_DECLARE(_observers); \
413 : /* Create all channel observations from observers list */ \
414 : FOR_EACH_FIXED_ARG_NONEMPTY_TERM(_ZBUS_CHAN_OBSERVATION, (;), _name, _observers)
415 :
416 : /**
417 : * @brief Initialize a message.
418 : *
419 : * This macro initializes a message by passing the values to initialize the message struct
420 : * or union.
421 : *
422 : * @param[in] _val Variadic with the initial values. ``ZBUS_INIT(0)`` means ``{0}``, as
423 : * ZBUS_INIT(.a=10, .b=30) means ``{.a=10, .b=30}``.
424 : */
425 1 : #define ZBUS_MSG_INIT(_val, ...) {_val, ##__VA_ARGS__}
426 :
427 : /* clang-format off */
428 :
429 : /**
430 : * @brief Define and initialize a subscriber.
431 : *
432 : * This macro defines an observer of subscriber type. It defines a message queue where the
433 : * subscriber will receive the notification asynchronously, and initialize the ``struct
434 : * zbus_observer`` defining the subscriber.
435 : *
436 : * @param[in] _name The subscriber's name.
437 : * @param[in] _queue_size The notification queue's size.
438 : * @param[in] _enable The subscriber initial enable state.
439 : */
440 1 : #define ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, _enable) \
441 : K_MSGQ_DEFINE(_zbus_observer_queue_##_name, \
442 : sizeof(struct zbus_channel *), \
443 : _queue_size, sizeof(struct zbus_channel *) \
444 : ); \
445 : static struct zbus_observer_data _CONCAT(_zbus_obs_data_, _name) = { \
446 : .enabled = _enable, \
447 : IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
448 : .priority = ZBUS_MIN_THREAD_PRIORITY, \
449 : )) \
450 : }; \
451 : _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \
452 : ZBUS_OBSERVER_NAME_INIT(_name) /* Name field */ \
453 : .type = ZBUS_OBSERVER_SUBSCRIBER_TYPE, \
454 : .data = &_CONCAT(_zbus_obs_data_, _name), \
455 : .queue = &_zbus_observer_queue_##_name, \
456 : }
457 : /* clang-format on */
458 :
459 : /**
460 : * @brief Define and initialize a subscriber.
461 : *
462 : * This macro defines an observer of subscriber type. It defines a message queue where the
463 : * subscriber will receive the notification asynchronously, and initialize the ``struct
464 : * zbus_observer`` defining the subscriber. The subscribers are defined in the enabled
465 : * state with this macro.
466 : *
467 : * @param[in] _name The subscriber's name.
468 : * @param[in] _queue_size The notification queue's size.
469 : */
470 1 : #define ZBUS_SUBSCRIBER_DEFINE(_name, _queue_size) \
471 : ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, true)
472 :
473 : /* clang-format off */
474 :
475 : /**
476 : * @brief Define and initialize a listener.
477 : *
478 : * This macro defines an observer of listener type. This macro establishes the callback where the
479 : * listener will be notified synchronously, and initialize the ``struct zbus_observer`` defining the
480 : * listener.
481 : *
482 : * @param[in] _name The listener's name.
483 : * @param[in] _cb The callback function.
484 : * @param[in] _enable The listener initial enable state.
485 : */
486 1 : #define ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable) \
487 : static struct zbus_observer_data _CONCAT(_zbus_obs_data_, _name) = { \
488 : .enabled = _enable, \
489 : IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
490 : .priority = ZBUS_MIN_THREAD_PRIORITY, \
491 : )) \
492 : }; \
493 : _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \
494 : ZBUS_OBSERVER_NAME_INIT(_name) /* Name field */ \
495 : .type = ZBUS_OBSERVER_LISTENER_TYPE, \
496 : .data = &_CONCAT(_zbus_obs_data_, _name), \
497 : .callback = (_cb) \
498 : }
499 : /* clang-format on */
500 :
501 : /**
502 : * @brief Define and initialize a listener.
503 : *
504 : * This macro defines an observer of listener type. This macro establishes the callback where the
505 : * listener will be notified synchronously and initialize the ``struct zbus_observer`` defining the
506 : * listener. The listeners are defined in the enabled state with this macro.
507 : *
508 : * @param[in] _name The listener's name.
509 : * @param[in] _cb The callback function.
510 : */
511 1 : #define ZBUS_LISTENER_DEFINE(_name, _cb) ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, true)
512 :
513 : /* clang-format off */
514 :
515 : /**
516 : * @brief Define and initialize a message subscriber.
517 : *
518 : * This macro defines an observer of @ref ZBUS_OBSERVER_SUBSCRIBER_TYPE type. It defines a FIFO
519 : * where the subscriber will receive the message asynchronously and initialize the @ref
520 : * zbus_observer defining the subscriber.
521 : *
522 : * @param[in] _name The subscriber's name.
523 : * @param[in] _enable The subscriber's initial state.
524 : */
525 1 : #define ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _enable) \
526 : static K_FIFO_DEFINE(_zbus_observer_fifo_##_name); \
527 : static struct zbus_observer_data _CONCAT(_zbus_obs_data_, _name) = { \
528 : .enabled = _enable, \
529 : IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
530 : .priority = ZBUS_MIN_THREAD_PRIORITY, \
531 : )) \
532 : }; \
533 : _ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \
534 : ZBUS_OBSERVER_NAME_INIT(_name) /* Name field */ \
535 : .type = ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE, \
536 : .data = &_CONCAT(_zbus_obs_data_, _name), \
537 : .message_fifo = &_zbus_observer_fifo_##_name, \
538 : }
539 : /* clang-format on */
540 :
541 : /**
542 : * @brief Define and initialize an enabled message subscriber.
543 : *
544 : * This macro defines an observer of message subscriber type. It defines a FIFO where the
545 : * subscriber will receive the message asynchronously and initialize the @ref
546 : * zbus_observer defining the subscriber. The message subscribers are defined in the enabled state
547 : * with this macro.
548 :
549 : *
550 : * @param[in] _name The subscriber's name.
551 : */
552 1 : #define ZBUS_MSG_SUBSCRIBER_DEFINE(_name) ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, true)
553 : /**
554 : *
555 : * @brief Publish to a channel
556 : *
557 : * This routine publishes a message to a channel.
558 : *
559 : * @param chan The channel's reference.
560 : * @param msg Reference to the message where the publish function copies the channel's
561 : * message data from.
562 : * @param timeout Waiting period to publish the channel,
563 : * or one of the special values K_NO_WAIT and K_FOREVER.
564 : *
565 : * @retval 0 Channel published.
566 : * @retval -ENOMSG The message is invalid based on the validator function or some of the
567 : * observers could not receive the notification.
568 : * @retval -EBUSY The channel is busy.
569 : * @retval -EAGAIN Waiting period timed out.
570 : * @retval -EFAULT A parameter is incorrect, the notification could not be sent to one or more
571 : * observer, or the function context is invalid (inside an ISR). The function only returns this
572 : * value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
573 : */
574 1 : int zbus_chan_pub(const struct zbus_channel *chan, const void *msg, k_timeout_t timeout);
575 :
576 : /**
577 : * @brief Read a channel
578 : *
579 : * This routine reads a message from a channel.
580 : *
581 : * @param[in] chan The channel's reference.
582 : * @param[out] msg Reference to the message where the read function copies the channel's
583 : * message data to.
584 : * @param[in] timeout Waiting period to read the channel,
585 : * or one of the special values K_NO_WAIT and K_FOREVER.
586 : *
587 : * @retval 0 Channel read.
588 : * @retval -EBUSY The channel is busy.
589 : * @retval -EAGAIN Waiting period timed out.
590 : * @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
591 : * function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
592 : */
593 1 : int zbus_chan_read(const struct zbus_channel *chan, void *msg, k_timeout_t timeout);
594 :
595 : /**
596 : * @brief Claim a channel
597 : *
598 : * This routine claims a channel. During the claiming period the channel is blocked for publishing,
599 : * reading, notifying or claiming again. Finishing is the only available action.
600 : *
601 : * @warning After calling this routine, the channel cannot be used by other
602 : * thread until the zbus_chan_finish routine is performed.
603 : *
604 : * @warning This routine should only be called once before a zbus_chan_finish.
605 : *
606 : * @param[in] chan The channel's reference.
607 : * @param[in] timeout Waiting period to claim the channel,
608 : * or one of the special values K_NO_WAIT and K_FOREVER.
609 : *
610 : * @retval 0 Channel claimed.
611 : * @retval -EBUSY The channel is busy.
612 : * @retval -EAGAIN Waiting period timed out.
613 : * @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
614 : * function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
615 : */
616 1 : int zbus_chan_claim(const struct zbus_channel *chan, k_timeout_t timeout);
617 :
618 : /**
619 : * @brief Finish a channel claim.
620 : *
621 : * This routine finishes a channel claim. After calling this routine with success, the channel will
622 : * be able to be used by other thread.
623 : *
624 : * @warning This routine must only be used after a zbus_chan_claim.
625 : *
626 : * @param chan The channel's reference.
627 : *
628 : * @retval 0 Channel finished.
629 : * @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
630 : * function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
631 : */
632 1 : int zbus_chan_finish(const struct zbus_channel *chan);
633 :
634 : /**
635 : * @brief Force a channel notification.
636 : *
637 : * This routine forces the event dispatcher to notify the channel's observers even if the message
638 : * has no changes. Note this function could be useful after claiming/finishing actions.
639 : *
640 : * @param chan The channel's reference.
641 : * @param timeout Waiting period to notify the channel,
642 : * or one of the special values K_NO_WAIT and K_FOREVER.
643 : *
644 : * @retval 0 Channel notified.
645 : * @retval -EBUSY The channel's semaphore returned without waiting.
646 : * @retval -EAGAIN Timeout to take the channel's semaphore.
647 : * @retval -ENOMEM There is not more buffer on the messgage buffers pool.
648 : * @retval -EFAULT A parameter is incorrect, the notification could not be sent to one or more
649 : * observer, or the function context is invalid (inside an ISR). The function only returns this
650 : * value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
651 : */
652 1 : int zbus_chan_notify(const struct zbus_channel *chan, k_timeout_t timeout);
653 :
654 : #if defined(CONFIG_ZBUS_CHANNEL_NAME) || defined(__DOXYGEN__)
655 :
656 : /**
657 : * @brief Get the channel's name.
658 : *
659 : * This routine returns the channel's name reference.
660 : *
661 : * @param chan The channel's reference.
662 : *
663 : * @return Channel's name reference.
664 : */
665 1 : static inline const char *zbus_chan_name(const struct zbus_channel *chan)
666 : {
667 : __ASSERT(chan != NULL, "chan is required");
668 :
669 : return chan->name;
670 : }
671 :
672 : #endif
673 :
674 : #if defined(CONFIG_ZBUS_CHANNEL_ID) || defined(__DOXYGEN__)
675 :
676 : /**
677 : * @brief Retrieve a zbus channel from its numeric identifier
678 : *
679 : * @param channel_id Unique channel ID from @ref ZBUS_CHAN_DEFINE_WITH_ID
680 : *
681 : * @retval NULL If channel with ID @a channel_id does not exist.
682 : * @retval chan Channel pointer with ID @a channel_id otherwise.
683 : */
684 1 : const struct zbus_channel *zbus_chan_from_id(uint32_t channel_id);
685 :
686 : #endif
687 :
688 : /**
689 : * @brief Get the reference for a channel message directly.
690 : *
691 : * This routine returns the reference of a channel message.
692 : *
693 : * @warning This function must only be used directly for already locked channels. This
694 : * can be done inside a listener for the receiving channel or after claim a channel.
695 : *
696 : * @param chan The channel's reference.
697 : *
698 : * @return Channel's message reference.
699 : */
700 1 : static inline void *zbus_chan_msg(const struct zbus_channel *chan)
701 : {
702 : __ASSERT(chan != NULL, "chan is required");
703 :
704 : return chan->message;
705 : }
706 :
707 : /**
708 : * @brief Get a constant reference for a channel message directly.
709 : *
710 : * This routine returns a constant reference of a channel message. This should be used
711 : * inside listeners to access the message directly. In this way zbus prevents the listener of
712 : * changing the notifying channel's message during the notification process.
713 : *
714 : * @warning This function must only be used directly for already locked channels. This
715 : * can be done inside a listener for the receiving channel or after claim a channel.
716 : *
717 : * @param chan The channel's constant reference.
718 : *
719 : * @return A constant channel's message reference.
720 : */
721 1 : static inline const void *zbus_chan_const_msg(const struct zbus_channel *chan)
722 : {
723 : __ASSERT(chan != NULL, "chan is required");
724 :
725 : return chan->message;
726 : }
727 :
728 : /**
729 : * @brief Get the channel's message size.
730 : *
731 : * This routine returns the channel's message size.
732 : *
733 : * @param chan The channel's reference.
734 : *
735 : * @return Channel's message size.
736 : */
737 1 : static inline uint16_t zbus_chan_msg_size(const struct zbus_channel *chan)
738 : {
739 : __ASSERT(chan != NULL, "chan is required");
740 :
741 : return chan->message_size;
742 : }
743 :
744 : /**
745 : * @brief Get the channel's user data.
746 : *
747 : * This routine returns the channel's user data.
748 : *
749 : * @param chan The channel's reference.
750 : *
751 : * @return Channel's user data.
752 : */
753 1 : static inline void *zbus_chan_user_data(const struct zbus_channel *chan)
754 : {
755 : __ASSERT(chan != NULL, "chan is required");
756 :
757 : return chan->user_data;
758 : }
759 :
760 : #if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION) || defined(__DOXYGEN__)
761 :
762 : /**
763 : * @brief Set the channel's msg subscriber `net_buf` pool.
764 : *
765 : * @param chan The channel's reference.
766 : * @param pool The reference to the `net_buf` memory pool.
767 : */
768 1 : static inline void zbus_chan_set_msg_sub_pool(const struct zbus_channel *chan,
769 : struct net_buf_pool *pool)
770 : {
771 : __ASSERT(chan != NULL, "chan is required");
772 : __ASSERT(pool != NULL, "pool is required");
773 :
774 : chan->data->msg_subscriber_pool = pool;
775 : }
776 :
777 : #endif /* ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION */
778 :
779 : #if defined(CONFIG_ZBUS_CHANNEL_PUBLISH_STATS) || defined(__DOXYGEN__)
780 :
781 : /**
782 : * @brief Update the publishing statistics for a channel
783 : *
784 : * This function updates the publishing statistics for the @ref zbus_chan_claim ->
785 : * @ref zbus_chan_finish workflow, which cannot automatically determine whether
786 : * new data has been published or not.
787 : *
788 : * @warning This function must only be used directly for already locked channels.
789 : *
790 : * @param chan The channel's reference.
791 : */
792 1 : static inline void zbus_chan_pub_stats_update(const struct zbus_channel *chan)
793 : {
794 : __ASSERT(chan != NULL, "chan is required");
795 :
796 : chan->data->publish_timestamp = k_uptime_ticks();
797 : chan->data->publish_count += 1;
798 : }
799 :
800 : /**
801 : * @brief Get the time a channel was last published to.
802 : *
803 : * @note Will return 0 if channel has not yet been published to.
804 : *
805 : * @param chan The channel's reference.
806 : *
807 : * @return The kernel timestamp of the last publishing action.
808 : */
809 1 : static inline k_ticks_t zbus_chan_pub_stats_last_time(const struct zbus_channel *chan)
810 : {
811 : __ASSERT(chan != NULL, "chan is required");
812 :
813 : return chan->data->publish_timestamp;
814 : }
815 :
816 : /**
817 : * @brief Get the number of times a channel has been published to.
818 : *
819 : * @note Will return 0 if channel has not yet been published to.
820 : *
821 : * @param chan The channel's reference.
822 : *
823 : * @return The number of times a channel has been published to.
824 : */
825 1 : static inline uint32_t zbus_chan_pub_stats_count(const struct zbus_channel *chan)
826 : {
827 : __ASSERT(chan != NULL, "chan is required");
828 :
829 : return chan->data->publish_count;
830 : }
831 :
832 : /**
833 : * @brief Get the average period between publishes to a channel.
834 : *
835 : * @note Will return 0 if channel has not yet been published to.
836 : *
837 : * @param chan The channel's reference.
838 : *
839 : * @return Average duration in milliseconds between publishes.
840 : */
841 1 : static inline uint32_t zbus_chan_pub_stats_avg_period(const struct zbus_channel *chan)
842 : {
843 : __ASSERT(chan != NULL, "chan is required");
844 :
845 : /* Not yet published, period = 0ms */
846 : if (chan->data->publish_count == 0) {
847 : return 0;
848 : }
849 : /* Average period across application runtime */
850 : return k_uptime_get() / chan->data->publish_count;
851 : }
852 :
853 : #else
854 :
855 : static inline void zbus_chan_pub_stats_update(const struct zbus_channel *chan)
856 : {
857 : (void)chan;
858 : }
859 :
860 : #endif /* CONFIG_ZBUS_CHANNEL_PUBLISH_STATS */
861 :
862 : #if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
863 :
864 : /**
865 : * @brief Add an observer to a channel.
866 : *
867 : * This routine adds an observer to the channel.
868 : *
869 : * @param chan The channel's reference.
870 : * @param obs The observer's reference to be added.
871 : * @param timeout Waiting period to add an observer,
872 : * or one of the special values K_NO_WAIT and K_FOREVER.
873 : *
874 : * @retval 0 Observer added to the channel.
875 : * @retval -EALREADY The observer is already present in the channel's runtime observers list.
876 : * @retval -ENOMEM Returned without waiting.
877 : * @retval -EAGAIN Waiting period timed out.
878 : * @retval -EINVAL Some parameter is invalid.
879 : */
880 1 : int zbus_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observer *obs,
881 : k_timeout_t timeout);
882 :
883 : /**
884 : * @brief Remove an observer from a channel.
885 : *
886 : * This routine removes an observer to the channel.
887 : *
888 : * @param chan The channel's reference.
889 : * @param obs The observer's reference to be removed.
890 : * @param timeout Waiting period to remove an observer,
891 : * or one of the special values K_NO_WAIT and K_FOREVER.
892 : *
893 : * @retval 0 Observer removed to the channel.
894 : * @retval -EINVAL Invalid data supplied.
895 : * @retval -EBUSY Returned without waiting.
896 : * @retval -EAGAIN Waiting period timed out.
897 : * @retval -ENODATA no observer found in channel's runtime observer list.
898 : * @retval -ENOMEM Returned without waiting.
899 : */
900 1 : int zbus_chan_rm_obs(const struct zbus_channel *chan, const struct zbus_observer *obs,
901 : k_timeout_t timeout);
902 :
903 : /** @cond INTERNAL_HIDDEN */
904 :
905 : struct zbus_observer_node {
906 : sys_snode_t node;
907 : const struct zbus_observer *obs;
908 : };
909 :
910 : /** @endcond */
911 :
912 : #endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */
913 :
914 : /**
915 : * @brief Change the observer state.
916 : *
917 : * This routine changes the observer state. A channel when disabled will not receive
918 : * notifications from the event dispatcher.
919 : *
920 : * @param[in] obs The observer's reference.
921 : * @param[in] enabled State to be. When false the observer stops to receive notifications.
922 : *
923 : * @retval 0 Observer set enable.
924 : * @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
925 : * function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
926 : */
927 1 : int zbus_obs_set_enable(const struct zbus_observer *obs, bool enabled);
928 :
929 : /**
930 : * @brief Get the observer state.
931 : *
932 : * This routine retrieves the observer state.
933 : *
934 : * @param[in] obs The observer's reference.
935 : * @param[out] enable The boolean output's reference.
936 : *
937 : * @return Observer state.
938 : */
939 1 : static inline int zbus_obs_is_enabled(const struct zbus_observer *obs, bool *enable)
940 : {
941 : _ZBUS_ASSERT(obs != NULL, "obs is required");
942 : _ZBUS_ASSERT(enable != NULL, "enable is required");
943 :
944 : *enable = obs->data->enabled;
945 :
946 : return 0;
947 : }
948 :
949 : /**
950 : * @brief Mask notifications from a channel to an observer.
951 : *
952 : * The observer can mask notifications from a specific observing channel by calling this function.
953 : *
954 : * @param obs The observer's reference to be added.
955 : * @param chan The channel's reference.
956 : * @param masked The mask state. When the mask is true, the observer will not receive notifications
957 : * from the channel.
958 : *
959 : * @retval 0 Channel notifications masked to the observer.
960 : * @retval -ESRCH No observation found for the related pair chan/obs.
961 : * @retval -EINVAL Some parameter is invalid.
962 : */
963 1 : int zbus_obs_set_chan_notification_mask(const struct zbus_observer *obs,
964 : const struct zbus_channel *chan, bool masked);
965 :
966 : /**
967 : * @brief Get the notifications masking state from a channel to an observer.
968 : *
969 : * @param obs The observer's reference to be added.
970 : * @param chan The channel's reference.
971 : * @param[out] masked The mask state. When the mask is true, the observer will not receive
972 : * notifications from the channel.
973 : *
974 : * @retval 0 Retrieved the masked state.
975 : * @retval -ESRCH No observation found for the related pair chan/obs.
976 : * @retval -EINVAL Some parameter is invalid.
977 : */
978 1 : int zbus_obs_is_chan_notification_masked(const struct zbus_observer *obs,
979 : const struct zbus_channel *chan, bool *masked);
980 :
981 : #if defined(CONFIG_ZBUS_OBSERVER_NAME) || defined(__DOXYGEN__)
982 :
983 : /**
984 : * @brief Get the observer's name.
985 : *
986 : * This routine returns the observer's name reference.
987 : *
988 : * @param obs The observer's reference.
989 : *
990 : * @return The observer's name reference.
991 : */
992 1 : static inline const char *zbus_obs_name(const struct zbus_observer *obs)
993 : {
994 : __ASSERT(obs != NULL, "obs is required");
995 :
996 : return obs->name;
997 : }
998 :
999 : #endif
1000 :
1001 : #if defined(CONFIG_ZBUS_PRIORITY_BOOST) || defined(__DOXYGEN__)
1002 :
1003 : /**
1004 : * @brief Set the observer thread priority by attaching it to a thread.
1005 : *
1006 : * @param[in] obs The observer's reference.
1007 : *
1008 : * @retval 0 Observer detached from the thread.
1009 : * @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
1010 : * function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
1011 : */
1012 1 : int zbus_obs_attach_to_thread(const struct zbus_observer *obs);
1013 :
1014 : /**
1015 : * @brief Clear the observer thread priority by detaching it from a thread.
1016 : *
1017 : * @param[in] obs The observer's reference.
1018 : *
1019 : * @retval 0 Observer detached from the thread.
1020 : * @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
1021 : * function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
1022 : */
1023 1 : int zbus_obs_detach_from_thread(const struct zbus_observer *obs);
1024 :
1025 : #endif /* CONFIG_ZBUS_PRIORITY_BOOST */
1026 :
1027 : /**
1028 : * @brief Wait for a channel notification.
1029 : *
1030 : * This routine makes the subscriber to wait a notification. The notification comes as a channel
1031 : * reference.
1032 : *
1033 : * @param[in] sub The subscriber's reference.
1034 : * @param[out] chan The notification channel's reference.
1035 : * @param[in] timeout Waiting period for a notification arrival,
1036 : * or one of the special values K_NO_WAIT and K_FOREVER.
1037 : *
1038 : * @retval 0 Notification received.
1039 : * @retval -ENOMSG Returned without waiting.
1040 : * @retval -EAGAIN Waiting period timed out.
1041 : * @retval -EINVAL The observer is not a subscriber.
1042 : * @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
1043 : * function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
1044 : */
1045 1 : int zbus_sub_wait(const struct zbus_observer *sub, const struct zbus_channel **chan,
1046 : k_timeout_t timeout);
1047 :
1048 : #if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) || defined(__DOXYGEN__)
1049 :
1050 : /**
1051 : * @brief Wait for a channel message.
1052 : *
1053 : * This routine makes the subscriber wait for the new message in case of channel publication.
1054 : *
1055 : * @param[in] sub The subscriber's reference.
1056 : * @param[out] chan The notification channel's reference.
1057 : * @param[out] msg A reference to a copy of the published message.
1058 : * @param[in] timeout Waiting period for a notification arrival,
1059 : * or one of the special values, K_NO_WAIT and K_FOREVER.
1060 : *
1061 : * @retval 0 Message received.
1062 : * @retval -EINVAL The observer is not a subscriber.
1063 : * @retval -ENOMSG Could not retrieve the net_buf from the subscriber FIFO.
1064 : * @retval -EILSEQ Received an invalid channel reference.
1065 : * @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
1066 : * function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
1067 : */
1068 1 : int zbus_sub_wait_msg(const struct zbus_observer *sub, const struct zbus_channel **chan, void *msg,
1069 : k_timeout_t timeout);
1070 :
1071 : #endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */
1072 :
1073 : /**
1074 : *
1075 : * @brief Iterate over channels.
1076 : *
1077 : * Enables the developer to iterate over the channels giving to this function an
1078 : * iterator_func which is called for each channel. If the iterator_func returns false all
1079 : * the iteration stops.
1080 : *
1081 : * @param[in] iterator_func The function that will be execute on each iteration.
1082 : *
1083 : * @retval true Iterator executed for all channels.
1084 : * @retval false Iterator could not be executed. Some iterate returned false.
1085 : */
1086 1 : bool zbus_iterate_over_channels(bool (*iterator_func)(const struct zbus_channel *chan));
1087 : /**
1088 : *
1089 : * @brief Iterate over channels with user data.
1090 : *
1091 : * Enables the developer to iterate over the channels giving to this function an
1092 : * iterator_func which is called for each channel. If the iterator_func returns false all
1093 : * the iteration stops.
1094 : *
1095 : * @param[in] iterator_func The function that will be execute on each iteration.
1096 : * @param[in] user_data The user data that can be passed in the function.
1097 : *
1098 : * @retval true Iterator executed for all channels.
1099 : * @retval false Iterator could not be executed. Some iterate returned false.
1100 : */
1101 1 : bool zbus_iterate_over_channels_with_user_data(
1102 : bool (*iterator_func)(const struct zbus_channel *chan, void *user_data), void *user_data);
1103 :
1104 : /**
1105 : *
1106 : * @brief Iterate over observers.
1107 : *
1108 : * Enables the developer to iterate over the observers giving to this function an
1109 : * iterator_func which is called for each observer. If the iterator_func returns false all
1110 : * the iteration stops.
1111 : *
1112 : * @param[in] iterator_func The function that will be execute on each iteration.
1113 : *
1114 : * @retval true Iterator executed for all channels.
1115 : * @retval false Iterator could not be executed. Some iterate returned false.
1116 : */
1117 1 : bool zbus_iterate_over_observers(bool (*iterator_func)(const struct zbus_observer *obs));
1118 : /**
1119 : *
1120 : * @brief Iterate over observers with user data.
1121 : *
1122 : * Enables the developer to iterate over the observers giving to this function an
1123 : * iterator_func which is called for each observer. If the iterator_func returns false all
1124 : * the iteration stops.
1125 : *
1126 : * @param[in] iterator_func The function that will be execute on each iteration.
1127 : * @param[in] user_data The user data that can be passed in the function.
1128 : *
1129 : * @retval true Iterator executed for all channels.
1130 : * @retval false Iterator could not be executed. Some iterate returned false.
1131 : */
1132 1 : bool zbus_iterate_over_observers_with_user_data(
1133 : bool (*iterator_func)(const struct zbus_observer *obs, void *user_data), void *user_data);
1134 :
1135 : /**
1136 : * @}
1137 : */
1138 :
1139 : #ifdef __cplusplus
1140 : }
1141 : #endif
1142 :
1143 : #endif /* ZEPHYR_INCLUDE_ZBUS_H_ */
|