1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_IPC_ICMSG_H_
8 #define ZEPHYR_INCLUDE_IPC_ICMSG_H_
9 
10 #include <stddef.h>
11 #include <stdint.h>
12 #include <zephyr/kernel.h>
13 #include <zephyr/drivers/mbox.h>
14 #include <zephyr/ipc/ipc_service.h>
15 #include "pbuf_v1.h"
16 #include <zephyr/sys/atomic.h>
17 
18 /* Config aliases that prevenets from config collisions: */
19 #undef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC
20 #ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC_V1
21 #define CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC_V1
22 #endif
23 #undef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_TO_MS
24 #ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_TO_MS_V1
25 #define CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_TO_MS CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_TO_MS_V1
26 #endif
27 #undef CONFIG_IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS
28 #ifdef CONFIG_IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS_V1
29 #define CONFIG_IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS \
30 	CONFIG_IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS_V1
31 #endif
32 #undef CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE
33 #ifdef CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE_V1
34 #define CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE_V1
35 #endif
36 #undef CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_STACK_SIZE
37 #ifdef CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_STACK_SIZE_V1
38 #define CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_STACK_SIZE \
39 	CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_STACK_SIZE_V1
40 #endif
41 #undef CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_PRIORITY
42 #ifdef CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_PRIORITY_V1
43 #define CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_PRIORITY CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_PRIORITY_V1
44 #endif
45 #undef CONFIG_PBUF_RX_READ_BUF_SIZE
46 #ifdef CONFIG_PBUF_RX_READ_BUF_SIZE_V1
47 #define CONFIG_PBUF_RX_READ_BUF_SIZE CONFIG_PBUF_RX_READ_BUF_SIZE_V1
48 #endif
49 
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 
54 /**
55  * @brief Icmsg IPC library API
56  * @defgroup ipc_icmsg_api Icmsg IPC library API
57  * @ingroup ipc
58  * @{
59  */
60 
61 enum icmsg_state {
62 	ICMSG_STATE_OFF,
63 	ICMSG_STATE_BUSY,
64 	ICMSG_STATE_READY,
65 };
66 
67 struct icmsg_config_t {
68 	struct mbox_dt_spec mbox_tx;
69 	struct mbox_dt_spec mbox_rx;
70 };
71 
72 struct icmsg_data_t {
73 	/* Tx/Rx buffers. */
74 	struct pbuf *tx_pb;
75 	struct pbuf *rx_pb;
76 #ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC
77 	struct k_mutex tx_lock;
78 #endif
79 
80 	/* Callbacks for an endpoint. */
81 	const struct ipc_service_cb *cb;
82 	void *ctx;
83 
84 	/* General */
85 	const struct icmsg_config_t *cfg;
86 #ifdef CONFIG_MULTITHREADING
87 	struct k_work_delayable notify_work;
88 	struct k_work mbox_work;
89 #endif
90 	atomic_t state;
91 };
92 
93 /** @brief Open an icmsg instance
94  *
95  *  Open an icmsg instance to be able to send and receive messages to a remote
96  *  instance.
97  *  This function is blocking until the handshake with the remote instance is
98  *  completed.
99  *  This function is intended to be called late in the initialization process,
100  *  possibly from a thread which can be safely blocked while handshake with the
101  *  remote instance is being pefromed.
102  *
103  *  @param[in] conf Structure containing configuration parameters for the icmsg
104  *                  instance.
105  *  @param[inout] dev_data Structure containing run-time data used by the icmsg
106  *                         instance.
107  *  @param[in] cb Structure containing callback functions to be called on
108  *                events generated by this icmsg instance. The pointed memory
109  *                must be preserved while the icmsg instance is active.
110  *  @param[in] ctx Pointer to context passed as an argument to callbacks.
111  *
112  *
113  *  @retval 0 on success.
114  *  @retval -EALREADY when the instance is already opened.
115  *  @retval other errno codes from dependent modules.
116  */
117 int icmsg_open(const struct icmsg_config_t *conf,
118 	       struct icmsg_data_t *dev_data,
119 	       const struct ipc_service_cb *cb, void *ctx);
120 
121 /** @brief Close an icmsg instance
122  *
123  *  Closing an icmsg instance results in releasing all resources used by given
124  *  instance including the shared memory regions and mbox devices.
125  *
126  *  @param[in] conf Structure containing configuration parameters for the icmsg
127  *                  instance being closed. Its content must be the same as used
128  *                  for creating this instance with @ref icmsg_open.
129  *  @param[inout] dev_data Structure containing run-time data used by the icmsg
130  *                         instance.
131  *
132  *  @retval 0 on success.
133  *  @retval other errno codes from dependent modules.
134  */
135 int icmsg_close(const struct icmsg_config_t *conf,
136 		struct icmsg_data_t *dev_data);
137 
138 /** @brief Send a message to the remote icmsg instance.
139  *
140  *  @param[in] conf Structure containing configuration parameters for the icmsg
141  *                  instance.
142  *  @param[inout] dev_data Structure containing run-time data used by the icmsg
143  *                         instance.
144  *  @param[in] msg Pointer to a buffer containing data to send.
145  *  @param[in] len Size of data in the @p msg buffer.
146  *
147  *
148  *  @retval Number of sent bytes.
149  *  @retval -EBUSY when the instance has not finished handshake with the remote
150  *                 instance.
151  *  @retval -ENODATA when the requested data to send is empty.
152  *  @retval -EBADMSG when the requested data to send is too big.
153  *  @retval -ENOBUFS when there are no TX buffers available.
154  *  @retval other errno codes from dependent modules.
155  */
156 int icmsg_send(const struct icmsg_config_t *conf,
157 	       struct icmsg_data_t *dev_data,
158 	       const void *msg, size_t len);
159 
160 /**
161  * @}
162  */
163 
164 #ifdef __cplusplus
165 }
166 #endif
167 
168 #endif /* ZEPHYR_INCLUDE_IPC_ICMSG_H_ */
169