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