/* * Copyright (c) 2022 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_IPC_ICMSG_H_ #define ZEPHYR_INCLUDE_IPC_ICMSG_H_ #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /** * @brief Icmsg IPC library API * @defgroup ipc_icmsg_api Icmsg IPC library API * @ingroup ipc * @{ */ enum icmsg_state { /** Instance is not initialized yet. In this state: sending will fail, opening allowed. */ ICMSG_STATE_OFF, /** Instance is initializing without session handshake. In this state: sending will fail, * opening will fail. */ ICMSG_STATE_INITIALIZING_SID_DISABLED, /** Instance is initializing with session handshake. It is waiting for remote to acknowledge * local session id. In this state: sending will fail, opening is allowed (local session id * will change, so the remote may get unbound() callback). */ ICMSG_STATE_INITIALIZING_SID_ENABLED, /** Instance is initializing with detection of session handshake support on remote side. * It is waiting for remote to acknowledge local session id or to send magic bytes. * In this state: sending will fail, opening is allowed (local session id * will change, so the remote may get unbound() callback if it supports it). */ ICMSG_STATE_INITIALIZING_SID_DETECT, /** Instance was closed on remote side. The unbound() callback was send on local side. * In this state: sending will be silently discarded (there may be outdated sends), * opening is allowed. */ ICMSG_STATE_DISCONNECTED, /* Connected states must be at the end. */ /** Instance is connected without session handshake support. In this state: sending will be * successful, opening will fail. */ ICMSG_STATE_CONNECTED_SID_DISABLED, /** Instance is connected with session handshake support. In this state: sending will be * successful, opening is allowed (session will change and remote will get unbound() * callback). */ ICMSG_STATE_CONNECTED_SID_ENABLED, }; enum icmsg_unbound_mode { ICMSG_UNBOUND_MODE_DISABLE = ICMSG_STATE_INITIALIZING_SID_DISABLED, ICMSG_UNBOUND_MODE_ENABLE = ICMSG_STATE_INITIALIZING_SID_ENABLED, ICMSG_UNBOUND_MODE_DETECT = ICMSG_STATE_INITIALIZING_SID_DETECT, }; struct icmsg_config_t { struct mbox_dt_spec mbox_tx; struct mbox_dt_spec mbox_rx; enum icmsg_unbound_mode unbound_mode; }; struct icmsg_data_t { /* Tx/Rx buffers. */ struct pbuf *tx_pb; struct pbuf *rx_pb; #ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC struct k_mutex tx_lock; #endif /* Callbacks for an endpoint. */ const struct ipc_service_cb *cb; void *ctx; /* General */ const struct icmsg_config_t *cfg; #ifdef CONFIG_MULTITHREADING struct k_work mbox_work; #endif uint16_t remote_sid; uint16_t local_sid; atomic_t state; }; /** @brief Open an icmsg instance * * Open an icmsg instance to be able to send and receive messages to a remote * instance. * This function is blocking until the handshake with the remote instance is * completed. * This function is intended to be called late in the initialization process, * possibly from a thread which can be safely blocked while handshake with the * remote instance is being performed. * * @param[in] conf Structure containing configuration parameters for the icmsg * instance. * @param[inout] dev_data Structure containing run-time data used by the icmsg * instance. * @param[in] cb Structure containing callback functions to be called on * events generated by this icmsg instance. The pointed memory * must be preserved while the icmsg instance is active. * @param[in] ctx Pointer to context passed as an argument to callbacks. * * * @retval 0 on success. * @retval -EALREADY when the instance is already opened. * @retval other errno codes from dependent modules. */ int icmsg_open(const struct icmsg_config_t *conf, struct icmsg_data_t *dev_data, const struct ipc_service_cb *cb, void *ctx); /** @brief Close an icmsg instance * * Closing an icmsg instance results in releasing all resources used by given * instance including the shared memory regions and mbox devices. * * @param[in] conf Structure containing configuration parameters for the icmsg * instance being closed. Its content must be the same as used * for creating this instance with @ref icmsg_open. * @param[inout] dev_data Structure containing run-time data used by the icmsg * instance. * * @retval 0 on success. * @retval other errno codes from dependent modules. */ int icmsg_close(const struct icmsg_config_t *conf, struct icmsg_data_t *dev_data); /** @brief Send a message to the remote icmsg instance. * * @param[in] conf Structure containing configuration parameters for the icmsg * instance. * @param[inout] dev_data Structure containing run-time data used by the icmsg * instance. * @param[in] msg Pointer to a buffer containing data to send. * @param[in] len Size of data in the @p msg buffer. * * * @retval Number of sent bytes. * @retval -EBUSY when the instance has not finished handshake with the remote * instance. * @retval -ENODATA when the requested data to send is empty. * @retval -EBADMSG when the requested data to send is too big. * @retval -ENOBUFS when there are no TX buffers available. * @retval other errno codes from dependent modules. */ int icmsg_send(const struct icmsg_config_t *conf, struct icmsg_data_t *dev_data, const void *msg, size_t len); /** * @} */ #ifdef __cplusplus } #endif #endif /* ZEPHYR_INCLUDE_IPC_ICMSG_H_ */