LCOV - code coverage report
Current view: top level - zephyr/zbus - zbus.h Coverage Total Hit
Test: new.info Lines: 92.4 % 79 73
Test Date: 2025-09-05 20:47:19

            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_ */
        

Generated by: LCOV version 2.0-1