1 /*
2  * Copyright (c) 2022 Rodrigo Peixoto <rodrigopex@gmail.com>
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include "messages.h"
7 
8 #include <stdint.h>
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/logging/log.h>
12 #include <zephyr/sys/util_macro.h>
13 #include <zephyr/zbus/zbus.h>
14 LOG_MODULE_DECLARE(zbus, CONFIG_ZBUS_LOG_LEVEL);
15 
16 ZBUS_CHAN_DEFINE(version_chan,	     /* Name */
17 		 struct version_msg, /* Message type */
18 
19 		 NULL,		       /* Validator */
20 		 NULL,		       /* User data */
21 		 ZBUS_OBSERVERS_EMPTY, /* observers */
22 		 ZBUS_MSG_INIT(.major = 0, .minor = 1,
23 			       .build = 1023) /* Initial value major 0, minor 1, build 1023 */
24 );
25 
26 ZBUS_CHAN_DEFINE(sensor_data_chan,  /* Name */
27 		 struct sensor_msg, /* Message type */
28 
29 		 NULL, /* Validator */
30 		 NULL, /* User data */
31 		 ZBUS_OBSERVERS(fast_handler1_lis, fast_handler2_lis, fast_handler3_lis,
32 				delay_handler1_lis, delay_handler2_lis, delay_handler3_lis,
33 				thread_handler1_sub, thread_handler2_sub,
34 				thread_handler3_sub), /* observers */
35 		 ZBUS_MSG_INIT(0)		      /* Initial value {0} */
36 );
37 
fh1_cb(const struct zbus_channel * chan)38 static void fh1_cb(const struct zbus_channel *chan)
39 {
40 	const struct sensor_msg *msg = zbus_chan_const_msg(chan);
41 
42 	LOG_INF("Sensor msg processed by CALLBACK fh1: temp = %u, press = %u, humidity = %u",
43 		msg->temp, msg->press, msg->humidity);
44 }
45 
46 ZBUS_LISTENER_DEFINE(fast_handler1_lis, fh1_cb);
47 
fh2_cb(const struct zbus_channel * chan)48 static void fh2_cb(const struct zbus_channel *chan)
49 {
50 	const struct sensor_msg *msg = zbus_chan_const_msg(chan);
51 
52 	LOG_INF("Sensor msg processed by CALLBACK fh2: temp = %u, press = %u, humidity = %u",
53 		msg->temp, msg->press, msg->humidity);
54 }
55 
56 ZBUS_LISTENER_DEFINE(fast_handler2_lis, fh2_cb);
57 
fh3_cb(const struct zbus_channel * chan)58 static void fh3_cb(const struct zbus_channel *chan)
59 {
60 	const struct sensor_msg *msg = zbus_chan_const_msg(chan);
61 
62 	LOG_INF("Sensor msg processed by CALLBACK fh3: temp = %u, press = %u, humidity = %u",
63 		msg->temp, msg->press, msg->humidity);
64 }
65 
66 ZBUS_LISTENER_DEFINE(fast_handler3_lis, fh3_cb);
67 
68 struct sensor_wq_info {
69 	struct k_work work;
70 	const struct zbus_channel *chan;
71 	uint8_t handle;
72 };
73 
74 static struct sensor_wq_info wq_handler1 = {.handle = 1};
75 static struct sensor_wq_info wq_handler2 = {.handle = 2};
76 static struct sensor_wq_info wq_handler3 = {.handle = 3};
77 
wq_dh_cb(struct k_work * item)78 static void wq_dh_cb(struct k_work *item)
79 {
80 	struct sensor_msg msg;
81 	struct sensor_wq_info *sens = CONTAINER_OF(item, struct sensor_wq_info, work);
82 
83 	zbus_chan_read(sens->chan, &msg, K_MSEC(200));
84 
85 	LOG_INF("Sensor msg processed by WORK QUEUE handler dh%u: temp = %u, press = %u, "
86 		"humidity = %u",
87 		sens->handle, msg.temp, msg.press, msg.humidity);
88 }
89 
dh1_cb(const struct zbus_channel * chan)90 static void dh1_cb(const struct zbus_channel *chan)
91 {
92 	wq_handler1.chan = chan;
93 
94 	k_work_submit(&wq_handler1.work);
95 }
96 
97 ZBUS_LISTENER_DEFINE(delay_handler1_lis, dh1_cb);
98 
dh2_cb(const struct zbus_channel * chan)99 static void dh2_cb(const struct zbus_channel *chan)
100 {
101 	wq_handler2.chan = chan;
102 
103 	k_work_submit(&wq_handler2.work);
104 }
105 
106 ZBUS_LISTENER_DEFINE(delay_handler2_lis, dh2_cb);
107 
dh3_cb(const struct zbus_channel * chan)108 static void dh3_cb(const struct zbus_channel *chan)
109 {
110 	wq_handler3.chan = chan;
111 
112 	k_work_submit(&wq_handler3.work);
113 }
114 
115 ZBUS_LISTENER_DEFINE(delay_handler3_lis, dh3_cb);
116 
main(void)117 int main(void)
118 {
119 	k_work_init(&wq_handler1.work, wq_dh_cb);
120 	k_work_init(&wq_handler2.work, wq_dh_cb);
121 	k_work_init(&wq_handler3.work, wq_dh_cb);
122 
123 	struct version_msg *v = zbus_chan_msg(&version_chan);
124 
125 	LOG_DBG("Sensor sample started, version %u.%u-%u!", v->major, v->minor, v->build);
126 	return 0;
127 }
128 
129 ZBUS_SUBSCRIBER_DEFINE(thread_handler1_sub, 4);
130 
thread_handler1_task(void)131 static void thread_handler1_task(void)
132 {
133 	const struct zbus_channel *chan;
134 
135 	while (!zbus_sub_wait(&thread_handler1_sub, &chan, K_FOREVER)) {
136 		struct sensor_msg msg;
137 
138 		zbus_chan_read(chan, &msg, K_MSEC(200));
139 
140 		LOG_INF("Sensor msg processed by THREAD handler 1: temp = %u, press = %u, "
141 			"humidity = %u",
142 			msg.temp, msg.press, msg.humidity);
143 	}
144 }
145 
146 K_THREAD_DEFINE(thread_handler1_id, 1024, thread_handler1_task, NULL, NULL, NULL, 3, 0, 0);
147 
148 ZBUS_SUBSCRIBER_DEFINE(thread_handler2_sub, 4);
149 
thread_handler2_task(void)150 static void thread_handler2_task(void)
151 {
152 	const struct zbus_channel *chan;
153 
154 	while (!zbus_sub_wait(&thread_handler2_sub, &chan, K_FOREVER)) {
155 		struct sensor_msg msg;
156 
157 		zbus_chan_read(chan, &msg, K_MSEC(200));
158 
159 		LOG_INF("Sensor msg processed by THREAD handler 2: temp = %u, press = %u, "
160 			"humidity = %u",
161 			msg.temp, msg.press, msg.humidity);
162 	}
163 }
164 
165 K_THREAD_DEFINE(thread_handler2_id, 1024, thread_handler2_task, NULL, NULL, NULL, 3, 0, 0);
166 
167 ZBUS_SUBSCRIBER_DEFINE(thread_handler3_sub, 4);
168 
thread_handler3_task(void)169 static void thread_handler3_task(void)
170 {
171 	const struct zbus_channel *chan;
172 
173 	while (!zbus_sub_wait(&thread_handler3_sub, &chan, K_FOREVER)) {
174 		struct sensor_msg msg;
175 
176 		zbus_chan_read(chan, &msg, K_MSEC(200));
177 
178 		LOG_INF("Sensor msg processed by THREAD handler 3: temp = %u, press = %u, "
179 			"humidity = %u",
180 			msg.temp, msg.press, msg.humidity);
181 	}
182 }
183 
184 K_THREAD_DEFINE(thread_handler3_id, 1024, thread_handler3_task, NULL, NULL, NULL, 3, 0, 0);
185