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 <zephyr/ipc/pbuf.h>
16 #include <zephyr/sys/atomic.h>
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 /**
23  * @brief Icmsg IPC library API
24  * @defgroup ipc_icmsg_api Icmsg IPC library API
25  * @ingroup ipc
26  * @{
27  */
28 
29 enum icmsg_state {
30 	ICMSG_STATE_OFF,
31 	ICMSG_STATE_BUSY,
32 	ICMSG_STATE_READY,
33 };
34 
35 struct icmsg_config_t {
36 	struct mbox_dt_spec mbox_tx;
37 	struct mbox_dt_spec mbox_rx;
38 };
39 
40 struct icmsg_data_t {
41 	/* Tx/Rx buffers. */
42 	struct pbuf *tx_pb;
43 	struct pbuf *rx_pb;
44 #ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC
45 	struct k_mutex tx_lock;
46 #endif
47 
48 	/* Callbacks for an endpoint. */
49 	const struct ipc_service_cb *cb;
50 	void *ctx;
51 
52 	/* General */
53 	const struct icmsg_config_t *cfg;
54 #ifdef CONFIG_MULTITHREADING
55 	struct k_work_delayable notify_work;
56 	struct k_work mbox_work;
57 #endif
58 	atomic_t state;
59 };
60 
61 /** @brief Open an icmsg instance
62  *
63  *  Open an icmsg instance to be able to send and receive messages to a remote
64  *  instance.
65  *  This function is blocking until the handshake with the remote instance is
66  *  completed.
67  *  This function is intended to be called late in the initialization process,
68  *  possibly from a thread which can be safely blocked while handshake with the
69  *  remote instance is being performed.
70  *
71  *  @param[in] conf Structure containing configuration parameters for the icmsg
72  *                  instance.
73  *  @param[inout] dev_data Structure containing run-time data used by the icmsg
74  *                         instance.
75  *  @param[in] cb Structure containing callback functions to be called on
76  *                events generated by this icmsg instance. The pointed memory
77  *                must be preserved while the icmsg instance is active.
78  *  @param[in] ctx Pointer to context passed as an argument to callbacks.
79  *
80  *
81  *  @retval 0 on success.
82  *  @retval -EALREADY when the instance is already opened.
83  *  @retval other errno codes from dependent modules.
84  */
85 int icmsg_open(const struct icmsg_config_t *conf,
86 	       struct icmsg_data_t *dev_data,
87 	       const struct ipc_service_cb *cb, void *ctx);
88 
89 /** @brief Close an icmsg instance
90  *
91  *  Closing an icmsg instance results in releasing all resources used by given
92  *  instance including the shared memory regions and mbox devices.
93  *
94  *  @param[in] conf Structure containing configuration parameters for the icmsg
95  *                  instance being closed. Its content must be the same as used
96  *                  for creating this instance with @ref icmsg_open.
97  *  @param[inout] dev_data Structure containing run-time data used by the icmsg
98  *                         instance.
99  *
100  *  @retval 0 on success.
101  *  @retval other errno codes from dependent modules.
102  */
103 int icmsg_close(const struct icmsg_config_t *conf,
104 		struct icmsg_data_t *dev_data);
105 
106 /** @brief Send a message to the remote icmsg instance.
107  *
108  *  @param[in] conf Structure containing configuration parameters for the icmsg
109  *                  instance.
110  *  @param[inout] dev_data Structure containing run-time data used by the icmsg
111  *                         instance.
112  *  @param[in] msg Pointer to a buffer containing data to send.
113  *  @param[in] len Size of data in the @p msg buffer.
114  *
115  *
116  *  @retval Number of sent bytes.
117  *  @retval -EBUSY when the instance has not finished handshake with the remote
118  *                 instance.
119  *  @retval -ENODATA when the requested data to send is empty.
120  *  @retval -EBADMSG when the requested data to send is too big.
121  *  @retval -ENOBUFS when there are no TX buffers available.
122  *  @retval other errno codes from dependent modules.
123  */
124 int icmsg_send(const struct icmsg_config_t *conf,
125 	       struct icmsg_data_t *dev_data,
126 	       const void *msg, size_t len);
127 
128 /**
129  * @}
130  */
131 
132 #ifdef __cplusplus
133 }
134 #endif
135 
136 #endif /* ZEPHYR_INCLUDE_IPC_ICMSG_H_ */
137