blob: 1e963a3875bc4ac02a162fe05d753dd8b6e0c95e [file] [log] [blame]
/*
* Copyright (c) 2022 Rodrigo Peixoto <rodrigopex@gmail.com>
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/zbus/zbus.h>
LOG_MODULE_DECLARE(zbus, CONFIG_ZBUS_LOG_LEVEL);
struct version_msg {
uint8_t major;
uint8_t minor;
uint16_t build;
};
struct acc_msg {
int x;
int y;
int z;
};
ZBUS_CHAN_DEFINE(version_chan, /* Name */
struct version_msg, /* Message type */
NULL, /* Validator */
NULL, /* User data */
ZBUS_OBSERVERS_EMPTY, /* observers */
ZBUS_MSG_INIT(.major = 0, .minor = 1,
.build = 2) /* Initial value major 0, minor 1, build 2 */
);
ZBUS_CHAN_DEFINE(acc_data_chan, /* Name */
struct acc_msg, /* Message type */
NULL, /* Validator */
NULL, /* User data */
ZBUS_OBSERVERS(foo_lis, bar_sub), /* observers */
ZBUS_MSG_INIT(.x = 0, .y = 0, .z = 0) /* Initial value */
);
static bool simple_chan_validator(const void *msg, size_t msg_size)
{
ARG_UNUSED(msg_size);
const int *simple = msg;
if ((*simple >= 0) && (*simple < 10)) {
return true;
}
return false;
}
ZBUS_CHAN_DEFINE(simple_chan, /* Name */
int, /* Message type */
simple_chan_validator, /* Validator */
NULL, /* User data */
ZBUS_OBSERVERS_EMPTY, /* observers */
0 /* Initial value is 0 */
);
static void listener_callback_example(const struct zbus_channel *chan)
{
const struct acc_msg *acc = zbus_chan_const_msg(chan);
LOG_INF("From listener -> Acc x=%d, y=%d, z=%d", acc->x, acc->y, acc->z);
}
ZBUS_LISTENER_DEFINE(foo_lis, listener_callback_example);
ZBUS_SUBSCRIBER_DEFINE(bar_sub, 4);
static void subscriber_task(void)
{
const struct zbus_channel *chan;
while (!zbus_sub_wait(&bar_sub, &chan, K_FOREVER)) {
struct acc_msg acc;
if (&acc_data_chan == chan) {
zbus_chan_read(&acc_data_chan, &acc, K_MSEC(500));
LOG_INF("From subscriber -> Acc x=%d, y=%d, z=%d", acc.x, acc.y, acc.z);
}
}
}
K_THREAD_DEFINE(subscriber_task_id, CONFIG_MAIN_STACK_SIZE, subscriber_task, NULL, NULL, NULL, 3, 0,
0);
static bool print_channel_data_iterator(const struct zbus_channel *chan, void *user_data)
{
int *count = user_data;
LOG_INF("%d - Channel %s:", *count, zbus_chan_name(chan));
LOG_INF(" Message size: %d", zbus_chan_msg_size(chan));
LOG_INF(" Observers:");
++(*count);
struct zbus_channel_observation *observation;
for (int16_t i = chan->data->observers_start_idx, limit = chan->data->observers_end_idx;
i < limit; ++i) {
STRUCT_SECTION_GET(zbus_channel_observation, i, &observation);
__ASSERT(observation != NULL, "observation must be not NULL");
LOG_INF(" - %s", observation->obs->name);
}
struct zbus_observer_node *obs_nd, *tmp;
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&chan->data->observers, obs_nd, tmp, node) {
LOG_INF(" - %s", obs_nd->obs->name);
}
return true;
}
static bool print_observer_data_iterator(const struct zbus_observer *obs, void *user_data)
{
int *count = user_data;
LOG_INF("%d - %s %s", *count,
obs->type == ZBUS_OBSERVER_LISTENER_TYPE ? "Listener" : "Subscriber",
zbus_obs_name(obs));
++(*count);
return true;
}
int main(void)
{
int err, value;
struct acc_msg acc1 = {.x = 1, .y = 1, .z = 1};
const struct version_msg *v = zbus_chan_const_msg(&version_chan);
LOG_INF("Sensor sample started raw reading, version %u.%u-%u!", v->major, v->minor,
v->build);
int count = 0;
LOG_INF("Channel list:");
zbus_iterate_over_channels_with_user_data(print_channel_data_iterator, &count);
count = 0;
LOG_INF("Observers list:");
zbus_iterate_over_observers_with_user_data(print_observer_data_iterator, &count);
zbus_chan_pub(&acc_data_chan, &acc1, K_SECONDS(1));
k_msleep(1000);
acc1.x = 2;
acc1.y = 2;
acc1.z = 2;
zbus_chan_pub(&acc_data_chan, &(acc1), K_SECONDS(1));
value = 5;
err = zbus_chan_pub(&simple_chan, &value, K_MSEC(200));
if (err == 0) {
LOG_INF("Pub a valid value to a channel with validator successfully.");
}
value = 15;
err = zbus_chan_pub(&simple_chan, &value, K_MSEC(200));
if (err == -ENOMSG) {
LOG_INF("Pub an invalid value to a channel with validator successfully.");
}
return 0;
}