ipc: ipc_service: Add support for multiple instances
The IPC service code is currently assuming that only one IPC instance does exist and the user can use the IPC service API to interface with that singleton instance. This is a huge limitation and this patch is trying to fix this assumption introducing three major changes to the IPC service API: - All the IPC instances are now supposed to be instantiated as a struct device. A new test is introduced to be used as skeleton for all the other backends. - ipc_service_register_backend() is now removed (because multiple backends are now supported at the same time). - All the other ipc_service_*() functions are now taking a struct device pointer as parameter to specify on which instance the user is going to act and operate. In this patch the documentation is also extended to better clarify the terminology used. Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
parent
3b4515a6e9
commit
086801ca2e
11 changed files with 312 additions and 53 deletions
|
@ -4,10 +4,11 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_IPC_SERVICE_IPC_SERVICE_H_
|
||||
#define ZEPHYR_INCLUDE_IPC_SERVICE_IPC_SERVICE_H_
|
||||
#ifndef ZEPHYR_INCLUDE_IPC_IPC_SERVICE_H_
|
||||
#define ZEPHYR_INCLUDE_IPC_IPC_SERVICE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <device.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -17,6 +18,44 @@ extern "C" {
|
|||
* @brief IPC Service API
|
||||
* @defgroup ipc_service_api IPC service APIs
|
||||
* @{
|
||||
*
|
||||
* Some terminology:
|
||||
*
|
||||
* - INSTANCE: an instance is the external representation of a physical
|
||||
* communication channel between two domains / CPUs.
|
||||
*
|
||||
* The actual implementation and internal representation of the
|
||||
* instance is peculiar to each backend. For example for
|
||||
* OpenAMP-based backends, an instance is usually represented by a
|
||||
* shared memory region and a couple of IPM devices for RX/TX
|
||||
* signalling.
|
||||
*
|
||||
* It's important to note that an instance per se is not used to
|
||||
* send data between domains / CPUs. To send and receive data the
|
||||
* user have to create (register) an endpoint in the instance
|
||||
* connecting the two domains of interest.
|
||||
*
|
||||
* It's possible to have zero or multiple endpoints in one single
|
||||
* instance, each one used to exchange data, possibly with different
|
||||
* priorities.
|
||||
*
|
||||
* The creation of the instances is left to the backend (usually at
|
||||
* init time), while the registration of the endpoints is left to
|
||||
* the user (usually at run time).
|
||||
*
|
||||
* - ENDPOINT: an endpoint is the entity the user must use to send / receive
|
||||
* data between two domains (connected by the instance). An
|
||||
* endpoint is always associated to an instance.
|
||||
*
|
||||
* - BACKEND: the backend must take care of at least two different things:
|
||||
*
|
||||
* 1) creating the instances at init time
|
||||
* 2) creating / registering the endpoints onto an instance at run
|
||||
* time when requested by the user
|
||||
*
|
||||
* The API doesn't mandate a way for the backend to create the
|
||||
* instances but itis strongly recommended to use the DT to retrieve
|
||||
* the configuration parameters for the instance.
|
||||
*/
|
||||
|
||||
/** @brief Event callback structure.
|
||||
|
@ -49,10 +88,17 @@ struct ipc_service_cb {
|
|||
|
||||
/** @brief Endpoint instance.
|
||||
*
|
||||
* Content is not important for user of the API.
|
||||
* It is implemented in a specific backend.
|
||||
* Token is not important for user of the API. It is implemented in a
|
||||
* specific backend.
|
||||
*/
|
||||
struct ipc_ept;
|
||||
struct ipc_ept {
|
||||
|
||||
/** Instance this endpoint belongs to. */
|
||||
const struct device *instance;
|
||||
|
||||
/** Backend-specific token used to identify an endpoint in an instance. */
|
||||
void *token;
|
||||
};
|
||||
|
||||
/** @brief Endpoint configuration structure. */
|
||||
struct ipc_ept_cfg {
|
||||
|
@ -70,20 +116,24 @@ struct ipc_ept_cfg {
|
|||
void *priv;
|
||||
};
|
||||
|
||||
/** @brief Register IPC endpoint.
|
||||
/** @brief Register IPC endpoint onto an instance.
|
||||
*
|
||||
* Registers IPC endpoint to enable communication with a remote device.
|
||||
* Registers IPC endpoint onto an instance to enable communication with a
|
||||
* remote device.
|
||||
*
|
||||
* The same function registers endpoints for both master and slave devices.
|
||||
*
|
||||
* @param instance Instance to register the endpoint onto.
|
||||
* @param ept Endpoint object.
|
||||
* @param cfg Endpoint configuration.
|
||||
*
|
||||
* @retval -EIO when no backend is registered.
|
||||
* @retval -EINVAL when pointer to an endpoint or endpoint configuration is invalid.
|
||||
* @retval -EINVAL when instance or endpoint configuration is invalid.
|
||||
* @retval Other errno codes depending on the implementation of the backend.
|
||||
*/
|
||||
int ipc_service_register_endpoint(struct ipc_ept **ept, const struct ipc_ept_cfg *cfg);
|
||||
int ipc_service_register_endpoint(const struct device *instance,
|
||||
struct ipc_ept *ept,
|
||||
const struct ipc_ept_cfg *cfg);
|
||||
|
||||
/** @brief Send data using given IPC endpoint.
|
||||
*
|
||||
|
@ -104,4 +154,4 @@ int ipc_service_send(struct ipc_ept *ept, const void *data, size_t len);
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_IPC_SERVICE_IPC_SERVICE_H_ */
|
||||
#endif /* ZEPHYR_INCLUDE_IPC_IPC_SERVICE_H_ */
|
||||
|
|
|
@ -25,42 +25,31 @@ extern "C" {
|
|||
* This structure is used for configuration backend during registration.
|
||||
*/
|
||||
struct ipc_service_backend {
|
||||
/** @brief Name of the IPC backend. */
|
||||
const char *name;
|
||||
|
||||
/** @brief Pointer to the function that will be used to send data to the endpoint.
|
||||
*
|
||||
* @param ept Registered endpoint.
|
||||
* @param instance Instance pointer.
|
||||
* @param token Backend-specific token.
|
||||
* @param data Pointer to the buffer to send.
|
||||
* @param len Number of bytes to send.
|
||||
*
|
||||
* @retval Status code.
|
||||
*/
|
||||
int (*send)(struct ipc_ept *ept, const void *data, size_t len);
|
||||
int (*send)(const struct device *instance, void *token,
|
||||
const void *data, size_t len);
|
||||
|
||||
/** @brief Pointer to the function that will be used to register endpoints.
|
||||
*
|
||||
* @param ept Endpoint object.
|
||||
* @param instance Instance to register the endpoint onto.
|
||||
* @param token Backend-specific token.
|
||||
* @param cfg Endpoint configuration.
|
||||
*
|
||||
* @retval Status code.
|
||||
*/
|
||||
int (*register_endpoint)(struct ipc_ept **ept, const struct ipc_ept_cfg *cfg);
|
||||
int (*register_endpoint)(const struct device *instance,
|
||||
void **token,
|
||||
const struct ipc_ept_cfg *cfg);
|
||||
};
|
||||
|
||||
/** @brief IPC backend registration.
|
||||
*
|
||||
* Registration must be done before using IPC Service.
|
||||
*
|
||||
* @param backend Configuration of the backend.
|
||||
*
|
||||
* @retval -EALREADY The backend is already registered.
|
||||
* @retval -EINVAL The backend configuration is incorrect.
|
||||
* @retval Zero on success.
|
||||
*
|
||||
*/
|
||||
int ipc_service_register_backend(const struct ipc_service_backend *backend);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue