Extend the RPMsg structs to accommodate for the introduction of new backends and contextually fix the ipc_rpmsg_static_vrings_mi backend (the only user). Rework also some comments and ipc_service glue code. Signed-off-by: Carlo Caione <ccaione@baylibre.com>
182 lines
5.4 KiB
C
182 lines
5.4 KiB
C
/*
|
|
* Copyright (c) 2021 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef ZEPHYR_INCLUDE_IPC_IPC_SERVICE_H_
|
|
#define ZEPHYR_INCLUDE_IPC_IPC_SERVICE_H_
|
|
|
|
#include <stdio.h>
|
|
#include <device.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @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.
|
|
*
|
|
* It is registered during endpoint registration.
|
|
* This structure is part of the endpoint configuration.
|
|
*/
|
|
struct ipc_service_cb {
|
|
/** @brief Bind was successful.
|
|
*
|
|
* @param priv Private user data.
|
|
*/
|
|
void (*bound)(void *priv);
|
|
|
|
/** @brief New packet arrived.
|
|
*
|
|
* @param data Pointer to data buffer.
|
|
* @param len Length of @a data.
|
|
* @param priv Private user data.
|
|
*/
|
|
void (*received)(const void *data, size_t len, void *priv);
|
|
|
|
/** @brief An error occurred.
|
|
*
|
|
* @param message Error message.
|
|
* @param priv Private user data.
|
|
*/
|
|
void (*error)(const char *message, void *priv);
|
|
};
|
|
|
|
/** @brief Endpoint instance.
|
|
*
|
|
* Token is not important for user of the API. It is implemented in a
|
|
* specific backend.
|
|
*/
|
|
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 {
|
|
|
|
/** Name of the endpoint. */
|
|
const char *name;
|
|
|
|
/** Endpoint priority. If the backend supports priorities. */
|
|
int prio;
|
|
|
|
/** Event callback structure. */
|
|
struct ipc_service_cb cb;
|
|
|
|
/** Private user data. */
|
|
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
|
|
* remote device.
|
|
*
|
|
* The same function registers endpoints for both host and remote 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 instance, endpoint or configuration is invalid.
|
|
* @retval -EBUSY when the instance is busy.
|
|
*
|
|
* @retval 0 on success.
|
|
* @retval other errno codes depending on the implementation of the backend.
|
|
*/
|
|
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.
|
|
*
|
|
* @param ept Registered endpoint by @ref ipc_service_register_endpoint.
|
|
* @param data Pointer to the buffer to send.
|
|
* @param len Number of bytes to send.
|
|
*
|
|
* @retval -EIO when no backend is registered or send hook is missing from
|
|
* backend.
|
|
* @retval -EINVAL when instance or endpoint is invalid.
|
|
* @retval -EBADMSG when the message is invalid.
|
|
* @retval -EBUSY when the instance is busy.
|
|
*
|
|
* @retval 0 on success.
|
|
* @retval other errno codes depending on the implementation of the backend.
|
|
*/
|
|
int ipc_service_send(struct ipc_ept *ept, const void *data, size_t len);
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* ZEPHYR_INCLUDE_IPC_IPC_SERVICE_H_ */
|