zbus: optional publishing statistics

Add optional statistics around the channel publishing action. Store the
time a channel was last published to, and a total publish count.

This information can be used to determine how old a given channels data
is, and an average channel publishing frequency.

Signed-off-by: Jordan Yates <jordan@embeint.com>
This commit is contained in:
Jordan Yates 2024-07-08 14:38:47 +10:00 committed by Anas Nashif
parent f2f1496156
commit e45ab126ea
3 changed files with 98 additions and 0 deletions

View File

@ -62,6 +62,13 @@ struct zbus_channel_data {
*/
struct net_buf_pool *msg_subscriber_pool;
#endif /* ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION */
#if defined(CONFIG_ZBUS_CHANNEL_PUBLISH_STATS) || defined(__DOXYGEN__)
/** Kernel timestamp of the last publish action on this channel */
k_ticks_t publish_timestamp;
/** Number of times data has been published to this channel */
uint32_t publish_count;
#endif /* CONFIG_ZBUS_CHANNEL_PUBLISH_STATS */
};
/**
@ -722,6 +729,89 @@ static inline void zbus_chan_set_msg_sub_pool(const struct zbus_channel *chan,
#endif /* ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION */
#if defined(CONFIG_ZBUS_CHANNEL_PUBLISH_STATS) || defined(__DOXYGEN__)
/**
* @brief Update the publishing statistics for a channel
*
* This function updates the publishing statistics for the @ref zbus_chan_claim ->
* @ref zbus_chan_finish workflow, which cannot automatically determine whether
* new data has been published or not.
*
* @warning This function must only be used directly for already locked channels.
*
* @param chan The channel's reference.
*/
static inline void zbus_chan_pub_stats_update(const struct zbus_channel *chan)
{
__ASSERT(chan != NULL, "chan is required");
chan->data->publish_timestamp = k_uptime_ticks();
chan->data->publish_count += 1;
}
/**
* @brief Get the time a channel was last published to.
*
* @note Will return 0 if channel has not yet been published to.
*
* @param chan The channel's reference.
*
* @return The kernel timestamp of the last publishing action.
*/
static inline k_ticks_t zbus_chan_pub_stats_last_time(const struct zbus_channel *chan)
{
__ASSERT(chan != NULL, "chan is required");
return chan->data->publish_timestamp;
}
/**
* @brief Get the number of times a channel has been published to.
*
* @note Will return 0 if channel has not yet been published to.
*
* @param chan The channel's reference.
*
* @return The number of times a channel has been published to.
*/
static inline uint32_t zbus_chan_pub_stats_count(const struct zbus_channel *chan)
{
__ASSERT(chan != NULL, "chan is required");
return chan->data->publish_count;
}
/**
* @brief Get the average period between publishes to a channel.
*
* @note Will return 0 if channel has not yet been published to.
*
* @param chan The channel's reference.
*
* @return Average duration in milliseconds between publishes.
*/
static inline uint32_t zbus_chan_pub_stats_avg_period(const struct zbus_channel *chan)
{
__ASSERT(chan != NULL, "chan is required");
/* Not yet published, period = 0ms */
if (chan->data->publish_count == 0) {
return 0;
}
/* Average period across application runtime */
return k_uptime_get() / chan->data->publish_count;
}
#else
static inline void zbus_chan_pub_stats_update(const struct zbus_channel *chan)
{
(void)chan;
}
#endif /* CONFIG_ZBUS_CHANNEL_PUBLISH_STATS */
#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
/**

View File

@ -19,6 +19,9 @@ config ZBUS_CHANNEL_NAME
config ZBUS_OBSERVER_NAME
bool "Observer name field"
config ZBUS_CHANNEL_PUBLISH_STATS
bool "Channel publishing statistics (Timestamp and count)"
config ZBUS_MSG_SUBSCRIBER
select NET_BUF
bool "Message subscribers will receive all messages in sequence."

View File

@ -355,6 +355,11 @@ int zbus_chan_pub(const struct zbus_channel *chan, const void *msg, k_timeout_t
return err;
}
#if defined(CONFIG_ZBUS_CHANNEL_PUBLISH_STATS)
chan->data->publish_timestamp = k_uptime_ticks();
chan->data->publish_count += 1;
#endif /* CONFIG_ZBUS_CHANNEL_PUBLISH_STATS */
memcpy(chan->message, msg, chan->message_size);
err = _zbus_vded_exec(chan, end_time);