From 83d0c9691586b806f5d43d68a42c1405c0fe37a2 Mon Sep 17 00:00:00 2001 From: Carlo Caione Date: Thu, 11 Nov 2021 16:34:51 +0100 Subject: [PATCH] ipc_service: Add open_instance function As know, an instance is the representation of a physical communication channel between two domains / CPUs. This communication channel must be usually known and initialized (that is "opened") by both parties in the communication before a proper communication can be instaurated using endpoints. Depending on the backend and on the library / protocol used by the backend, this "opening" can go through some handshaking or synchronization procedure run by the parties that sometimes can be blocking or time-consuming. For example in the simplest case of a backend using OpenAMP, the remote side of the communication is waiting for the local part to be up and running by loop-waiting on some flag set in the shared memory by the local party. This is a blocking process so a particular attention must be paid to where this is going to be placed in the backend code. Currently it is only possible to have this synchronization procedure in two points: (1) the init function of the instance, (2) during ipc_service_register_endpoint(). It should be highly discouraged to put any blocking routine in the init code, so (1) must be excluded. It is also frowned upon using the endpoint registration function (2) because the synchronization is something concerning the instance, not the single endpoints. This patch is adding a new optional ipc_service_open_instance() function that can be used to host the handshaking or synchronization code between the two parties of the instance. Signed-off-by: Carlo Caione --- include/ipc/ipc_service.h | 15 +++++++++++++++ include/ipc/ipc_service_backend.h | 12 ++++++++++++ subsys/ipc/ipc_service/ipc_service.c | 24 ++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/include/ipc/ipc_service.h b/include/ipc/ipc_service.h index 6755f3ccc83..0cf631aa188 100644 --- a/include/ipc/ipc_service.h +++ b/include/ipc/ipc_service.h @@ -116,6 +116,21 @@ struct ipc_ept_cfg { void *priv; }; +/** @brief Open an instance + * + * Function to be used to open an instance before being able to register a new + * endpoint on it. + * + * @retval -EINVAL when instance configuration is invalid. + * @retval -EIO when no backend is registered. + * @retval -EALREADY when the instance is already opened (or being opened). + * + * @retval 0 on success or when not implemented on the backend (not needed). + * @retval other errno codes depending on the implementation of the backend. + */ +int ipc_service_open_instance(const struct device *instance); + + /** @brief Register IPC endpoint onto an instance. * * Registers IPC endpoint onto an instance to enable communication with a diff --git a/include/ipc/ipc_service_backend.h b/include/ipc/ipc_service_backend.h index 486d3cc98b4..53e546d49cf 100644 --- a/include/ipc/ipc_service_backend.h +++ b/include/ipc/ipc_service_backend.h @@ -25,6 +25,18 @@ extern "C" { * This structure is used for configuration backend during registration. */ struct ipc_service_backend { + /** @brief Pointer to the function that will be used to open an instance + * + * @param instance Instance pointer. + * + * @retval -EALREADY when the instance is already opened. + * + * @retval 0 on success + * @retval other errno codes depending on the implementation of the + * backend. + */ + int (*open_instance)(const struct device *instance); + /** @brief Pointer to the function that will be used to send data to the endpoint. * * @param instance Instance pointer. diff --git a/subsys/ipc/ipc_service/ipc_service.c b/subsys/ipc/ipc_service/ipc_service.c index 040223bc4e3..ca3efb34ac5 100644 --- a/subsys/ipc/ipc_service/ipc_service.c +++ b/subsys/ipc/ipc_service/ipc_service.c @@ -14,6 +14,30 @@ LOG_MODULE_REGISTER(ipc_service, CONFIG_IPC_SERVICE_LOG_LEVEL); +int ipc_service_open_instance(const struct device *instance) +{ + const struct ipc_service_backend *backend; + + if (!instance) { + LOG_ERR("Invalid instance"); + return -EINVAL; + } + + backend = (const struct ipc_service_backend *) instance->api; + + if (!backend) { + LOG_ERR("Invalid backend configuration"); + return -EIO; + } + + if (!backend->open_instance) { + /* maybe not needed on backend */ + return 0; + } + + return backend->open_instance(instance); +} + int ipc_service_register_endpoint(const struct device *instance, struct ipc_ept *ept, const struct ipc_ept_cfg *cfg)