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