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 <ccaione@baylibre.com>
This commit is contained in:
Carlo Caione 2021-11-11 16:34:51 +01:00 committed by Christopher Friedt
commit 83d0c96915
3 changed files with 51 additions and 0 deletions

View file

@ -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

View file

@ -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.

View file

@ -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)