diff --git a/dts/bindings/ipc/zephyr,ipc-openamp-static-vrings.yaml b/dts/bindings/ipc/zephyr,ipc-openamp-static-vrings.yaml index 4a4d0524f05..934ffdb8bfe 100644 --- a/dts/bindings/ipc/zephyr,ipc-openamp-static-vrings.yaml +++ b/dts/bindings/ipc/zephyr,ipc-openamp-static-vrings.yaml @@ -28,3 +28,18 @@ properties: mbox-names: description: MBOX channel names (must be called "tx" and "rx") required: true + + zephyr,priority: + type: array + required: false + description: | + WQ priority for the instance. This property is an array composed by the + priority level and the type of priority (PRIO_COOP for cooperative or + PRIO_PREEMPT for preemptive). + + For example for a thread priority K_PRIO_COOP(1) in DT we have + priority = <1 PRIO_COOP>; + or for K_PRIO_PREEMPT(2) + priority = <2 PRIO_PREEMPT>; + + When this property is missing a default priority of 0 is assumed. diff --git a/include/dt-bindings/ipc_service/static_vrings.h b/include/dt-bindings/ipc_service/static_vrings.h new file mode 100644 index 00000000000..1c51ce14a0e --- /dev/null +++ b/include/dt-bindings/ipc_service/static_vrings.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2022 Carlo Caione + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __DT_BINDING_IPC_SERVICE_STATIC_VRINGS_H +#define __DT_BINDING_IPC_SERVICE_STATIC_VRINGS_H + +#include + +#define PRIO_COOP BIT(0) +#define PRIO_PREEMPT BIT(1) + +#endif /* __DT_BINDING_IPC_SERVICE_STATIC_VRINGS_H */ diff --git a/samples/subsys/ipc/ipc_service/static_vrings/boards/nrf5340dk_nrf5340_cpuapp.overlay b/samples/subsys/ipc/ipc_service/static_vrings/boards/nrf5340dk_nrf5340_cpuapp.overlay index c59c5e12023..410f7608de9 100644 --- a/samples/subsys/ipc/ipc_service/static_vrings/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/samples/subsys/ipc/ipc_service/static_vrings/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + / { chosen { /delete-property/ zephyr,ipc_shm; @@ -42,6 +44,7 @@ mboxes = <&mbox 2>, <&mbox 3>; mbox-names = "tx", "rx"; role = "host"; + zephyr,priority = <1 PRIO_COOP>; status = "okay"; }; }; diff --git a/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/nrf5340dk_nrf5340_cpunet.overlay b/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/nrf5340dk_nrf5340_cpunet.overlay index 130529a132a..de11400d110 100644 --- a/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/nrf5340dk_nrf5340_cpunet.overlay +++ b/samples/subsys/ipc/ipc_service/static_vrings/remote/boards/nrf5340dk_nrf5340_cpunet.overlay @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + / { chosen { /delete-property/ zephyr,ipc_shm; @@ -40,6 +42,7 @@ mboxes = <&mbox 2>, <&mbox 3>; mbox-names = "rx", "tx"; role = "remote"; + zephyr,priority = <2 PRIO_PREEMPT>; status = "okay"; }; }; diff --git a/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c b/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c index 585fa130195..0ef7e8bf73d 100644 --- a/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c +++ b/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c @@ -15,20 +15,21 @@ #include #include +#include #include "ipc_rpmsg_static_vrings.h" #define DT_DRV_COMPAT zephyr_ipc_openamp_static_vrings -#define WQ_PRIORITY K_HIGHEST_APPLICATION_THREAD_PRIO +#define NUM_INSTANCES DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) + #define WQ_STACK_SIZE CONFIG_IPC_SERVICE_BACKEND_RPMSG_WQ_STACK_SIZE #define STATE_READY (0) #define STATE_BUSY (1) #define STATE_INITED (2) -K_KERNEL_STACK_DEFINE(mbox_stack, WQ_STACK_SIZE); -static struct k_work_q mbox_wq; +K_THREAD_STACK_ARRAY_DEFINE(mbox_stack, NUM_INSTANCES, WQ_STACK_SIZE); struct backend_data_t { /* RPMsg */ @@ -37,8 +38,11 @@ struct backend_data_t { /* Static VRINGs */ struct ipc_static_vrings vr; - /* General */ + /* MBOX WQ */ struct k_work mbox_work; + struct k_work_q mbox_wq; + + /* General */ unsigned int role; atomic_t state; }; @@ -49,6 +53,9 @@ struct backend_config_t { size_t shm_size; struct mbox_channel mbox_tx; struct mbox_channel mbox_rx; + unsigned int wq_prio_type; + unsigned int wq_prio; + unsigned int id; }; static void rpmsg_service_unbind(struct rpmsg_endpoint *ep) @@ -262,14 +269,20 @@ static void mbox_callback(const struct device *instance, uint32_t channel, { struct backend_data_t *data = user_data; - k_work_submit_to_queue(&mbox_wq, &data->mbox_work); + k_work_submit_to_queue(&data->mbox_wq, &data->mbox_work); } static int mbox_init(const struct device *instance) { const struct backend_config_t *conf = instance->config; struct backend_data_t *data = instance->data; - int err; + int prio, err; + + prio = (conf->wq_prio_type == PRIO_COOP) ? K_PRIO_COOP(conf->wq_prio) : + K_PRIO_PREEMPT(conf->wq_prio); + + k_work_queue_init(&data->mbox_wq); + k_work_queue_start(&data->mbox_wq, mbox_stack[conf->id], WQ_STACK_SIZE, prio, NULL); k_work_init(&data->mbox_work, mbox_callback_process); @@ -458,19 +471,12 @@ static int backend_init(const struct device *instance) { const struct backend_config_t *conf = instance->config; struct backend_data_t *data = instance->data; - static bool wq_started; data->role = conf->role; k_mutex_init(&data->rpmsg_inst.mtx); atomic_set(&data->state, STATE_READY); - if (!wq_started) { - k_work_queue_start(&mbox_wq, mbox_stack, K_KERNEL_STACK_SIZEOF(mbox_stack), - WQ_PRIORITY, NULL); - wq_started = true; - } - return 0; } @@ -481,6 +487,13 @@ static int backend_init(const struct device *instance) .shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, memory_region)), \ .mbox_tx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), tx), \ .mbox_rx = MBOX_DT_CHANNEL_GET(DT_DRV_INST(i), rx), \ + .wq_prio = COND_CODE_1(DT_INST_NODE_HAS_PROP(i, zephyr_priority), \ + (DT_INST_PROP_BY_IDX(i, zephyr_priority, 0)), \ + (0)), \ + .wq_prio_type = COND_CODE_1(DT_INST_NODE_HAS_PROP(i, zephyr_priority), \ + (DT_INST_PROP_BY_IDX(i, zephyr_priority, 1)), \ + (PRIO_PREEMPT)), \ + .id = i, \ }; \ \ static struct backend_data_t backend_data_##i; \