/* * 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 #include #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_ */