Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ipc: Base icmsg implementation on added packed buffer #64624

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions dts/bindings/ipc/zephyr,ipc-icmsg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ properties:
required: true
type: phandle

dcache-alignment:
type: int
description: |
Data cache alignment. If any side of the communication uses cache on
rx-region/tx-region this property must be the biggest value of the
invalidation or the write-back size for both sides of the communication.
If no side of the communication uses data cache this property could be
safely omitted.
For example:
Side A: no data cache
Side B: 32 Bytes write-back size, 16 Bytes invalidation size
dcache-alignment = 32; for both

mboxes:
description: phandle to the MBOX controller (TX and RX are required)
required: true
Expand Down
162 changes: 3 additions & 159 deletions include/zephyr/ipc/icmsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#include <zephyr/kernel.h>
#include <zephyr/drivers/mbox.h>
#include <zephyr/ipc/ipc_service.h>
#include <zephyr/ipc/pbuf.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/sys/spsc_pbuf.h>

#ifdef __cplusplus
extern "C" {
Expand All @@ -33,19 +33,14 @@ enum icmsg_state {
};

struct icmsg_config_t {
uintptr_t tx_shm_addr;
uintptr_t rx_shm_addr;
size_t tx_shm_size;
size_t rx_shm_size;
struct mbox_channel mbox_tx;
struct mbox_channel mbox_rx;
};

struct icmsg_data_t {
/* Tx/Rx buffers. */
struct spsc_pbuf *tx_ib;
struct spsc_pbuf *rx_ib;
atomic_t tx_buffer_state;
struct pbuf *tx_pb;
struct pbuf *rx_pb;
#ifdef CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_SYNC
struct k_mutex tx_lock;
#endif
Expand All @@ -59,12 +54,6 @@ struct icmsg_data_t {
struct k_work_delayable notify_work;
struct k_work mbox_work;
atomic_t state;
/* No-copy */
#ifdef CONFIG_IPC_SERVICE_ICMSG_NOCOPY_RX
atomic_t rx_buffer_state;
const void *rx_buffer;
uint16_t rx_len;
#endif
};

/** @brief Open an icmsg instance
Expand Down Expand Up @@ -134,151 +123,6 @@ int icmsg_send(const struct icmsg_config_t *conf,
struct icmsg_data_t *dev_data,
const void *msg, size_t len);

/** @brief Get an empty TX buffer to be sent using @ref icmsg_send_nocopy
*
* This function can be called to get an empty TX buffer so that the
* application can directly put its data into the sending buffer avoiding copy
* performed by the icmsg library.
*
* It is the application responsibility to correctly fill the allocated TX
* buffer with data and passing correct parameters to @ref
* icmsg_send_nocopy function to perform data no-copy-send mechanism.
*
* The size parameter can be used to request a buffer with a certain size:
* - if the size can be accommodated the function returns no errors and the
* buffer is allocated
* - if the requested size is too big, the function returns -ENOMEM and the
* the buffer is not allocated.
* - if the requested size is '0' the buffer is allocated with the maximum
* allowed size.
*
* In all the cases on return the size parameter contains the maximum size for
* the returned buffer.
*
* When the function returns no errors, the buffer is intended as allocated
* and it is released under one of two conditions: (1) when sending the buffer
* using @ref icmsg_send_nocopy (and in this case the buffer is automatically
* released by the backend), (2) when using @ref icmsg_drop_tx_buffer on a
* buffer not sent.
*
* @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[out] data Pointer to the empty TX buffer.
* @param[inout] size Pointer to store the requested TX buffer size. If the
* function returns -ENOMEM, this parameter returns the
* maximum allowed size.
*
* @retval -ENOBUFS when there are no TX buffers available.
* @retval -EALREADY when a buffer was already claimed and not yet released.
* @retval -ENOMEM when the requested size is too big (and the size parameter
* contains the maximum allowed size).
*
* @retval 0 on success.
*/
int icmsg_get_tx_buffer(const struct icmsg_config_t *conf,
struct icmsg_data_t *dev_data,
void **data, size_t *size);

/** @brief Drop and release a TX buffer
*
* Drop and release a TX buffer. It is possible to drop only TX buffers
* obtained by using @ref icmsg_get_tx_buffer.
*
* @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] data Pointer to the TX buffer.
*
* @retval -EALREADY when the buffer was already dropped.
* @retval -ENXIO when the buffer was not obtained using @ref
* ipc_service_get_tx_buffer
*
* @retval 0 on success.
*/
int icmsg_drop_tx_buffer(const struct icmsg_config_t *conf,
struct icmsg_data_t *dev_data,
const void *data);

/** @brief Send a message from a buffer obtained by @ref icmsg_get_tx_buffer
* to the remote icmsg instance.
*
* This is equivalent to @ref icmsg_send but in this case the TX buffer must
* have been obtained by using @ref icmsg_get_tx_buffer.
*
* The API user has to take the responsibility for getting the TX buffer using
* @ref icmsg_get_tx_buffer and filling the TX buffer with the data.
*
* After the @ref icmsg_send_nocopy function is issued the TX buffer is no
* more owned by the sending task and must not be touched anymore unless the
* function fails and returns an error.
*
* If this function returns an error, @ref icmsg_drop_tx_buffer can be used
* to drop the TX buffer.
*
* @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.
*
*
* @return Size of sent data on success.
* @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 -ENXIO when the buffer was not obtained using @ref
* ipc_service_get_tx_buffer
* @retval other errno codes from dependent modules.
*/
int icmsg_send_nocopy(const struct icmsg_config_t *conf,
struct icmsg_data_t *dev_data,
const void *msg, size_t len);

#ifdef CONFIG_IPC_SERVICE_ICMSG_NOCOPY_RX
/** @brief Hold RX buffer to be used outside of the received callback.
*
* @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] data Pointer to the buffer to be held.
*
* @retval 0 on success.
* @retval -EBUSY when the instance has not finished handshake with the remote
* instance.
* @retval -EINVAL when the @p data argument does not point to a valid RX
* buffer.
* @retval -EALREADY when the buffer is already held.
*/
int icmsg_hold_rx_buffer(const struct icmsg_config_t *conf,
struct icmsg_data_t *dev_data,
const void *data);

/** @brief Release RX buffer for future use.
*
* @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] data Pointer to the buffer to be released.
*
* @retval 0 on success.
* @retval -EBUSY when the instance has not finished handshake with the remote
* instance.
* @retval -EINVAL when the @p data argument does not point to a valid RX
* buffer.
* @retval -EALREADY when the buffer is not held.
*/
int icmsg_release_rx_buffer(const struct icmsg_config_t *conf,
struct icmsg_data_t *dev_data,
const void *data);
#endif

/**
* @}
*/
Expand Down
112 changes: 0 additions & 112 deletions include/zephyr/ipc/icmsg_me.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,118 +247,6 @@ int icmsg_me_send(const struct icmsg_config_t *conf,
struct icmsg_me_data_t *data, icmsg_me_ept_id_t id,
const void *msg, size_t len);

/** @brief Get an empty TX buffer to be sent using @ref icmsg_me_send_nocopy
*
* This function is a wrapper around @ref icmsg_get_tx_buffer aligning buffer
* size and pointers to fit header required by the multi-endpoint feature.
* It shares all properites and usage scenarios with @ref icmsg_get_tx_buffer.
*
* @param[in] conf Structure containing configuration parameters for the
& underlying icmsg instance.
* @param[inout] data Structure containing run-time data used by the icmsg_me
* instance. The structure is initialized with
* @ref icmsg_me_init and its content must be preserved
* while the icmsg_me instance is active.
* @param[out] buffer Pointer to the empty TX buffer.
* @param[inout] size Pointer to store the requested TX buffer size. If the
* function returns -ENOMEM, this parameter returns the
* maximum allowed size.
* @param[in] wait Timeout value to wait for a free buffer acceptable by
* the function caller. Only K_NO_WAIT is supported by icmsg.
*
* @retval 0 on success.
* @retval -ENOTSUP when requested unsupported @p wait timeout.
* @retval -ENOBUFS when there are no TX buffers available.
* @retval -ENOMEM when the requested size is too big (and the size parameter
* contains the maximum allowed size).
* @retval other errno codes from dependent modules.
*/
int icmsg_me_get_tx_buffer(const struct icmsg_config_t *conf,
struct icmsg_me_data_t *data,
void **buffer, uint32_t *size, k_timeout_t wait);

/** @brief Drop and release a TX buffer
*
* This function is a wrapper around @ref icmsg_drop_tx_buffer aligning buffer
* pointer to fit header required by the multi-endpoint feature. This function
* shares all properties and usage scenarios with @ref icmsg_drop_tx_buffer.
*
* @param[in] conf Structure containing configuration parameters for the
* underlying icmsg instance.
* @param[inout] data Structure containing run-time data used by the icmsg_me
* instance. The structure is initialized with
* @ref icmsg_me_init and its content must be preserved
* while the icmsg_me instance is active.
* @param[in] buffer Pointer to the TX buffer obtained with
* @ref icmsg_me_get_tx_buffer.
*
* @retval 0 on success.
* @retval other errno codes from dependent modules.
*/
int icmsg_me_drop_tx_buffer(const struct icmsg_config_t *conf,
struct icmsg_me_data_t *data,
const void *buffer);

/** @brief Send a message from a buffer obtained by @ref icmsg_me_get_tx_buffer
* to the remote icmsg_me instance.
*
* This function is a wrapper around @ref icmsg_send_nocopy aligning buffer
* size and pointer to fit header required by the multi-endpoint feature. This
* function shares all properties and usage scenarios with
* @ref icmsg_send_nocopy.
*
* @param[in] conf Structure containing configuration parameters for the
* underlying icmsg instance.
* @param[inout] data Structure containing run-time data used by the icmsg_me
* instance. The structure is initialized with
* @ref icmsg_me_init and its content must be preserved
* while the icmsg_me instance is active.
* @param[in] id Id of the endpoint to use.
* @param[in] msg Pointer to a buffer containing data to send.
* @param[in] len Size of data in the @p msg buffer.
*
*
* @return Size of sent data on success.
* @retval other errno codes from dependent modules.
*/
int icmsg_me_send_nocopy(const struct icmsg_config_t *conf,
struct icmsg_me_data_t *data, icmsg_me_ept_id_t id,
const void *msg, size_t len);

#ifdef CONFIG_IPC_SERVICE_ICMSG_ME_NOCOPY_RX
/** @brief Hold RX buffer to be used outside of the received callback.
*
* @param[in] conf Structure containing configuration parameters for the
* underlying icmsg instance.
* @param[inout] data Structure containing run-time data used by the icmsg_me
* instance. The structure is initialized with
* @ref icmsg_me_init and its content must be preserved
* while the icmsg_me instance is active.
* @param[in] buffer Pointer to the buffer to be held.
*
* @retval 0 on success.
* @retval other errno codes from dependent modules.
*/
int icmsg_me_hold_rx_buffer(const struct icmsg_config_t *conf,
struct icmsg_me_data_t *data, void *buffer);

/** @brief Release RX buffer for future use.
*
* @param[in] conf Structure containing configuration parameters for the
* underlying icmsg instance.
* @param[inout] data Structure containing run-time data used by the icmsg_me
* instance. The structure is initialized with
* @ref icmsg_me_init and its content must be preserved
* while the icmsg_me instance is active.
* @param[in] buffer Pointer to the buffer to be released.
*
* @retval 0 on success.
* @retval other errno codes from dependent modules.
*/
int icmsg_me_release_rx_buffer(const struct icmsg_config_t *conf,
struct icmsg_me_data_t *data, void *buffer);
#endif /* CONFIG_IPC_SERVICE_ICMSG_ME_NOCOPY_RX */

/**
* @}
*/
Expand Down
Loading
Loading