Skip to content

Commit ab34a9d

Browse files
JordanYateskartben
authored andcommitted
zbus: remove k_malloc dependency for ZBUS_RUNTIME_OBSERVERS
Remove the dependency on the system heap existing when enabling `ZBUS_RUNTIME_OBSERVERS`. Instead the previously allocated memory is required to be provided to `zbus_chan_add_obs` (which can still be allocated through malloc). Signed-off-by: Jordan Yates <[email protected]>
1 parent 8a4bb18 commit ab34a9d

File tree

5 files changed

+45
-56
lines changed

5 files changed

+45
-56
lines changed

include/zephyr/zbus/zbus.h

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -861,24 +861,32 @@ static inline void zbus_chan_pub_stats_update(const struct zbus_channel *chan)
861861

862862
#if defined(CONFIG_ZBUS_RUNTIME_OBSERVERS) || defined(__DOXYGEN__)
863863

864+
/**
865+
* @brief Structure for linking observers to chanels
866+
*/
867+
struct zbus_observer_node {
868+
sys_snode_t node;
869+
const struct zbus_observer *obs;
870+
};
871+
864872
/**
865873
* @brief Add an observer to a channel.
866874
*
867875
* This routine adds an observer to the channel.
868876
*
869877
* @param chan The channel's reference.
870878
* @param obs The observer's reference to be added.
879+
* @param node Persistent structure to link the channel to the observer
871880
* @param timeout Waiting period to add an observer,
872881
* or one of the special values K_NO_WAIT and K_FOREVER.
873882
*
874883
* @retval 0 Observer added to the channel.
875884
* @retval -EALREADY The observer is already present in the channel's runtime observers list.
876-
* @retval -ENOMEM Returned without waiting.
877885
* @retval -EAGAIN Waiting period timed out.
878886
* @retval -EINVAL Some parameter is invalid.
879887
*/
880888
int zbus_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observer *obs,
881-
k_timeout_t timeout);
889+
struct zbus_observer_node *node, k_timeout_t timeout);
882890

883891
/**
884892
* @brief Remove an observer from a channel.
@@ -900,15 +908,6 @@ int zbus_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observe
900908
int zbus_chan_rm_obs(const struct zbus_channel *chan, const struct zbus_observer *obs,
901909
k_timeout_t timeout);
902910

903-
/** @cond INTERNAL_HIDDEN */
904-
905-
struct zbus_observer_node {
906-
sys_snode_t node;
907-
const struct zbus_observer *obs;
908-
};
909-
910-
/** @endcond */
911-
912911
#endif /* CONFIG_ZBUS_RUNTIME_OBSERVERS */
913912

914913
/**

samples/subsys/zbus/runtime_obs_registration/src/main.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,19 @@ int main(void)
4444
LOG_INF("System started");
4545

4646
const struct zbus_channel *chan;
47+
struct zbus_observer_node obs_node;
4748

4849
while (1) {
4950
LOG_INF("Activating filter");
50-
zbus_chan_add_obs(&raw_data_chan, &filter_lis, K_MSEC(200));
51+
zbus_chan_add_obs(&raw_data_chan, &filter_lis, &obs_node, K_MSEC(200));
5152

5253
zbus_sub_wait(&state_change_sub, &chan, K_FOREVER);
5354

5455
LOG_INF("Deactivating filter");
5556
zbus_chan_rm_obs(&raw_data_chan, &filter_lis, K_MSEC(200));
5657

5758
LOG_INF("Bypass filter");
58-
zbus_chan_add_obs(&raw_data_chan, &consumer_sub, K_MSEC(200));
59+
zbus_chan_add_obs(&raw_data_chan, &consumer_sub, &obs_node, K_MSEC(200));
5960

6061
zbus_sub_wait(&state_change_sub, &chan, K_FOREVER);
6162

subsys/zbus/zbus_runtime_observers.c

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
LOG_MODULE_DECLARE(zbus, CONFIG_ZBUS_LOG_LEVEL);
1010

1111
int zbus_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observer *obs,
12-
k_timeout_t timeout)
12+
struct zbus_observer_node *node, k_timeout_t timeout)
1313
{
1414
int err;
1515
struct zbus_observer_node *obs_nd, *tmp;
@@ -18,6 +18,7 @@ int zbus_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observe
1818
_ZBUS_ASSERT(!k_is_in_isr(), "ISR blocked");
1919
_ZBUS_ASSERT(chan != NULL, "chan is required");
2020
_ZBUS_ASSERT(obs != NULL, "obs is required");
21+
_ZBUS_ASSERT(node != NULL, "node is required");
2122

2223
err = k_sem_take(&chan->data->sem, timeout);
2324
if (err) {
@@ -46,19 +47,9 @@ int zbus_chan_add_obs(const struct zbus_channel *chan, const struct zbus_observe
4647
}
4748
}
4849

49-
struct zbus_observer_node *new_obs_nd = k_malloc(sizeof(struct zbus_observer_node));
50+
node->obs = obs;
5051

51-
if (new_obs_nd == NULL) {
52-
LOG_ERR("Could not allocate observer node the heap is full!");
53-
54-
k_sem_give(&chan->data->sem);
55-
56-
return -ENOMEM;
57-
}
58-
59-
new_obs_nd->obs = obs;
60-
61-
sys_slist_append(&chan->data->observers, &new_obs_nd->node);
52+
sys_slist_append(&chan->data->observers, &node->node);
6253

6354
k_sem_give(&chan->data->sem);
6455

@@ -85,8 +76,6 @@ int zbus_chan_rm_obs(const struct zbus_channel *chan, const struct zbus_observer
8576
if (obs_nd->obs == obs) {
8677
sys_slist_remove(&chan->data->observers, &prev_obs_nd->node, &obs_nd->node);
8778

88-
k_free(obs_nd);
89-
9079
k_sem_give(&chan->data->sem);
9180

9281
return 0;

tests/subsys/zbus/runtime_observers_registration/src/main.c

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,16 @@ ZTEST(basic, test_specification_based__zbus_obs_add_rm_obs)
6969
{
7070
count_callback1 = 0;
7171
struct sensor_data_msg sd = {.a = 10, .b = 100};
72+
static struct zbus_observer_node n1, n2, n3, n4, n5, n6;
7273

7374
/* Tyring to add same static observer as one dynamic */
74-
zassert_equal(-EEXIST, zbus_chan_add_obs(&chan2, &lis2, K_MSEC(200)), NULL);
75+
zassert_equal(-EEXIST, zbus_chan_add_obs(&chan2, &lis2, &n2, K_MSEC(200)), NULL);
7576

7677
zassert_equal(0, zbus_chan_pub(&chan1, &sd, K_MSEC(500)), NULL);
7778
zassert_equal(count_callback1, 0, "The counter could not be more than zero, no obs");
7879

79-
zassert_equal(0, zbus_chan_add_obs(&chan1, &lis1, K_MSEC(200)), NULL);
80-
zassert_equal(-EALREADY, zbus_chan_add_obs(&chan1, &lis1, K_MSEC(200)),
80+
zassert_equal(0, zbus_chan_add_obs(&chan1, &lis1, &n1, K_MSEC(200)), NULL);
81+
zassert_equal(-EALREADY, zbus_chan_add_obs(&chan1, &lis1, &n1, K_MSEC(200)),
8182
"It cannot be added twice");
8283

8384
zassert_equal(0, zbus_chan_pub(&chan1, &sd, K_MSEC(500)), NULL);
@@ -98,30 +99,21 @@ ZTEST(basic, test_specification_based__zbus_obs_add_rm_obs)
9899
zassert_equal(0, zbus_chan_pub(&chan2, &sd, K_MSEC(500)), NULL);
99100
zassert_equal(count_callback2, 1, "The counter could not be more than zero, no obs");
100101

101-
zassert_equal(0, zbus_chan_add_obs(&chan2, &lis3, K_MSEC(200)), NULL);
102+
zassert_equal(0, zbus_chan_add_obs(&chan2, &lis3, &n3, K_MSEC(200)), NULL);
102103

103-
zassert_equal(-EALREADY, zbus_chan_add_obs(&chan2, &lis3, K_MSEC(200)),
104+
zassert_equal(-EALREADY, zbus_chan_add_obs(&chan2, &lis3, &n3, K_MSEC(200)),
104105
"It cannot be added twice");
105106

106107
zassert_equal(0, zbus_chan_pub(&chan2, &sd, K_MSEC(500)), NULL);
107108
zassert_equal(count_callback2, 3, "The counter could not be more than zero, no obs, %d",
108109
count_callback2);
109110
count_callback2 = 0;
110-
zassert_equal(0, zbus_chan_add_obs(&chan2, &sub1, K_MSEC(200)), NULL);
111-
zassert_equal(0, zbus_chan_add_obs(&chan2, &sub2, K_MSEC(200)), NULL);
112-
zassert_equal(0, zbus_chan_add_obs(&chan2, &lis4, K_MSEC(200)), "It must add the obs");
113-
zassert_equal(0, zbus_chan_add_obs(&chan2, &lis5, K_MSEC(200)), "It must add the obs");
114-
zassert_equal(0, zbus_chan_add_obs(&chan2, &lis6, K_MSEC(200)), "It must add the obs");
111+
zassert_equal(0, zbus_chan_add_obs(&chan2, &sub1, &n1, K_MSEC(200)), NULL);
112+
zassert_equal(0, zbus_chan_add_obs(&chan2, &sub2, &n2, K_MSEC(200)), NULL);
113+
zassert_equal(0, zbus_chan_add_obs(&chan2, &lis4, &n4, K_MSEC(200)), "It must add the obs");
114+
zassert_equal(0, zbus_chan_add_obs(&chan2, &lis5, &n5, K_MSEC(200)), "It must add the obs");
115+
zassert_equal(0, zbus_chan_add_obs(&chan2, &lis6, &n6, K_MSEC(200)), "It must add the obs");
115116

116-
/* Make the heap full */
117-
void *mem;
118-
119-
do {
120-
mem = k_malloc(1);
121-
} while (mem != NULL);
122-
123-
/* With the heap full it will not be possible to add another obs */
124-
zassert_equal(-ENOMEM, zbus_chan_add_obs(&chan2, &lis7, K_MSEC(200)), NULL);
125117
zassert_equal(0, zbus_chan_pub(&chan2, &sd, K_MSEC(500)), NULL);
126118
zassert_equal(count_callback2, 5, NULL);
127119

@@ -142,7 +134,9 @@ static struct aux2_wq_data wq_handler;
142134

143135
static void wq_dh_cb(struct k_work *item)
144136
{
145-
zassert_equal(-EAGAIN, zbus_chan_add_obs(&chan2, &sub1, K_MSEC(200)), NULL);
137+
static struct zbus_observer_node node;
138+
139+
zassert_equal(-EAGAIN, zbus_chan_add_obs(&chan2, &sub1, &node, K_MSEC(200)), NULL);
146140
zassert_equal(-EAGAIN, zbus_chan_rm_obs(&chan2, &sub2, K_MSEC(200)), NULL);
147141
}
148142

@@ -192,11 +186,12 @@ ZBUS_CHAN_ADD_OBS(chan4, prio_lis4, 2);
192186
ZTEST(basic, test_specification_based__zbus_obs_priority)
193187
{
194188
struct sensor_data_msg sd = {.a = 70, .b = 116};
189+
static struct zbus_observer_node n1, n2;
195190

196191
execution_sequence_idx = 0;
197192

198-
zassert_equal(0, zbus_chan_add_obs(&chan4, &prio_lis2, K_MSEC(200)), NULL);
199-
zassert_equal(0, zbus_chan_add_obs(&chan4, &prio_lis1, K_MSEC(200)), NULL);
193+
zassert_equal(0, zbus_chan_add_obs(&chan4, &prio_lis2, &n1, K_MSEC(200)), NULL);
194+
zassert_equal(0, zbus_chan_add_obs(&chan4, &prio_lis1, &n2, K_MSEC(200)), NULL);
200195

201196
zassert_equal(0, zbus_chan_pub(&chan4, &sd, K_MSEC(500)), NULL);
202197

tests/subsys/zbus/unittests/src/main.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ static struct action_msg ga;
137137

138138
static void isr_handler(const void *operation)
139139
{
140+
static struct zbus_observer_node fast_node, aux_node;
140141
enum operation *op = (enum operation *)operation;
141142

142143
switch (*op) {
@@ -156,7 +157,7 @@ static void isr_handler(const void *operation)
156157
isr_return = zbus_chan_finish(NULL);
157158
break;
158159
case ADD_OBS_ISR_INVAL:
159-
isr_return = zbus_chan_add_obs(&aux2_chan, &fast_lis, K_MSEC(200));
160+
isr_return = zbus_chan_add_obs(&aux2_chan, &fast_lis, &fast_node, K_MSEC(200));
160161
break;
161162
case RM_OBS_ISR_INVAL:
162163
isr_return = zbus_chan_rm_obs(&aux2_chan, &fast_lis, K_MSEC(200));
@@ -177,7 +178,7 @@ static void isr_handler(const void *operation)
177178
isr_return = zbus_chan_finish(&aux2_chan);
178179
break;
179180
case ADD_OBS_ISR:
180-
isr_return = zbus_chan_add_obs(&aux2_chan, NULL, K_MSEC(200));
181+
isr_return = zbus_chan_add_obs(&aux2_chan, NULL, &aux_node, K_MSEC(200));
181182
break;
182183
case RM_OBS_ISR:
183184
isr_return = zbus_chan_rm_obs(&aux2_chan, NULL, K_MSEC(200));
@@ -244,6 +245,7 @@ const STRUCT_SECTION_ITERABLE(zbus_observer, invalid_obs) = {
244245

245246
ZTEST(basic, test_specification_based__zbus_chan)
246247
{
248+
static struct zbus_observer_node node;
247249
struct action_msg a = {0};
248250

249251
/* Trying invalid parameters */
@@ -269,9 +271,11 @@ ZTEST(basic, test_specification_based__zbus_chan)
269271

270272
zassert_equal(-EFAULT, zbus_chan_finish(NULL), "It must be -EFAULT");
271273

272-
zassert_equal(-EFAULT, zbus_chan_add_obs(NULL, &sub1, K_MSEC(200)), NULL);
274+
zassert_equal(-EFAULT, zbus_chan_add_obs(NULL, &sub1, &node, K_MSEC(200)), NULL);
273275

274-
zassert_equal(-EFAULT, zbus_chan_add_obs(&aux2_chan, NULL, K_MSEC(200)), NULL);
276+
zassert_equal(-EFAULT, zbus_chan_add_obs(&aux2_chan, NULL, &node, K_MSEC(200)), NULL);
277+
278+
zassert_equal(-EFAULT, zbus_chan_add_obs(&aux2_chan, &sub1, NULL, K_MSEC(200)), NULL);
275279

276280
zassert_equal(-EFAULT, zbus_chan_rm_obs(NULL, &sub1, K_MSEC(200)), NULL);
277281

@@ -326,7 +330,7 @@ ZTEST(basic, test_specification_based__zbus_chan)
326330

327331
k_msleep(100);
328332

329-
zassert_equal(0, zbus_chan_add_obs(&stuck_chan, &sub1, K_MSEC(200)), NULL);
333+
zassert_equal(0, zbus_chan_add_obs(&stuck_chan, &sub1, &node, K_MSEC(200)), NULL);
330334

331335
zassert_equal(0, zbus_chan_notify(&stuck_chan, K_MSEC(200)), "It must finish correctly");
332336

@@ -599,6 +603,7 @@ ZTEST(basic, test_hard_channel)
599603

600604
ZTEST(basic, test_specification_based__zbus_obs_set_enable)
601605
{
606+
struct zbus_observer_node node;
602607
bool enable;
603608

604609
count_fast = 0;
@@ -617,7 +622,7 @@ ZTEST(basic, test_specification_based__zbus_obs_set_enable)
617622
zbus_obs_is_enabled(&rt_fast_lis, &enable);
618623
zassert_equal(false, enable);
619624

620-
zassert_equal(0, zbus_chan_add_obs(&aux1_chan, &rt_fast_lis, K_MSEC(200)), NULL);
625+
zassert_equal(0, zbus_chan_add_obs(&aux1_chan, &rt_fast_lis, &node, K_MSEC(200)), NULL);
621626

622627
zassert_equal(0, zbus_obs_set_enable(&fast_lis, false),
623628
"Must be zero. The observer must be disabled");

0 commit comments

Comments
 (0)