zephyr/include/zephyr/zbus/zbus.h

997 lines
37 KiB
C
Raw Permalink Normal View History

/*
* Copyright (c) 2022 Rodrigo Peixoto <rodrigopex@gmail.com>
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_ZBUS_H_
#define ZEPHYR_INCLUDE_ZBUS_H_
#include <string.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/iterable_sections.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Zbus API
* @defgroup zbus_apis Zbus APIs
* @ingroup os_services
* @{
*/
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
/**
* @brief Type used to represent a channel mutable data.
*
* Every channel has a zbus_channel_data structure associated.
*/
struct zbus_channel_data {
/** Static channel observer list start index. Considering the ITERABLE SECTIONS allocation
* order.
*/
int16_t observers_start_idx;
/** Static channel observer list end index. Considering the ITERABLE SECTIONS allocation
* order.
*/
int16_t observers_end_idx;
/** Access control semaphore. Points to the semaphore used to avoid race conditions
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
* for accessing the channel.
*/
struct k_sem sem;
#if defined(CONFIG_ZBUS_PRIORITY_BOOST)
/** Highest observer priority. Indicates the priority that the VDED will use to boost the
* notification process avoiding preemptions.
*/
int highest_observer_priority;
#endif /* CONFIG_ZBUS_PRIORITY_BOOST */
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
/** Channel observer list. Represents the channel's observers list, it can be empty
* or have listeners and subscribers mixed in any sequence. It can be changed in runtime.
*/
sys_slist_t observers;
#endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */
#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION) || defined(__DOXYGEN__)
/** Net buf pool for message subscribers. It can be either the global or a separated one.
*/
struct net_buf_pool *msg_subscriber_pool;
#endif /* ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION */
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
};
/**
* @brief Type used to represent a channel.
*
* Every channel has a zbus_channel structure associated used to control the channel
* access and usage.
*/
struct zbus_channel {
#if defined(CONFIG_ZBUS_CHANNEL_NAME) || defined(__DOXYGEN__)
/** Channel name. */
const char *const name;
#endif
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
/** Message reference. Represents the message's reference that points to the actual
* shared memory region.
*/
void *const message;
/** Message size. Represents the channel's message size. */
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
const size_t message_size;
/** User data available to extend zbus features. The channel must be claimed before
* using this field.
*/
void *const user_data;
/** Message validator. Stores the reference to the function to check the message
* validity before actually performing the publishing. No invalid messages can be
* published. Every message is valid when this field is empty.
*/
bool (*const validator)(const void *msg, size_t msg_size);
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
/** Mutable channel data struct. */
struct zbus_channel_data *const data;
};
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
/**
* @brief Type used to represent an observer type.
*
* A observer can be a listener or a subscriber.
*/
enum __packed zbus_observer_type {
ZBUS_OBSERVER_LISTENER_TYPE,
ZBUS_OBSERVER_SUBSCRIBER_TYPE,
ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE,
};
struct zbus_observer_data {
/** Enabled flag. Indicates if observer is receiving notification. */
bool enabled;
#if defined(CONFIG_ZBUS_PRIORITY_BOOST)
/** Subscriber attached thread priority. */
int priority;
#endif /* CONFIG_ZBUS_PRIORITY_BOOST */
};
/**
* @brief Type used to represent an observer.
*
* Every observer has an representation structure containing the relevant information.
* An observer is a code portion interested in some channel. The observer can be notified
* synchronously or asynchronously and it is called listener and subscriber respectively.
* The observer can be enabled or disabled during runtime by change the enabled boolean
* field of the structure. The listeners have a callback function that is executed by the
* bus with the index of the changed channel as argument when the notification is sent.
* The subscribers have a message queue where the bus enqueues the index of the changed
* channel when a notification is sent.
*
* @see zbus_obs_set_enable function to properly change the observer's enabled field.
*
*/
struct zbus_observer {
#if defined(CONFIG_ZBUS_OBSERVER_NAME) || defined(__DOXYGEN__)
/** Observer name. */
const char *const name;
#endif
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
/** Type indication. */
enum zbus_observer_type type;
/** Mutable observer data struct. */
struct zbus_observer_data *const data;
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
union {
/** Observer message queue. It turns the observer into a subscriber. */
struct k_msgq *const queue;
/** Observer callback function. It turns the observer into a listener. */
void (*const callback)(const struct zbus_channel *chan);
#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) || defined(__DOXYGEN__)
/** Observer message FIFO. It turns the observer into a message subscriber. It only
* exists if the @kconfig{CONFIG_ZBUS_MSG_SUBSCRIBER} is enabled.
*/
struct k_fifo *const message_fifo;
#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
};
};
/** @cond INTERNAL_HIDDEN */
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
struct zbus_channel_observation_mask {
bool enabled;
};
struct zbus_channel_observation {
const struct zbus_channel *const chan;
const struct zbus_observer *const obs;
};
#ifdef __cplusplus
#define _ZBUS_CPP_EXTERN extern
#else
#define _ZBUS_CPP_EXTERN
#endif /* __cplusplus */
#define ZBUS_MIN_THREAD_PRIORITY (CONFIG_NUM_PREEMPT_PRIORITIES - 1)
#if defined(CONFIG_ZBUS_ASSERT_MOCK)
#define _ZBUS_ASSERT(_cond, _fmt, ...) \
do { \
if (!(_cond)) { \
printk("ZBUS ASSERT: "); \
printk(_fmt, ##__VA_ARGS__); \
printk("\n"); \
return -EFAULT; \
} \
} while (0)
#else
#define _ZBUS_ASSERT(_cond, _fmt, ...) __ASSERT(_cond, _fmt, ##__VA_ARGS__)
#endif
#if defined(CONFIG_ZBUS_CHANNEL_NAME)
#define ZBUS_CHANNEL_NAME_INIT(_name) .name = #_name,
#define _ZBUS_CHAN_NAME(_chan) (_chan)->name
#else
#define ZBUS_CHANNEL_NAME_INIT(_name)
#define _ZBUS_CHAN_NAME(_chan) ""
#endif
#if defined(CONFIG_ZBUS_OBSERVER_NAME)
#define ZBUS_OBSERVER_NAME_INIT(_name) .name = #_name,
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
#define _ZBUS_OBS_NAME(_obs) (_obs)->name
#else
#define ZBUS_OBSERVER_NAME_INIT(_name)
#define _ZBUS_OBS_NAME(_obs) ""
#endif
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS)
#define ZBUS_RUNTIME_OBSERVERS_LIST_DECL(_slist_name) static sys_slist_t _slist_name
#define ZBUS_RUNTIME_OBSERVERS_LIST_INIT(_slist_name) .runtime_observers = &_slist_name,
#else
#define ZBUS_RUNTIME_OBSERVERS_LIST_DECL(_slist_name)
#define ZBUS_RUNTIME_OBSERVERS_LIST_INIT(_slist_name) /* No runtime observers */
#endif
#define _ZBUS_OBS_EXTERN(_name) extern struct zbus_observer _name
#define _ZBUS_CHAN_EXTERN(_name) extern const struct zbus_channel _name
#define ZBUS_REF(_value) &(_value)
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
#define FOR_EACH_FIXED_ARG_NONEMPTY_TERM(F, sep, fixed_arg, ...) \
COND_CODE_0(/* are there zero non-empty arguments ? */ \
NUM_VA_ARGS_LESS_1( \
LIST_DROP_EMPTY(__VA_ARGS__, _)), /* if so, expand to nothing */ \
(), /* otherwise, expand to: */ \
(FOR_EACH_IDX_FIXED_ARG( \
F, sep, fixed_arg, \
LIST_DROP_EMPTY(__VA_ARGS__)) /* plus a final terminator */ \
__DEBRACKET sep))
#define _ZBUS_OBSERVATION_PREFIX(_idx) \
GET_ARG_N(_idx, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, \
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, \
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, \
58, 59, 60, 61, 62, 63)
#define _ZBUS_CHAN_OBSERVATION(_idx, _obs, _chan) \
const STRUCT_SECTION_ITERABLE( \
zbus_channel_observation, \
_CONCAT(_chan, _ZBUS_OBSERVATION_PREFIX(UTIL_INC(_idx)))) = {.chan = &_chan, \
.obs = &_obs}; \
STRUCT_SECTION_ITERABLE(zbus_channel_observation_mask, \
_CONCAT(_CONCAT(_chan, _ZBUS_OBSERVATION_PREFIX(UTIL_INC(_idx))), \
_mask)) = {.enabled = false};
#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
#define _ZBUS_RUNTIME_OBSERVERS(_name) .observers = &(_CONCAT(_observers_, _name)),
#define _ZBUS_RUNTIME_OBSERVERS_DECL(_name) static sys_slist_t _CONCAT(_observers_, _name);
#else
#define _ZBUS_RUNTIME_OBSERVERS(_name)
#define _ZBUS_RUNTIME_OBSERVERS_DECL(_name)
#endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */
/** @endcond */
/* clang-format off */
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
/**
* @brief Add a static channel observervation.
*
* This macro initializes a channel observation by receiving the
* channel and the observer.
*
* @param _chan Channel instance.
* @param _obs Observer instance.
* @param _masked Observation state.
* @param _prio Observer notification sequence priority.
*/
#define ZBUS_CHAN_ADD_OBS_WITH_MASK(_chan, _obs, _masked, _prio) \
const STRUCT_SECTION_ITERABLE(zbus_channel_observation, \
_CONCAT(_CONCAT(_chan, zz), _CONCAT(_prio, _obs))) = { \
.chan = &_chan, \
.obs = &_obs, \
}; \
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
STRUCT_SECTION_ITERABLE(zbus_channel_observation_mask, \
_CONCAT(_CONCAT(_CONCAT(_chan, zz), _CONCAT(_prio, _obs)), \
_mask)) = {.enabled = _masked}
/* clang-format on */
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
/**
* @brief Add a static channel observervation.
*
* This macro initializes a channel observation by receiving the
* channel and the observer.
*
* @param _chan Channel instance.
* @param _obs Observer instance.
* @param _prio Observer notification sequence priority.
*/
#define ZBUS_CHAN_ADD_OBS(_chan, _obs, _prio) ZBUS_CHAN_ADD_OBS_WITH_MASK(_chan, _obs, false, _prio)
/**
* @def ZBUS_OBS_DECLARE
* This macro list the observers to be used in a file. Internally, it declares the observers with
* the extern statement. Note it is only necessary when the observers are declared outside the file.
*/
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
#define ZBUS_OBS_DECLARE(...) FOR_EACH_NONEMPTY_TERM(_ZBUS_OBS_EXTERN, (;), __VA_ARGS__)
/**
* @def ZBUS_CHAN_DECLARE
* This macro list the channels to be used in a file. Internally, it declares the channels with the
* extern statement. Note it is only necessary when the channels are declared outside the file.
*/
#define ZBUS_CHAN_DECLARE(...) FOR_EACH(_ZBUS_CHAN_EXTERN, (;), __VA_ARGS__)
/**
* @def ZBUS_OBSERVERS_EMPTY
* This macro indicates the channel has no observers.
*/
#define ZBUS_OBSERVERS_EMPTY
/**
* @def ZBUS_OBSERVERS
* This macro indicates the channel has listed observers. Note the sequence of observer notification
* will follow the same as listed.
*/
#define ZBUS_OBSERVERS(...) __VA_ARGS__
/* clang-format off */
/**
* @brief Zbus channel definition.
*
* This macro defines a channel.
*
* @param _name The channel's name.
* @param _type The Message type. It must be a struct or union.
* @param _validator The validator function.
* @param _user_data A pointer to the user data.
*
* @see struct zbus_channel
* @param _observers The observers list. The sequence indicates the priority of the observer. The
* first the highest priority.
* @param _init_val The message initialization.
*/
#define ZBUS_CHAN_DEFINE(_name, _type, _validator, _user_data, _observers, _init_val) \
static _type _CONCAT(_zbus_message_, _name) = _init_val; \
static struct zbus_channel_data _CONCAT(_zbus_chan_data_, _name) = { \
.observers_start_idx = -1, \
.observers_end_idx = -1, \
IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
.highest_observer_priority = ZBUS_MIN_THREAD_PRIORITY, \
)) \
}; \
static K_MUTEX_DEFINE(_CONCAT(_zbus_mutex_, _name)); \
_ZBUS_CPP_EXTERN const STRUCT_SECTION_ITERABLE(zbus_channel, _name) = { \
ZBUS_CHANNEL_NAME_INIT(_name) /* Maybe removed */ \
.message = &_CONCAT(_zbus_message_, _name), \
.message_size = sizeof(_type), \
.user_data = _user_data, \
.validator = _validator, \
.data = &_CONCAT(_zbus_chan_data_, _name), \
IF_ENABLED(ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION, ( \
.msg_subscriber_pool = &_zbus_msg_subscribers_pool, \
)) \
}; \
/* Extern declaration of observers */ \
ZBUS_OBS_DECLARE(_observers); \
/* Create all channel observations from observers list */ \
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
FOR_EACH_FIXED_ARG_NONEMPTY_TERM(_ZBUS_CHAN_OBSERVATION, (;), _name, _observers)
/* clang-format on */
/**
* @brief Initialize a message.
*
* This macro initializes a message by passing the values to initialize the message struct
* or union.
*
* @param[in] _val Variadic with the initial values. ``ZBUS_INIT(0)`` means ``{0}``, as
* ZBUS_INIT(.a=10, .b=30) means ``{.a=10, .b=30}``.
*/
#define ZBUS_MSG_INIT(_val, ...) \
{ \
_val, ##__VA_ARGS__ \
}
/* clang-format off */
/**
* @brief Define and initialize a subscriber.
*
* This macro defines an observer of subscriber type. It defines a message queue where the
* subscriber will receive the notification asynchronously, and initialize the ``struct
* zbus_observer`` defining the subscriber.
*
* @param[in] _name The subscriber's name.
* @param[in] _queue_size The notification queue's size.
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
* @param[in] _enable The subscriber initial enable state.
*/
#define ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, _enable) \
K_MSGQ_DEFINE(_zbus_observer_queue_##_name, \
sizeof(const struct zbus_channel *), \
_queue_size, sizeof(const struct zbus_channel *) \
); \
static struct zbus_observer_data _CONCAT(_zbus_obs_data_, _name) = { \
.enabled = _enable, \
IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
.priority = ZBUS_MIN_THREAD_PRIORITY, \
)) \
}; \
STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \
ZBUS_OBSERVER_NAME_INIT(_name) /* Name field */ \
.type = ZBUS_OBSERVER_SUBSCRIBER_TYPE, \
.data = &_CONCAT(_zbus_obs_data_, _name), \
.queue = &_zbus_observer_queue_##_name, \
}
/* clang-format on */
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
/**
* @brief Define and initialize a subscriber.
*
* This macro defines an observer of subscriber type. It defines a message queue where the
* subscriber will receive the notification asynchronously, and initialize the ``struct
* zbus_observer`` defining the subscriber. The subscribers are defined in the enabled
* state with this macro.
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
*
* @param[in] _name The subscriber's name.
* @param[in] _queue_size The notification queue's size.
*/
#define ZBUS_SUBSCRIBER_DEFINE(_name, _queue_size) \
ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, true)
/* clang-format off */
/**
* @brief Define and initialize a listener.
*
* This macro defines an observer of listener type. This macro establishes the callback where the
* listener will be notified synchronously, and initialize the ``struct zbus_observer`` defining the
* listener.
*
* @param[in] _name The listener's name.
* @param[in] _cb The callback function.
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
* @param[in] _enable The listener initial enable state.
*/
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
#define ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable) \
static struct zbus_observer_data _CONCAT(_zbus_obs_data_, _name) = { \
.enabled = _enable, \
IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
.priority = ZBUS_MIN_THREAD_PRIORITY, \
)) \
}; \
STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \
ZBUS_OBSERVER_NAME_INIT(_name) /* Name field */ \
.type = ZBUS_OBSERVER_LISTENER_TYPE, \
.data = &_CONCAT(_zbus_obs_data_, _name), \
.callback = (_cb) \
}
/* clang-format on */
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
/**
* @brief Define and initialize a listener.
*
* This macro defines an observer of listener type. This macro establishes the callback where the
* listener will be notified synchronously and initialize the ``struct zbus_observer`` defining the
* listener. The listeners are defined in the enabled state with this macro.
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
*
* @param[in] _name The listener's name.
* @param[in] _cb The callback function.
*/
#define ZBUS_LISTENER_DEFINE(_name, _cb) ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, true)
/* clang-format off */
/**
* @brief Define and initialize a message subscriber.
*
* This macro defines an observer of @ref ZBUS_OBSERVER_SUBSCRIBER_TYPE type. It defines a FIFO
* where the subscriber will receive the message asynchronously and initialize the @ref
* zbus_observer defining the subscriber.
*
* @param[in] _name The subscriber's name.
* @param[in] _enable The subscriber's initial state.
*/
#define ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _enable) \
static K_FIFO_DEFINE(_zbus_observer_fifo_##_name); \
static struct zbus_observer_data _CONCAT(_zbus_obs_data_, _name) = { \
.enabled = _enable, \
IF_ENABLED(CONFIG_ZBUS_PRIORITY_BOOST, ( \
.priority = ZBUS_MIN_THREAD_PRIORITY, \
)) \
}; \
STRUCT_SECTION_ITERABLE(zbus_observer, _name) = { \
ZBUS_OBSERVER_NAME_INIT(_name) /* Name field */ \
.type = ZBUS_OBSERVER_MSG_SUBSCRIBER_TYPE, \
.data = &_CONCAT(_zbus_obs_data_, _name), \
.message_fifo = &_zbus_observer_fifo_##_name, \
}
/* clang-format on */
/**
* @brief Define and initialize an enabled message subscriber.
*
* This macro defines an observer of message subscriber type. It defines a FIFO where the
* subscriber will receive the message asynchronously and initialize the @ref
* zbus_observer defining the subscriber. The message subscribers are defined in the enabled state
* with this macro.
*
* @param[in] _name The subscriber's name.
*/
#define ZBUS_MSG_SUBSCRIBER_DEFINE(_name) ZBUS_MSG_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, true)
/**
*
* @brief Publish to a channel
*
* This routine publishes a message to a channel.
*
* @param chan The channel's reference.
* @param msg Reference to the message where the publish function copies the channel's
* message data from.
* @param timeout Waiting period to publish the channel,
* or one of the special values K_NO_WAIT and K_FOREVER.
*
* @retval 0 Channel published.
* @retval -ENOMSG The message is invalid based on the validator function or some of the
* observers could not receive the notification.
* @retval -EBUSY The channel is busy.
* @retval -EAGAIN Waiting period timed out.
* @retval -EFAULT A parameter is incorrect, the notification could not be sent to one or more
* observer, or the function context is invalid (inside an ISR). The function only returns this
* value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
*/
int zbus_chan_pub(const struct zbus_channel *chan, const void *msg, k_timeout_t timeout);
/**
* @brief Read a channel
*
* This routine reads a message from a channel.
*
* @param[in] chan The channel's reference.
* @param[out] msg Reference to the message where the read function copies the channel's
* message data to.
* @param[in] timeout Waiting period to read the channel,
* or one of the special values K_NO_WAIT and K_FOREVER.
*
* @retval 0 Channel read.
* @retval -EBUSY The channel is busy.
* @retval -EAGAIN Waiting period timed out.
* @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
* function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
*/
int zbus_chan_read(const struct zbus_channel *chan, void *msg, k_timeout_t timeout);
/**
* @brief Claim a channel
*
* This routine claims a channel. During the claiming period the channel is blocked for publishing,
* reading, notifying or claiming again. Finishing is the only available action.
*
* @warning After calling this routine, the channel cannot be used by other
* thread until the zbus_chan_finish routine is performed.
*
* @warning This routine should only be called once before a zbus_chan_finish.
*
* @param[in] chan The channel's reference.
* @param[in] timeout Waiting period to claim the channel,
* or one of the special values K_NO_WAIT and K_FOREVER.
*
* @retval 0 Channel claimed.
* @retval -EBUSY The channel is busy.
* @retval -EAGAIN Waiting period timed out.
* @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
* function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
*/
int zbus_chan_claim(const struct zbus_channel *chan, k_timeout_t timeout);
/**
* @brief Finish a channel claim.
*
* This routine finishes a channel claim. After calling this routine with success, the channel will
* be able to be used by other thread.
*
* @warning This routine must only be used after a zbus_chan_claim.
*
* @param chan The channel's reference.
*
* @retval 0 Channel finished.
* @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
* function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
*/
int zbus_chan_finish(const struct zbus_channel *chan);
/**
* @brief Force a channel notification.
*
* This routine forces the event dispatcher to notify the channel's observers even if the message
* has no changes. Note this function could be useful after claiming/finishing actions.
*
* @param chan The channel's reference.
* @param timeout Waiting period to notify the channel,
* or one of the special values K_NO_WAIT and K_FOREVER.
*
* @retval 0 Channel notified.
* @retval -EBUSY The channel's semaphore returned without waiting.
* @retval -EAGAIN Timeout to take the channel's semaphore.
* @retval -ENOMEM There is not more buffer on the messgage buffers pool.
* @retval -EFAULT A parameter is incorrect, the notification could not be sent to one or more
* observer, or the function context is invalid (inside an ISR). The function only returns this
* value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
*/
int zbus_chan_notify(const struct zbus_channel *chan, k_timeout_t timeout);
#if defined(CONFIG_ZBUS_CHANNEL_NAME) || defined(__DOXYGEN__)
/**
* @brief Get the channel's name.
*
* This routine returns the channel's name reference.
*
* @param chan The channel's reference.
*
* @return Channel's name reference.
*/
static inline const char *zbus_chan_name(const struct zbus_channel *chan)
{
__ASSERT(chan != NULL, "chan is required");
return chan->name;
}
#endif
/**
* @brief Get the reference for a channel message directly.
*
* This routine returns the reference of a channel message.
*
* @warning This function must only be used directly for already locked channels. This
* can be done inside a listener for the receiving channel or after claim a channel.
*
* @param chan The channel's reference.
*
* @return Channel's message reference.
*/
static inline void *zbus_chan_msg(const struct zbus_channel *chan)
{
__ASSERT(chan != NULL, "chan is required");
return chan->message;
}
/**
* @brief Get a constant reference for a channel message directly.
*
* This routine returns a constant reference of a channel message. This should be used
* inside listeners to access the message directly. In this way zbus prevents the listener of
* changing the notifying channel's message during the notification process.
*
* @warning This function must only be used directly for already locked channels. This
* can be done inside a listener for the receiving channel or after claim a channel.
*
* @param chan The channel's constant reference.
*
* @return A constant channel's message reference.
*/
static inline const void *zbus_chan_const_msg(const struct zbus_channel *chan)
{
__ASSERT(chan != NULL, "chan is required");
return chan->message;
}
/**
* @brief Get the channel's message size.
*
* This routine returns the channel's message size.
*
* @param chan The channel's reference.
*
* @return Channel's message size.
*/
static inline uint16_t zbus_chan_msg_size(const struct zbus_channel *chan)
{
__ASSERT(chan != NULL, "chan is required");
return chan->message_size;
}
/**
* @brief Get the channel's user data.
*
* This routine returns the channel's user data.
*
* @param chan The channel's reference.
*
* @return Channel's user data.
*/
static inline void *zbus_chan_user_data(const struct zbus_channel *chan)
{
__ASSERT(chan != NULL, "chan is required");
return chan->user_data;
}
#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION) || defined(__DOXYGEN__)
/**
* @brief Set the channel's msg subscriber `net_buf` pool.
*
* @param chan The channel's reference.
* @param pool The reference to the `net_buf` memory pool.
*/
static inline void zbus_chan_set_msg_sub_pool(const struct zbus_channel *chan,
struct net_buf_pool *pool)
{
__ASSERT(chan != NULL, "chan is required");
__ASSERT(pool != NULL, "pool is required");
chan->data->msg_subscriber_pool = pool;
}
#endif /* ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION */
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
/**
* @brief Add an observer to a channel.
*
* This routine adds an observer to the channel.
*
* @param chan The channel's reference.
* @param obs The observer's reference to be added.
* @param timeout Waiting period to add an observer,
* or one of the special values K_NO_WAIT and K_FOREVER.
*
* @retval 0 Observer added to the channel.
* @retval -EALREADY The observer is already present in the channel's runtime observers list.
* @retval -ENOMEM Returned without waiting.
* @retval -EAGAIN Waiting period timed out.
* @retval -EINVAL Some parameter is invalid.
*/
int zbus_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observer *obs,
k_timeout_t timeout);
/**
* @brief Remove an observer from a channel.
*
* This routine removes an observer to the channel.
*
* @param chan The channel's reference.
* @param obs The observer's reference to be removed.
* @param timeout Waiting period to remove an observer,
* or one of the special values K_NO_WAIT and K_FOREVER.
*
* @retval 0 Observer removed to the channel.
* @retval -EINVAL Invalid data supplied.
* @retval -EBUSY Returned without waiting.
* @retval -EAGAIN Waiting period timed out.
* @retval -ENODATA no observer found in channel's runtime observer list.
* @retval -ENOMEM Returned without waiting.
*/
int zbus_chan_rm_obs(const struct zbus_channel *chan, const struct zbus_observer *obs,
k_timeout_t timeout);
/** @cond INTERNAL_HIDDEN */
struct zbus_observer_node {
sys_snode_t node;
const struct zbus_observer *obs;
};
/** @endcond */
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
#endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */
/**
* @brief Change the observer state.
*
* This routine changes the observer state. A channel when disabled will not receive
* notifications from the event dispatcher.
*
* @param[in] obs The observer's reference.
* @param[in] enabled State to be. When false the observer stops to receive notifications.
*
* @retval 0 Observer set enable.
* @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
* function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
*/
int zbus_obs_set_enable(struct zbus_observer *obs, bool enabled);
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
/**
* @brief Get the observer state.
*
* This routine retrieves the observer state.
*
* @param[in] obs The observer's reference.
* @param[out] enable The boolean output's reference.
*
* @return Observer state.
*/
static inline int zbus_obs_is_enabled(struct zbus_observer *obs, bool *enable)
{
_ZBUS_ASSERT(obs != NULL, "obs is required");
_ZBUS_ASSERT(enable != NULL, "enable is required");
*enable = obs->data->enabled;
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
return 0;
}
/**
* @brief Mask notifications from a channel to an observer.
*
* The observer can mask notifications from a specific observing channel by calling this function.
*
* @param obs The observer's reference to be added.
* @param chan The channel's reference.
* @param masked The mask state. When the mask is true, the observer will not receive notifications
* from the channel.
*
* @retval 0 Channel notifications masked to the observer.
* @retval -ESRCH No observation found for the related pair chan/obs.
* @retval -EINVAL Some parameter is invalid.
*/
int zbus_obs_set_chan_notification_mask(const struct zbus_observer *obs,
const struct zbus_channel *chan, bool masked);
/**
* @brief Get the notifications masking state from a channel to an observer.
*
* @param obs The observer's reference to be added.
* @param chan The channel's reference.
* @param[out] masked The mask state. When the mask is true, the observer will not receive
* notifications from the channel.
*
* @retval 0 Retrieved the masked state.
* @retval -ESRCH No observation found for the related pair chan/obs.
* @retval -EINVAL Some parameter is invalid.
*/
int zbus_obs_is_chan_notification_masked(const struct zbus_observer *obs,
const struct zbus_channel *chan, bool *masked);
#if defined(CONFIG_ZBUS_OBSERVER_NAME) || defined(__DOXYGEN__)
/**
* @brief Get the observer's name.
*
* This routine returns the observer's name reference.
*
* @param obs The observer's reference.
*
* @return The observer's name reference.
*/
static inline const char *zbus_obs_name(const struct zbus_observer *obs)
{
__ASSERT(obs != NULL, "obs is required");
return obs->name;
}
#endif
#if defined(CONFIG_ZBUS_PRIORITY_BOOST) || defined(__DOXYGEN__)
/**
* @brief Set the observer thread priority by attaching it to a thread.
*
* @param[in] obs The observer's reference.
*
* @retval 0 Observer detached from the thread.
* @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
* function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
*/
int zbus_obs_attach_to_thread(const struct zbus_observer *obs);
/**
* @brief Clear the observer thread priority by detaching it from a thread.
*
* @param[in] obs The observer's reference.
*
* @retval 0 Observer detached from the thread.
* @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
* function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
*/
int zbus_obs_detach_from_thread(const struct zbus_observer *obs);
#endif /* CONFIG_ZBUS_PRIORITY_BOOST */
/**
* @brief Wait for a channel notification.
*
* This routine makes the subscriber to wait a notification. The notification comes as a channel
* reference.
*
* @param[in] sub The subscriber's reference.
* @param[out] chan The notification channel's reference.
* @param[in] timeout Waiting period for a notification arrival,
* or one of the special values K_NO_WAIT and K_FOREVER.
*
* @retval 0 Notification received.
* @retval -ENOMSG Returned without waiting.
* @retval -EAGAIN Waiting period timed out.
* @retval -EINVAL The observer is not a subscriber.
* @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
* function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
*/
int zbus_sub_wait(const struct zbus_observer *sub, const struct zbus_channel **chan,
k_timeout_t timeout);
#if defined(CONFIG_ZBUS_MSG_SUBSCRIBER) || defined(__DOXYGEN__)
/**
* @brief Wait for a channel message.
*
* This routine makes the subscriber wait for the new message in case of channel publication.
*
* @param[in] sub The subscriber's reference.
* @param[out] chan The notification channel's reference.
* @param[out] msg A reference to a copy of the published message.
* @param[in] timeout Waiting period for a notification arrival,
* or one of the special values, K_NO_WAIT and K_FOREVER.
*
* @retval 0 Message received.
* @retval -EINVAL The observer is not a subscriber.
* @retval -ENOMSG Could not retrieve the net_buf from the subscriber FIFO.
* @retval -EILSEQ Received an invalid channel reference.
* @retval -EFAULT A parameter is incorrect, or the function context is invalid (inside an ISR). The
* function only returns this value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
*/
int zbus_sub_wait_msg(const struct zbus_observer *sub, const struct zbus_channel **chan, void *msg,
k_timeout_t timeout);
#endif /* CONFIG_ZBUS_MSG_SUBSCRIBER */
/**
*
* @brief Iterate over channels.
*
* Enables the developer to iterate over the channels giving to this function an
* iterator_func which is called for each channel. If the iterator_func returns false all
* the iteration stops.
*
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
* @param[in] iterator_func The function that will be execute on each iteration.
*
* @retval true Iterator executed for all channels.
* @retval false Iterator could not be executed. Some iterate returned false.
*/
bool zbus_iterate_over_channels(bool (*iterator_func)(const struct zbus_channel *chan));
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
/**
*
* @brief Iterate over channels with user data.
*
* Enables the developer to iterate over the channels giving to this function an
* iterator_func which is called for each channel. If the iterator_func returns false all
* the iteration stops.
*
* @param[in] iterator_func The function that will be execute on each iteration.
* @param[in] user_data The user data that can be passed in the function.
*
* @retval true Iterator executed for all channels.
* @retval false Iterator could not be executed. Some iterate returned false.
*/
bool zbus_iterate_over_channels_with_user_data(
bool (*iterator_func)(const struct zbus_channel *chan, void *user_data), void *user_data);
/**
*
* @brief Iterate over observers.
*
* Enables the developer to iterate over the observers giving to this function an
* iterator_func which is called for each observer. If the iterator_func returns false all
* the iteration stops.
*
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
* @param[in] iterator_func The function that will be execute on each iteration.
*
* @retval true Iterator executed for all channels.
* @retval false Iterator could not be executed. Some iterate returned false.
*/
bool zbus_iterate_over_observers(bool (*iterator_func)(const struct zbus_observer *obs));
zbus: improve the way of storing observers ZBus stores observers in two ways: statically using a list and dynamically using a memory slab. Both present limitations. Static observers work only for channel definition. The dynamic observers rely on a memory slab that forces the user to manage its size to avoid issues with adding observers. This commit fixes the static allocation problem by using the iterable sections for allocating observation data and replacing the VDED execution sequence since now it is possible to prioritize static observer execution. All the runtime observers are dynamically allocated on the heap instead of a specific memory pool. BREAK changes (only internal, not APIs): * ZBus channel metadata changed. Remove the observers' static array pointer. Rename the `runtime_observers` pointer to `observers`. Add `observer_start_idx` and `observer_end_idx`; * Change the VDED execution sequence. The position (on definition time), the priority in conjunction with the lexical order, is considered for static post-definition time observers. At last, the runtime observer follows the adding sequence; * Replace the `CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE` with `CONFIG_ZBUS_RUNTIME_OBSERVERS`. New APIs: * New iterable section iterators (for channels and observers) can now receive a user_data pointer to keep context between the function calls; * New `ZBUS_LISTENER_DEFINE_WITH_ENABLE(_name, _cb, _enable)` and `ZBUS_SUBSCRIBER_DEFINE_WITH_ENABLE(_name, _queue_size, enable)` that enable developers define disabled observers. They need to be enabled during runtime to receive notifications from the bus; * `ZBUS_CHAN_ADD_OBS` macro for adding post-definition static observers of a channel. Important changes: * Move the ZBus LD file content to the `common-ram.ld` LD file. That was necessary to make ZBus compatible with some Xtensa and RISCV boards. Signed-off-by: Rodrigo Peixoto <rodrigopex@gmail.com>
2023-07-22 17:55:48 +02:00
/**
*
* @brief Iterate over observers with user data.
*
* Enables the developer to iterate over the observers giving to this function an
* iterator_func which is called for each observer. If the iterator_func returns false all
* the iteration stops.
*
* @param[in] iterator_func The function that will be execute on each iteration.
* @param[in] user_data The user data that can be passed in the function.
*
* @retval true Iterator executed for all channels.
* @retval false Iterator could not be executed. Some iterate returned false.
*/
bool zbus_iterate_over_observers_with_user_data(
bool (*iterator_func)(const struct zbus_observer *obs, void *user_data), void *user_data);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_ZBUS_H_ */