ipc_service: mi: Convert to device driver
As part of the work to support multiple IPC instances / backends using
IPC service, the static vrings mi code must be reworked to resemble a
classic device driver.
Fix also the sample using it.
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
diff --git a/include/ipc/ipc_rpmsg.h b/include/ipc/ipc_rpmsg.h
index c3f742d..6778673 100644
--- a/include/ipc/ipc_rpmsg.h
+++ b/include/ipc/ipc_rpmsg.h
@@ -24,6 +24,8 @@
/** Number of endpoints. */
#define NUM_ENDPOINTS CONFIG_IPC_SERVICE_NUM_ENDPOINTS_PER_INSTANCE
+struct ipc_rpmsg_ept;
+
/**
* @typedef rpmsg_ept_bound_cb
* @brief Define the bound callback.
@@ -33,13 +35,13 @@
*
* @param ept Endpoint of the instance just bound.
*/
-typedef void (*rpmsg_ept_bound_cb)(struct ipc_ept *ept);
+typedef void (*rpmsg_ept_bound_cb)(struct ipc_rpmsg_ept *ept);
/** @brief Endpoint structure.
*
* Used to define an endpoint to be encapsulated in an RPMsg instance.
*/
-struct ipc_ept {
+struct ipc_rpmsg_ept {
/** RPMsg endpoint. */
struct rpmsg_endpoint ep;
@@ -62,7 +64,7 @@
*/
struct ipc_rpmsg_instance {
/** Endpoints in the instance. */
- struct ipc_ept endpoint[NUM_ENDPOINTS];
+ struct ipc_rpmsg_ept endpoint[NUM_ENDPOINTS];
/** RPMsg virtIO device. */
struct rpmsg_virtio_device rvdev;
@@ -115,7 +117,7 @@
* @retval Other errno codes depending on the OpenAMP implementation.
*/
int ipc_rpmsg_register_ept(struct ipc_rpmsg_instance *instance, unsigned int role,
- struct ipc_ept *ept);
+ struct ipc_rpmsg_ept *ept);
/**
* @}
diff --git a/samples/subsys/ipc/ipc_service/remote/src/main.c b/samples/subsys/ipc/ipc_service/remote/src/main.c
index cbf6b37..71d33a9 100644
--- a/samples/subsys/ipc/ipc_service/remote/src/main.c
+++ b/samples/subsys/ipc/ipc_service/remote/src/main.c
@@ -14,6 +14,8 @@
#include <ipc/ipc_service.h>
+#define MI_BACKEND_DRIVER_NAME "MI_BACKEND"
+
#define APP_TASK_STACK_SIZE 1024
K_THREAD_STACK_DEFINE(thread_stack_1, APP_TASK_STACK_SIZE);
@@ -31,8 +33,8 @@
static K_SEM_DEFINE(data_rx1_sem, 0, 1);
static K_SEM_DEFINE(data_rx2_sem, 0, 1);
-static struct ipc_ept *ept_1;
-static struct ipc_ept *ept_2;
+static struct ipc_ept ept_1;
+static struct ipc_ept ept_2;
static void ept_bound_1(void *priv)
{
@@ -71,11 +73,15 @@
ARG_UNUSED(arg1);
ARG_UNUSED(arg2);
ARG_UNUSED(arg3);
+
+ const struct device *ipc_instance;
int status = 0;
uint8_t message = 0U;
printk("\r\nIPC Service [remote 1] demo started\r\n");
+ ipc_instance = device_get_binding(MI_BACKEND_DRIVER_NAME);
+
static struct ipc_ept_cfg ept_cfg = {
.name = "ep_1",
.prio = 0,
@@ -87,7 +93,7 @@
},
};
- status = ipc_service_register_endpoint(&ept_1, &ept_cfg);
+ status = ipc_service_register_endpoint(ipc_instance, &ept_1, &ept_cfg);
if (status < 0) {
printk("ipc_service_register_endpoint failed %d\n", status);
return;
@@ -101,7 +107,7 @@
printk("Remote [1] received a message: %d\n", message);
message++;
- status = ipc_service_send(ept_1, &message, sizeof(message));
+ status = ipc_service_send(&ept_1, &message, sizeof(message));
if (status < 0) {
printk("send_message(%d) failed with status %d\n",
message, status);
@@ -117,11 +123,15 @@
ARG_UNUSED(arg1);
ARG_UNUSED(arg2);
ARG_UNUSED(arg3);
+
+ const struct device *ipc_instance;
int status = 0;
uint8_t message = 0U;
printk("\r\nIPC Service [remote 2] demo started\r\n");
+ ipc_instance = device_get_binding(MI_BACKEND_DRIVER_NAME);
+
static struct ipc_ept_cfg ept_cfg = {
.name = "ep_2",
.prio = 0,
@@ -133,7 +143,7 @@
},
};
- status = ipc_service_register_endpoint(&ept_2, &ept_cfg);
+ status = ipc_service_register_endpoint(ipc_instance, &ept_2, &ept_cfg);
if (status < 0) {
printk("ipc_service_register_endpoint failed %d\n", status);
@@ -148,7 +158,7 @@
printk("Remote [2] received a message: %d\n", message);
message++;
- status = ipc_service_send(ept_2, &message, sizeof(message));
+ status = ipc_service_send(&ept_2, &message, sizeof(message));
if (status < 0) {
printk("send_message(%d) failed with status %d\n",
message, status);
diff --git a/samples/subsys/ipc/ipc_service/src/main.c b/samples/subsys/ipc/ipc_service/src/main.c
index 00bdb20..2bc1f50 100644
--- a/samples/subsys/ipc/ipc_service/src/main.c
+++ b/samples/subsys/ipc/ipc_service/src/main.c
@@ -15,6 +15,8 @@
#include <ipc/ipc_service.h>
+#define MI_BACKEND_DRIVER_NAME "MI_BACKEND"
+
#define APP_TASK_STACK_SIZE 1024
K_THREAD_STACK_DEFINE(thread_stack_1, APP_TASK_STACK_SIZE);
@@ -32,8 +34,8 @@
static K_SEM_DEFINE(data_rx1_sem, 0, 1);
static K_SEM_DEFINE(data_rx2_sem, 0, 1);
-static struct ipc_ept *ept_1;
-static struct ipc_ept *ept_2;
+static struct ipc_ept ept_1;
+static struct ipc_ept ept_2;
static void ept_bound_1(void *priv)
{
@@ -72,11 +74,15 @@
ARG_UNUSED(arg1);
ARG_UNUSED(arg2);
ARG_UNUSED(arg3);
+
+ const struct device *ipc_instance;
int status = 0;
uint8_t message = 0U;
printk("\r\nIPC Service [master 1] demo started\r\n");
+ ipc_instance = device_get_binding(MI_BACKEND_DRIVER_NAME);
+
static struct ipc_ept_cfg ept_cfg = {
.name = "ep_1",
.prio = 0,
@@ -88,7 +94,7 @@
},
};
- status = ipc_service_register_endpoint(&ept_1, &ept_cfg);
+ status = ipc_service_register_endpoint(ipc_instance, &ept_1, &ept_cfg);
if (status < 0) {
printk("ipc_service_register_endpoint failed %d\n", status);
return;
@@ -97,7 +103,7 @@
k_sem_take(&bound_ept1_sem, K_FOREVER);
while (message < 100) {
- status = ipc_service_send(ept_1, &message, sizeof(message));
+ status = ipc_service_send(&ept_1, &message, sizeof(message));
if (status < 0) {
printk("send_message(%d) failed with status %d\n",
message, status);
@@ -119,11 +125,15 @@
ARG_UNUSED(arg1);
ARG_UNUSED(arg2);
ARG_UNUSED(arg3);
+
+ const struct device *ipc_instance;
int status = 0;
uint8_t message = 0U;
printk("\r\nIPC Service [master 2] demo started\r\n");
+ ipc_instance = device_get_binding(MI_BACKEND_DRIVER_NAME);
+
static struct ipc_ept_cfg ept_cfg = {
.name = "ep_2",
.prio = 0,
@@ -135,7 +145,7 @@
},
};
- status = ipc_service_register_endpoint(&ept_2, &ept_cfg);
+ status = ipc_service_register_endpoint(ipc_instance, &ept_2, &ept_cfg);
if (status < 0) {
printk("ipc_service_register_endpoint failed %d\n", status);
@@ -145,7 +155,7 @@
k_sem_take(&bound_ept2_sem, K_FOREVER);
while (message < 100) {
- status = ipc_service_send(ept_2, &message, sizeof(message));
+ status = ipc_service_send(&ept_2, &message, sizeof(message));
if (status < 0) {
printk("send_message(%d) failed with status %d\n",
message, status);
diff --git a/subsys/ipc/ipc_service/backends/ipc_rpmsg.c b/subsys/ipc/ipc_service/backends/ipc_rpmsg.c
index 5504b0d..5233192 100644
--- a/subsys/ipc/ipc_service/backends/ipc_rpmsg.c
+++ b/subsys/ipc/ipc_service/backends/ipc_rpmsg.c
@@ -16,7 +16,7 @@
{
struct rpmsg_virtio_device *p_rvdev;
struct ipc_rpmsg_instance *instance;
- struct ipc_ept *ept;
+ struct ipc_rpmsg_ept *ept;
int err;
p_rvdev = CONTAINER_OF(rdev, struct rpmsg_virtio_device, rdev);
@@ -41,7 +41,7 @@
}
int ipc_rpmsg_register_ept(struct ipc_rpmsg_instance *instance, unsigned int role,
- struct ipc_ept *ept)
+ struct ipc_rpmsg_ept *ept)
{
struct rpmsg_device *rdev;
diff --git a/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings_mi.c b/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings_mi.c
index 9b20b4b..3762303 100644
--- a/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings_mi.c
+++ b/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings_mi.c
@@ -17,6 +17,8 @@
#include "ipc_rpmsg_static_vrings_mi.h"
+#define MI_BACKEND_DRIVER_NAME "MI_BACKEND"
+
LOG_MODULE_REGISTER(ipc_rpmsg_multi_instance, CONFIG_IPC_SERVICE_LOG_LEVEL);
#define WQ_STACK_SIZE CONFIG_IPC_SERVICE_BACKEND_RPMSG_MI_WQ_STACK_SIZE
@@ -74,9 +76,14 @@
static struct rpmsg_mi_instance instance[NUM_INSTANCES];
-static int send(struct ipc_ept *ept, const void *data, size_t len)
+static int send(const struct device *instance, void *token,
+ const void *data, size_t len)
{
- return rpmsg_send(&ept->ep, data, len);
+ struct ipc_rpmsg_ept *rpmsg_ept;
+
+ rpmsg_ept = (struct ipc_rpmsg_ept *) token;
+
+ return rpmsg_send(&rpmsg_ept->ep, data, len);
}
static struct rpmsg_mi_instance *get_available_instance(const struct ipc_ept_cfg *cfg)
@@ -90,7 +97,7 @@
return NULL;
}
-static struct ipc_ept *get_available_ept_slot(struct ipc_rpmsg_instance *rpmsg_instance)
+static struct ipc_rpmsg_ept *get_available_ept_slot(struct ipc_rpmsg_instance *rpmsg_instance)
{
for (size_t i = 0; i < NUM_ENDPOINTS; i++) {
if (rpmsg_instance->endpoint[i].name == NULL) {
@@ -168,7 +175,7 @@
instance->vr.shm_size = shm_local_size;
}
-static void bound_cb(struct ipc_ept *ept)
+static void bound_cb(struct ipc_rpmsg_ept *ept)
{
/* Notify the remote site that binding has occurred */
rpmsg_send(&ept->ep, (uint8_t *)"", 0);
@@ -180,9 +187,9 @@
static int ept_cb(struct rpmsg_endpoint *ep, void *data, size_t len, uint32_t src, void *priv)
{
- struct ipc_ept *ept;
+ struct ipc_rpmsg_ept *ept;
- ept = (struct ipc_ept *) priv;
+ ept = (struct ipc_rpmsg_ept *) priv;
if (len == 0) {
if (!ept->bound) {
@@ -239,14 +246,18 @@
return 0;
}
-static int register_ept(struct ipc_ept **r_ept, const struct ipc_ept_cfg *cfg)
+static int register_ept(const struct device *dev,
+ void **token,
+ const struct ipc_ept_cfg *cfg)
{
struct ipc_rpmsg_instance *rpmsg_instance;
struct rpmsg_mi_instance *instance;
- struct ipc_ept *ept;
+ struct ipc_rpmsg_ept *rpmsg_ept;
int err;
- if (!cfg || !r_ept) {
+ ARG_UNUSED(dev);
+
+ if (!cfg || !token) {
return -EINVAL;
}
@@ -283,29 +294,28 @@
instance->is_initialized = true;
}
- ept = get_available_ept_slot(rpmsg_instance);
- if (ept == NULL) {
+ rpmsg_ept = get_available_ept_slot(rpmsg_instance);
+ if (rpmsg_ept == NULL) {
return -ENODEV;
}
- ept->name = cfg->name;
- ept->cb = &cfg->cb;
- ept->priv = cfg->priv;
- ept->bound = false;
- ept->ep.priv = ept;
+ rpmsg_ept->name = cfg->name;
+ rpmsg_ept->cb = &cfg->cb;
+ rpmsg_ept->priv = cfg->priv;
+ rpmsg_ept->bound = false;
+ rpmsg_ept->ep.priv = rpmsg_ept;
- err = ipc_rpmsg_register_ept(rpmsg_instance, instance->role, ept);
+ err = ipc_rpmsg_register_ept(rpmsg_instance, instance->role, rpmsg_ept);
if (err != 0) {
return err;
}
- *r_ept = ept;
+ (*token) = rpmsg_ept;
return 0;
}
-const static struct ipc_service_backend backend = {
- .name = "RPMSG backend - static VRINGs (multi-instance)",
+const static struct ipc_service_backend backend_ops = {
.send = send,
.register_endpoint = register_ept,
};
@@ -321,6 +331,9 @@
VIRTIO_DEV_MASTER : VIRTIO_DEV_SLAVE;
}
- return ipc_service_register_backend(&backend);
+ return 0;
}
-SYS_INIT(backend_init, POST_KERNEL, CONFIG_IPC_SERVICE_REG_BACKEND_PRIORITY);
+
+DEVICE_DEFINE(mi_backend, MI_BACKEND_DRIVER_NAME, &backend_init, NULL, NULL,
+ NULL, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
+ &backend_ops);