Line data Source code
1 0 : /* 2 : * Copyright (c) 2023 Nordic Semiconductor ASA 3 : * 4 : * SPDX-License-Identifier: Apache-2.0 5 : */ 6 : 7 : #ifndef ZEPHYR_INCLUDE_IPC_ICMSG_ME_H_ 8 : #define ZEPHYR_INCLUDE_IPC_ICMSG_ME_H_ 9 : 10 : #include <stdint.h> 11 : #include <zephyr/kernel.h> 12 : #include <zephyr/ipc/icmsg.h> 13 : #include <zephyr/ipc/ipc_service.h> 14 : 15 : #ifdef __cplusplus 16 : extern "C" { 17 : #endif 18 : 19 : /** 20 : * @brief Multi-endpoint extension of icmsg IPC library 21 : * @defgroup ipc_icmsg_me_api Icmsg multi-endpoint IPC library API 22 : * @ingroup ipc 23 : * @{ 24 : */ 25 : 26 : 27 : /* If more bytes than 1 was used for endpoint id, endianness should be 28 : * considered. 29 : */ 30 0 : typedef uint8_t icmsg_me_ept_id_t; 31 : 32 0 : struct icmsg_me_data_t { 33 0 : struct icmsg_data_t icmsg_data; 34 0 : struct ipc_ept_cfg ept_cfg; 35 : 36 0 : struct k_event event; 37 : 38 0 : struct k_mutex send_mutex; 39 0 : const struct ipc_ept_cfg *epts[CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_NUM_EP]; 40 : 41 0 : uint8_t send_buffer[CONFIG_IPC_SERVICE_BACKEND_ICMSG_ME_SEND_BUF_SIZE] __aligned(4); 42 : }; 43 : 44 : 45 : /** @brief Initialize an icmsg_me instance 46 : * 47 : * This function is intended to be called during system initialization. 48 : * It initializes the underlying icmsg instance as one of the initialization 49 : * steps. 50 : * 51 : * @param[in] conf Structure containing configuration parameters for the 52 : * underlying icmsg instance being created. 53 : * @param[inout] data Structure containing run-time data used by the icmsg_me 54 : * instance. The structure shall be filled with zeros 55 : * when calling this function. The content of this 56 : * structure must be preserved while the icmsg_me instance 57 : * is active. 58 : * 59 : * @retval 0 on success. 60 : * @retval other errno codes from dependent modules. 61 : */ 62 1 : int icmsg_me_init(const struct icmsg_config_t *conf, 63 : struct icmsg_me_data_t *data); 64 : 65 : /** @brief Open an icmsg_me instance 66 : * 67 : * Open an icmsg_me instance to be able to send and receive messages to a 68 : * remote instance. 69 : * This function is blocking until the handshake with the remote instance is 70 : * completed. 71 : * This function is intended to be called late in the initialization process, 72 : * possibly from a thread which can be safely blocked while handshake with the 73 : * remote instance is being pefromed. 74 : * 75 : * @param[in] conf Structure containing configuration parameters for the 76 : * underlying icmsg instance. 77 : * @param[inout] data Structure containing run-time data used by the icmsg_me 78 : * instance. The structure is initialized with 79 : * @ref icmsg_me_init and its content must be preserved 80 : * while the icmsg_me instance is active. 81 : * @param[in] cb Structure containing callback functions to be called on 82 : * events generated by this icmsg_me instance. The pointed memory 83 : * must be preserved while the icmsg_me instance is active. 84 : * @param[in] ctx Pointer to context passed as an argument to callbacks. 85 : * 86 : * 87 : * @retval 0 on success. 88 : * @retval other errno codes from dependent modules. 89 : */ 90 1 : int icmsg_me_open(const struct icmsg_config_t *conf, 91 : struct icmsg_me_data_t *data, 92 : const struct ipc_service_cb *cb, 93 : void *ctx); 94 : 95 : /** @brief Wait until the underlying icmsg instance calls bound callback 96 : * 97 : * This function blocks calling thread until the underlying icmsg connection 98 : * is bound. If the connection was bound before this function is called, the 99 : * function ends immediately without any delay. 100 : * 101 : * This function is intended to be used in the endpoints handshake procedure 102 : * to make sure that handshake is not performed until the icmsg channel is 103 : * ready to pass handshake messages. 104 : * 105 : * @param[inout] data Structure containing run-time data used by the icmsg_me 106 : * instance. The structure is initialized with 107 : * @ref icmsg_me_init and its content must be preserved 108 : * while the icmsg_me instance is active. 109 : */ 110 1 : void icmsg_me_wait_for_icmsg_bind(struct icmsg_me_data_t *data); 111 : 112 : /** @brief Notify the icmsg_me instance that the underlying icmsg was bound 113 : * 114 : * The icmsg_me API users are responsible to implement the callback functions 115 : * called by the underlying icmsg instance. One of the actions of the bound 116 : * callback must be calling this function. 117 : * 118 : * @param[inout] data Structure containing run-time data used by the icmsg_me 119 : * instance. The structure is initialized with 120 : * @ref icmsg_me_init and its content must be preserved 121 : * while the icmsg_me instance is active. 122 : */ 123 1 : void icmsg_me_icmsg_bound(struct icmsg_me_data_t *data); 124 : 125 : /** @brief Notify the icmsg_me instance that data for an endpoint was received 126 : * 127 : * The icmsg_me API users are responsible to implement the callback functions 128 : * called by the underlying icmsg instance. If the data received by the icmsg 129 : * instance contains data frame destined to one of the endpoints, this 130 : * function must be called. 131 : * 132 : * @param[inout] data Structure containing run-time data used by the icmsg_me 133 : * instance. The structure is initialized with 134 : * @ref icmsg_me_init and its content must be preserved 135 : * while the icmsg_me instance is active. 136 : * @param[in] id The value identifyig the endpoint. 137 : * @param[in] msg Data frame received from the peer, stripped of the 138 : * multi-endpoint header. 139 : * @param[in] len Size of the data pointed by @p msg. 140 : */ 141 1 : void icmsg_me_received_data(struct icmsg_me_data_t *data, icmsg_me_ept_id_t id, 142 : const void *msg, size_t len); 143 : 144 : /** @brief Set endpoint configuration in an empty endpoint slot 145 : * 146 : * During endpoint handshake the handshake initiator must select an id number 147 : * and store endpoint metadata required to finalize handshake and maintain 148 : * the connection. This function is a helper which stores the configuration 149 : * in an empty configuration slot and provides the unique id value associated 150 : * with the selected slot. 151 : * 152 : * @note This function is not reentrant for a single icmsg_me instance. 153 : * It must be protected by the caller using mutex, critical section, 154 : * spinlock, or similar solution. 155 : * This function is reentrant for different icmsg_me instances. The 156 : * protection scope might be limited to a single instance. 157 : * 158 : * @param[inout] data Structure containing run-time data used by the icmsg_me 159 : * instance. The structure is initialized with 160 : * @ref icmsg_me_init and its content must be preserved 161 : * while the icmsg_me instance is active. 162 : * @param[in] ept_cfg Configuration data of the endpoint for which the 163 : * handshake procedure is being initiated. 164 : * @param[out] id The value uniquely identifyig this endpoint. 165 : * 166 : * @retval 0 on success. 167 : * @retval -ENOMEM when there are no more empty endpoint configuration slots. 168 : */ 169 1 : int icmsg_me_set_empty_ept_cfg_slot(struct icmsg_me_data_t *data, 170 : const struct ipc_ept_cfg *ept_cfg, 171 : icmsg_me_ept_id_t *id); 172 : 173 : /** @brief Set endpoint configuration in a selected endpoint slot 174 : * 175 : * During endpoint handshake the handshake follower must store endpoint id and 176 : * metadata required to finalize handshake and maintain the connection. This 177 : * function is a helper which stores the configuration in a configuration slot 178 : * associated with the id of the endpoint. 179 : * 180 : * @param[inout] data Structure containing run-time data used by the icmsg_me 181 : * instance. The structure is initialized with 182 : * @ref icmsg_me_init and its content must be preserved 183 : * while the icmsg_me instance is active. 184 : * @param[in] id The value uniquely identifyig this endpoint. 185 : * @param[in] ept_cfg Configuration data of the endpoint for which the 186 : * handshake procedure is ongoing. 187 : * 188 : * @retval 0 on success. 189 : * @retval -ENOENT when @p id is out of range of available slots. 190 : */ 191 1 : int icmsg_me_set_ept_cfg(struct icmsg_me_data_t *data, icmsg_me_ept_id_t id, 192 : const struct ipc_ept_cfg *ept_cfg); 193 : 194 : /** @brief Get endpoint configuration from a selected endpoint slot 195 : * 196 : * When the icmsg_me instance receives data from a remote endpoint, it must 197 : * get the endpoint configuration based on the id of the endpoint. This 198 : * function is designed for this purpose. 199 : * 200 : * If retrieved endpoint configuration is not set, @p ept_cfg points to NULL. 201 : * 202 : * @param[inout] data Structure containing run-time data used by the icmsg_me 203 : * instance. The structure is initialized with 204 : * @ref icmsg_me_init and its content must be preserved 205 : * while the icmsg_me instance is active. 206 : * @param[in] id The value uniquely identifyig endpoint. 207 : * @param[in] ept_cfg Configuration data of the endpoint with given id. 208 : * 209 : * @retval 0 on success. 210 : * @retval -ENOENT when @p id is out of range of available slots. 211 : */ 212 1 : int icmsg_me_get_ept_cfg(struct icmsg_me_data_t *data, icmsg_me_ept_id_t id, 213 : const struct ipc_ept_cfg **ept_cfg); 214 : 215 : /** @brief Reset endpoint configuration in a selected endpoint slot. 216 : * 217 : * If handshake fails or an endpoint is disconnected, then configuration 218 : * slot for given endpoint should be vacated. This function is intended to 219 : * be used for this purpose. 220 : * 221 : * @param[inout] data Structure containing run-time data used by the icmsg_me 222 : * instance. The structure is initialized with 223 : * @ref icmsg_me_init and its content must be preserved 224 : * while the icmsg_me instance is active. 225 : * @param[in] id The value uniquely identifyig endpoint. 226 : */ 227 1 : void icmsg_me_reset_ept_cfg(struct icmsg_me_data_t *data, icmsg_me_ept_id_t id); 228 : 229 : /** @brief Send a message to the remote icmsg_me endpoint. 230 : * 231 : * @param[in] conf Structure containing configuration parameters for the 232 : * underlying icmsg instance. 233 : * @param[inout] data Structure containing run-time data used by the icmsg_me 234 : * instance. The structure is initialized with 235 : * @ref icmsg_me_init and its content must be preserved 236 : * while the icmsg_me instance is active. 237 : * @param[in] id Id of the endpoint to use. 238 : * @param[in] msg Pointer to a buffer containing data to send. 239 : * @param[in] len Size of data in the @p msg buffer. 240 : * 241 : * 242 : * @retval 0 on success. 243 : * @retval -EBADMSG when the requested data to send is too big. 244 : * @retval other errno codes from dependent modules. 245 : */ 246 1 : int icmsg_me_send(const struct icmsg_config_t *conf, 247 : struct icmsg_me_data_t *data, icmsg_me_ept_id_t id, 248 : const void *msg, size_t len); 249 : 250 : /** 251 : * @} 252 : */ 253 : 254 : #ifdef __cplusplus 255 : } 256 : #endif 257 : 258 : #endif /* ZEPHYR_INCLUDE_IPC_ICMSG_ME_H_ */