Skip to content

Commit 0620cb1

Browse files
rakonscarlescufi
authored andcommitted
ipc: ipc_service: icmsg: Increase reliability of bonding
This commit changes the way bonding between endpoints is processed. There is no blind attempt to read the buffer without mbox notification. On second side the notification is repeated multiple times until valid bonding is detected. Signed-off-by: Radoslaw Koppel <[email protected]>
1 parent 15ffcb2 commit 0620cb1

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
lines changed

include/zephyr/ipc/icmsg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ struct icmsg_data_t {
3737
void *ctx;
3838

3939
/* General */
40+
const struct icmsg_config_t *cfg;
41+
struct k_work_delayable notify_work;
4042
struct k_work mbox_work;
4143
atomic_t state;
4244
};

subsys/ipc/ipc_service/backends/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,13 @@ config SYSTEM_WORKQUEUE_PRIORITY
8989
depends on IPC_SERVICE_ICMSG
9090
range -256 -1
9191

92+
config IPC_SERVICE_BACKEND_ICMSG_BOND_NOTIFY_REPEAT_TO_MS
93+
int "Bond notification timeout in miliseconds"
94+
range 1 100
95+
default 1
96+
help
97+
Time to wait for remote bonding notification before the
98+
notification is repeated.
99+
92100
rsource "Kconfig.icmsg_me"
93101
rsource "Kconfig.rpmsg"

subsys/ipc/ipc_service/lib/icmsg.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <zephyr/sys/spsc_pbuf.h>
1313

1414
#define CB_BUF_SIZE CONFIG_IPC_SERVICE_ICMSG_CB_BUF_SIZE
15+
#define BOND_NOTIFY_REPEAT_TO K_MSEC(CONFIG_IPC_SERVICE_BACKEND_ICMSG_BOND_NOTIFY_REPEAT_TO_MS)
1516

1617
static const uint8_t magic[] = {0x45, 0x6d, 0x31, 0x6c, 0x31, 0x4b,
1718
0x30, 0x72, 0x6e, 0x33, 0x6c, 0x69, 0x34};
@@ -34,10 +35,30 @@ static int mbox_deinit(const struct icmsg_config_t *conf,
3435
}
3536

3637
(void)k_work_cancel(&dev_data->mbox_work);
38+
(void)k_work_cancel_delayable(&dev_data->notify_work);
3739

3840
return 0;
3941
}
4042

43+
static void notify_process(struct k_work *item)
44+
{
45+
struct k_work_delayable *dwork = k_work_delayable_from_work(item);
46+
struct icmsg_data_t *dev_data =
47+
CONTAINER_OF(dwork, struct icmsg_data_t, notify_work);
48+
49+
(void)mbox_send(&dev_data->cfg->mbox_tx, NULL);
50+
51+
atomic_t state = atomic_get(&dev_data->state);
52+
53+
if (state != ICMSG_STATE_READY) {
54+
int ret;
55+
56+
ret = k_work_reschedule(dwork, BOND_NOTIFY_REPEAT_TO);
57+
__ASSERT_NO_MSG(ret >= 0);
58+
(void)ret;
59+
}
60+
}
61+
4162
static void mbox_callback_process(struct k_work *item)
4263
{
4364
struct icmsg_data_t *dev_data = CONTAINER_OF(item, struct icmsg_data_t, mbox_work);
@@ -61,6 +82,8 @@ static void mbox_callback_process(struct k_work *item)
6182
dev_data->cb->received(cb_buffer, len, dev_data->ctx);
6283
}
6384
} else {
85+
int ret;
86+
6487
__ASSERT_NO_MSG(state == ICMSG_STATE_BUSY);
6588
if (len != sizeof(magic) || memcmp(magic, cb_buffer, len)) {
6689
__ASSERT_NO_MSG(false);
@@ -72,6 +95,9 @@ static void mbox_callback_process(struct k_work *item)
7295
}
7396

7497
atomic_set(&dev_data->state, ICMSG_STATE_READY);
98+
ret = k_work_cancel_delayable(&dev_data->notify_work);
99+
__ASSERT_NO_MSG(ret >= 0);
100+
(void)ret;
75101
}
76102

77103
/* Reading with NULL buffer to know if there are data in the
@@ -102,6 +128,7 @@ static int mbox_init(const struct icmsg_config_t *conf,
102128
int err;
103129

104130
k_work_init(&dev_data->mbox_work, mbox_callback_process);
131+
k_work_init_delayable(&dev_data->notify_work, notify_process);
105132

106133
err = mbox_register_callback(&conf->mbox_rx, mbox_callback, dev_data);
107134
if (err != 0) {
@@ -137,6 +164,7 @@ int icmsg_open(const struct icmsg_config_t *conf,
137164

138165
dev_data->cb = cb;
139166
dev_data->ctx = ctx;
167+
dev_data->cfg = conf;
140168

141169
ret = mbox_init(conf, dev_data);
142170
if (ret) {
@@ -154,16 +182,11 @@ int icmsg_open(const struct icmsg_config_t *conf,
154182
return ret;
155183
}
156184

157-
ret = mbox_send(&conf->mbox_tx, NULL);
158-
if (ret) {
185+
ret = k_work_schedule(&dev_data->notify_work, K_NO_WAIT);
186+
if (ret < 0) {
159187
return ret;
160188
}
161189

162-
ret = spsc_pbuf_read(dev_data->rx_ib, NULL, 0);
163-
if (ret > 0) {
164-
(void)k_work_submit(&dev_data->mbox_work);
165-
}
166-
167190
return 0;
168191
}
169192

0 commit comments

Comments
 (0)