Skip to content

Commit b9de465

Browse files
jaz1-nordicrlubos
authored andcommitted
[nrf fromlist] ipc: icmsg: Align to NO MULTITHREADING
Adapting icmsg to work without the MULTITHREADING functionality. Dependencies for kernel work_queue, mutexes and other functions related to running multithreaded applications have been 'ifdefed'. Signed-off-by: Jakub Zymelka <[email protected]> Upstream PR: zephyrproject-rtos/zephyr#73857
1 parent 1e7a13b commit b9de465

File tree

3 files changed

+86
-14
lines changed

3 files changed

+86
-14
lines changed

include/zephyr/ipc/icmsg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ struct icmsg_data_t {
5151

5252
/* General */
5353
const struct icmsg_config_t *cfg;
54+
#ifdef CONFIG_MULTITHREADING
5455
struct k_work_delayable notify_work;
5556
struct k_work mbox_work;
57+
#endif
5658
atomic_t state;
5759
};
5860

subsys/ipc/ipc_service/lib/Kconfig.icmsg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
config IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC
55
bool "Synchronize access to shared memory"
6+
depends on MULTITHREADING
67
default y
78
help
89
Provide synchronization access to shared memory at a library level.
@@ -30,6 +31,7 @@ config IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS
3031

3132
config IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE
3233
bool "Use dedicated workqueue"
34+
depends on MULTITHREADING
3335
default y
3436
help
3537
Enable dedicated workqueue thread for the ICMsg backend.

subsys/ipc/ipc_service/lib/icmsg.c

Lines changed: 82 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,21 @@
1515
#define BOND_NOTIFY_REPEAT_TO K_MSEC(CONFIG_IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS)
1616
#define SHMEM_ACCESS_TO K_MSEC(CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_TO_MS)
1717

18-
1918
static const uint8_t magic[] = {0x45, 0x6d, 0x31, 0x6c, 0x31, 0x4b,
2019
0x30, 0x72, 0x6e, 0x33, 0x6c, 0x69, 0x34};
2120

21+
#ifdef CONFIG_MULTITHREADING
2222
#if IS_ENABLED(CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE)
2323
static K_THREAD_STACK_DEFINE(icmsg_stack, CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_STACK_SIZE);
2424
static struct k_work_q icmsg_workq;
2525
static struct k_work_q *const workq = &icmsg_workq;
2626
#else
2727
static struct k_work_q *const workq = &k_sys_work_q;
2828
#endif
29+
static void mbox_callback_process(struct k_work *item);
30+
#else
31+
static void mbox_callback_process(struct icmsg_data_t *dev_data);
32+
#endif
2933

3034
static int mbox_deinit(const struct icmsg_config_t *conf,
3135
struct icmsg_data_t *dev_data)
@@ -42,12 +46,20 @@ static int mbox_deinit(const struct icmsg_config_t *conf,
4246
return err;
4347
}
4448

49+
#ifdef CONFIG_MULTITHREADING
4550
(void)k_work_cancel(&dev_data->mbox_work);
4651
(void)k_work_cancel_delayable(&dev_data->notify_work);
52+
#endif
4753

4854
return 0;
4955
}
5056

57+
static bool is_endpoint_ready(struct icmsg_data_t *dev_data)
58+
{
59+
return atomic_get(&dev_data->state) == ICMSG_STATE_READY;
60+
}
61+
62+
#ifdef CONFIG_MULTITHREADING
5163
static void notify_process(struct k_work *item)
5264
{
5365
struct k_work_delayable *dwork = k_work_delayable_from_work(item);
@@ -66,37 +78,53 @@ static void notify_process(struct k_work *item)
6678
(void)ret;
6779
}
6880
}
69-
70-
static bool is_endpoint_ready(struct icmsg_data_t *dev_data)
81+
#else
82+
static void notify_process(struct icmsg_data_t *dev_data)
7183
{
72-
return atomic_get(&dev_data->state) == ICMSG_STATE_READY;
84+
(void)mbox_send_dt(&dev_data->cfg->mbox_tx, NULL);
85+
#if defined(CONFIG_SYS_CLOCK_EXISTS)
86+
int64_t start = k_uptime_get();
87+
#endif
88+
89+
while (false == is_endpoint_ready(dev_data)) {
90+
mbox_callback_process(dev_data);
91+
92+
#if defined(CONFIG_SYS_CLOCK_EXISTS)
93+
if ((k_uptime_get() - start) > CONFIG_IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS) {
94+
#endif
95+
(void)mbox_send_dt(&dev_data->cfg->mbox_tx, NULL);
96+
#if defined(CONFIG_SYS_CLOCK_EXISTS)
97+
start = k_uptime_get();
98+
};
99+
#endif
100+
}
73101
}
102+
#endif
74103

104+
#ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC
75105
static int reserve_tx_buffer_if_unused(struct icmsg_data_t *dev_data)
76106
{
77-
#ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC
78107
int ret = k_mutex_lock(&dev_data->tx_lock, SHMEM_ACCESS_TO);
79108

80109
if (ret < 0) {
81110
return ret;
82111
}
83-
#endif
112+
84113
return 0;
85114
}
86115

87116
static int release_tx_buffer(struct icmsg_data_t *dev_data)
88117
{
89-
#ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC
90118
return k_mutex_unlock(&dev_data->tx_lock);
91-
#endif
92-
return 0;
93119
}
120+
#endif
94121

95122
static uint32_t data_available(struct icmsg_data_t *dev_data)
96123
{
97124
return pbuf_read(dev_data->rx_pb, NULL, 0);
98125
}
99126

127+
#ifdef CONFIG_MULTITHREADING
100128
static void submit_mbox_work(struct icmsg_data_t *dev_data)
101129
{
102130
if (k_work_submit_to_queue(workq, &dev_data->mbox_work) < 0) {
@@ -121,10 +149,33 @@ static void submit_work_if_buffer_free_and_data_available(
121149

122150
submit_mbox_work(dev_data);
123151
}
152+
#else
153+
static void submit_if_buffer_free(struct icmsg_data_t *dev_data)
154+
{
155+
mbox_callback_process(dev_data);
156+
}
157+
158+
static void submit_if_buffer_free_and_data_available(
159+
struct icmsg_data_t *dev_data)
160+
{
161+
162+
if (!data_available(dev_data)) {
163+
return;
164+
}
165+
166+
mbox_callback_process(dev_data);
167+
}
168+
#endif
124169

170+
#ifdef CONFIG_MULTITHREADING
125171
static void mbox_callback_process(struct k_work *item)
172+
#else
173+
static void mbox_callback_process(struct icmsg_data_t *dev_data)
174+
#endif
126175
{
176+
#ifdef CONFIG_MULTITHREADING
127177
struct icmsg_data_t *dev_data = CONTAINER_OF(item, struct icmsg_data_t, mbox_work);
178+
#endif
128179

129180
atomic_t state = atomic_get(&dev_data->state);
130181

@@ -141,8 +192,7 @@ static void mbox_callback_process(struct k_work *item)
141192

142193
if (state == ICMSG_STATE_READY) {
143194
if (dev_data->cb->received) {
144-
dev_data->cb->received(rx_buffer, len,
145-
dev_data->ctx);
195+
dev_data->cb->received(rx_buffer, len, dev_data->ctx);
146196
}
147197
} else {
148198
__ASSERT_NO_MSG(state == ICMSG_STATE_BUSY);
@@ -162,24 +212,33 @@ static void mbox_callback_process(struct k_work *item)
162212

163213
atomic_set(&dev_data->state, ICMSG_STATE_READY);
164214
}
165-
215+
#ifdef CONFIG_MULTITHREADING
166216
submit_work_if_buffer_free_and_data_available(dev_data);
217+
#else
218+
submit_if_buffer_free_and_data_available(dev_data);
219+
#endif
167220
}
168221

169222
static void mbox_callback(const struct device *instance, uint32_t channel,
170223
void *user_data, struct mbox_msg *msg_data)
171224
{
172225
struct icmsg_data_t *dev_data = user_data;
226+
#ifdef CONFIG_MULTITHREADING
173227
submit_work_if_buffer_free(dev_data);
228+
#else
229+
submit_if_buffer_free(dev_data);
230+
#endif
174231
}
175232

176233
static int mbox_init(const struct icmsg_config_t *conf,
177234
struct icmsg_data_t *dev_data)
178235
{
179236
int err;
180237

238+
#ifdef CONFIG_MULTITHREADING
181239
k_work_init(&dev_data->mbox_work, mbox_callback_process);
182240
k_work_init_delayable(&dev_data->notify_work, notify_process);
241+
#endif
183242

184243
err = mbox_register_callback_dt(&conf->mbox_rx, mbox_callback, dev_data);
185244
if (err != 0) {
@@ -233,12 +292,14 @@ int icmsg_open(const struct icmsg_config_t *conf,
233292
if (ret) {
234293
return ret;
235294
}
236-
295+
#ifdef CONFIG_MULTITHREADING
237296
ret = k_work_schedule_for_queue(workq, &dev_data->notify_work, K_NO_WAIT);
238297
if (ret < 0) {
239298
return ret;
240299
}
241-
300+
#else
301+
notify_process(dev_data);
302+
#endif
242303
return 0;
243304
}
244305

@@ -263,7 +324,9 @@ int icmsg_send(const struct icmsg_config_t *conf,
263324
{
264325
int ret;
265326
int write_ret;
327+
#ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC
266328
int release_ret;
329+
#endif
267330
int sent_bytes;
268331

269332
if (!is_endpoint_ready(dev_data)) {
@@ -275,14 +338,19 @@ int icmsg_send(const struct icmsg_config_t *conf,
275338
return -ENODATA;
276339
}
277340

341+
#ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC
278342
ret = reserve_tx_buffer_if_unused(dev_data);
279343
if (ret < 0) {
280344
return -ENOBUFS;
281345
}
346+
#endif
282347

283348
write_ret = pbuf_write(dev_data->tx_pb, msg, len);
349+
350+
#ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC
284351
release_ret = release_tx_buffer(dev_data);
285352
__ASSERT_NO_MSG(!release_ret);
353+
#endif
286354

287355
if (write_ret < 0) {
288356
return write_ret;

0 commit comments

Comments
 (0)