LCOV - code coverage report
Current view: top level - zephyr/ipc - pbuf.h Coverage Total Hit
Test: new.info Lines: 53.8 % 26 14
Test Date: 2025-09-05 16:43:28

            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_PBUF_H_
       8              : #define ZEPHYR_INCLUDE_IPC_PBUF_H_
       9              : 
      10              : #include <zephyr/cache.h>
      11              : #include <zephyr/devicetree.h>
      12              : 
      13              : #ifdef __cplusplus
      14              : extern "C" {
      15              : #endif
      16              : 
      17              : /**
      18              :  * @brief Packed buffer API
      19              :  * @defgroup pbuf Packed Buffer API
      20              :  * @ingroup ipc
      21              :  * @{
      22              :  */
      23              : 
      24              : /** @brief Size of packet length field. */
      25            1 : #define PBUF_PACKET_LEN_SZ sizeof(uint32_t)
      26              : 
      27              : /* Amount of data that is left unused to distinguish between empty and full. */
      28              : #define _PBUF_IDX_SIZE sizeof(uint32_t)
      29              : 
      30              : /* Minimal length of the data field in the buffer to store the smalest packet
      31              :  * possible.
      32              :  * (+1) for at least one byte of data.
      33              :  * (+_PBUF_IDX_SIZE) to distinguish buffer full and buffer empty.
      34              :  * Rounded up to keep wr/rd indexes pointing to aligned address.
      35              :  */
      36              : #define _PBUF_MIN_DATA_LEN ROUND_UP(PBUF_PACKET_LEN_SZ + 1 + _PBUF_IDX_SIZE, _PBUF_IDX_SIZE)
      37              : 
      38              : #if defined(CONFIG_ARCH_POSIX)
      39              : /* For the native simulated boards we need to modify some pointers at init */
      40              : #define PBUF_MAYBE_CONST
      41              : #else
      42            0 : #define PBUF_MAYBE_CONST const
      43              : #endif
      44              : 
      45              : /** @brief Control block of packet buffer.
      46              :  *
      47              :  * The structure contains configuration data.
      48              :  */
      49            1 : struct pbuf_cfg {
      50            0 :         volatile uint32_t *rd_idx_loc;   /* Address of the variable holding
      51              :                                           * index value of the first valid byte
      52              :                                           * in data[].
      53              :                                           */
      54            0 :         volatile uint32_t *handshake_loc;/* Address of the variable holding
      55              :                                           * handshake information.
      56              :                                           */
      57            0 :         volatile uint32_t *wr_idx_loc;   /* Address of the variable holding
      58              :                                           * index value of the first free byte
      59              :                                           * in data[].
      60              :                                           */
      61            0 :         uint32_t dcache_alignment;       /* CPU data cache line size in bytes.
      62              :                                           * Used for validation - TODO: To be
      63              :                                           * replaced by flags.
      64              :                                           */
      65            0 :         uint32_t len;                    /* Length of data[] in bytes. */
      66            0 :         uint8_t *data_loc;               /* Location of the data[]. */
      67              : };
      68              : 
      69              : /**
      70              :  * @brief Data block of the packed buffer.
      71              :  *
      72              :  * The structure contains local copies of wr and rd indexes used by writer and
      73              :  * reader respectively.
      74              :  */
      75            1 : struct pbuf_data {
      76            0 :         volatile uint32_t wr_idx;       /* Index of the first holding first
      77              :                                          * free byte in data[]. Used for
      78              :                                          * writing.
      79              :                                          */
      80            0 :         volatile uint32_t rd_idx;       /* Index of the first holding first
      81              :                                          * valid byte in data[]. Used for
      82              :                                          * reading.
      83              :                                          */
      84              : };
      85              : 
      86              : 
      87              : /**
      88              :  * @brief Scure packed buffer.
      89              :  *
      90              :  * The packet buffer implements lightweight unidirectional packet
      91              :  * buffer with read/write semantics on top of a memory region shared
      92              :  * by the reader and writer. It embeds cache and memory barrier management to
      93              :  * ensure correct data access.
      94              :  *
      95              :  * This structure supports single writer and reader. Data stored in the buffer
      96              :  * is encapsulated to a message (with length header). The read/write API is
      97              :  * written in a way to protect the data from being corrupted.
      98              :  */
      99            1 : struct pbuf {
     100            0 :         PBUF_MAYBE_CONST struct pbuf_cfg *const cfg; /* Configuration of the
     101              :                                                       * buffer.
     102              :                                                       */
     103            0 :         struct pbuf_data data;                  /* Data used to read and write
     104              :                                                  * to the buffer
     105              :                                                  */
     106              : };
     107              : 
     108              : /**
     109              :  * @brief Macro for configuration initialization.
     110              :  *
     111              :  * It is recommended to use this macro to initialize packed buffer
     112              :  * configuration.
     113              :  *
     114              :  * @param mem_addr      Memory address for pbuf.
     115              :  * @param size          Size of the memory.
     116              :  * @param dcache_align  Data cache alignment.
     117              :  * @param use_handshake Add handshake word inside shared memory that can be access with
     118              :  *                      @ref pbuf_handshake_read and @ref pbuf_handshake_write.
     119              :  */
     120            1 : #define PBUF_CFG_INIT(mem_addr, size, dcache_align, use_handshake)                      \
     121              : {                                                                                       \
     122              :         .rd_idx_loc = (uint32_t *)(mem_addr),                                           \
     123              :         .handshake_loc = use_handshake ? (uint32_t *)((uint8_t *)(mem_addr) +           \
     124              :                                 _PBUF_IDX_SIZE) : NULL,                                 \
     125              :         .wr_idx_loc = (uint32_t *)((uint8_t *)(mem_addr) + MAX(dcache_align,            \
     126              :                                 (use_handshake ? 2 : 1) * _PBUF_IDX_SIZE)),             \
     127              :         .data_loc = (uint8_t *)((uint8_t *)(mem_addr) +                                 \
     128              :                                 MAX(dcache_align, (use_handshake ? 2 : 1) *             \
     129              :                                                   _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE),    \
     130              :         .len = (uint32_t)((uint32_t)(size) - MAX(dcache_align,                          \
     131              :                         (use_handshake ? 2 : 1) * _PBUF_IDX_SIZE) - _PBUF_IDX_SIZE),    \
     132              :         .dcache_alignment = (dcache_align),                                             \
     133              : }
     134              : 
     135              : /**
     136              :  * @brief Macro calculates memory overhead taken by the header in shared memory.
     137              :  *
     138              :  * It contains the read index, write index and padding.
     139              :  *
     140              :  * @param dcache_align  Data cache alignment.
     141              :  */
     142            1 : #define PBUF_HEADER_OVERHEAD(dcache_align) \
     143              :         (MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE)
     144              : 
     145              : /**
     146              :  * @brief Statically define and initialize pbuf.
     147              :  *
     148              :  * @param name                  Name of the pbuf.
     149              :  * @param mem_addr              Memory address for pbuf.
     150              :  * @param size                  Size of the memory.
     151              :  * @param dcache_align          Data cache line size.
     152              :  * @param use_handshake         Add handshake word inside shared memory that can be access with
     153              :  *                              @ref pbuf_handshake_read and @ref pbuf_handshake_write.
     154              :  */
     155            1 : #define PBUF_DEFINE(name, mem_addr, size, dcache_align, use_handshake, compatibility)   \
     156              :         BUILD_ASSERT(dcache_align >= 0,                                                      \
     157              :                         "Cache line size must be non negative.");                     \
     158              :         BUILD_ASSERT((size) > 0 && IS_PTR_ALIGNED_BYTES(size, _PBUF_IDX_SIZE),               \
     159              :                         "Incorrect size.");                                           \
     160              :         BUILD_ASSERT(IS_PTR_ALIGNED_BYTES(mem_addr, MAX(dcache_align, _PBUF_IDX_SIZE)), \
     161              :                         "Misaligned memory.");                                                \
     162              :         BUILD_ASSERT(size >= (MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE +   \
     163              :                         _PBUF_MIN_DATA_LEN), "Insufficient size.");                   \
     164              :         BUILD_ASSERT(!(compatibility) || (dcache_align) >= 8,                                \
     165              :                 "Data cache alignment must be at least 8 if compatibility is enabled.");\
     166              :         static PBUF_MAYBE_CONST struct pbuf_cfg cfg_##name =                            \
     167              :                         PBUF_CFG_INIT(mem_addr, size, dcache_align, use_handshake);     \
     168              :         static struct pbuf name = {                                                     \
     169              :                 .cfg = &cfg_##name,                                                 \
     170              :         }
     171              : 
     172              : /**
     173              :  * @brief Initialize the Tx packet buffer.
     174              :  *
     175              :  * This function initializes the Tx packet buffer based on provided configuration.
     176              :  * If the configuration is incorrect, the function will return error.
     177              :  *
     178              :  * It is recommended to use PBUF_DEFINE macro for build time initialization.
     179              :  *
     180              :  * @param pb    Pointer to the packed buffer containing
     181              :  *              configuration and data. Configuration has to be
     182              :  *              fixed before the initialization.
     183              :  * @retval 0 on success.
     184              :  * @retval -EINVAL when the input parameter is incorrect.
     185              :  */
     186            1 : int pbuf_tx_init(struct pbuf *pb);
     187              : 
     188              : /**
     189              :  * @brief Initialize the Rx packet buffer.
     190              :  *
     191              :  * This function initializes the Rx packet buffer.
     192              :  * If the configuration is incorrect, the function will return error.
     193              :  *
     194              :  * It is recommended to use PBUF_DEFINE macro for build time initialization.
     195              :  *
     196              :  * @param pb    Pointer to the packed buffer containing
     197              :  *              configuration and data. Configuration has to be
     198              :  *              fixed before the initialization.
     199              :  * @retval 0 on success.
     200              :  * @retval -EINVAL when the input parameter is incorrect.
     201              :  */
     202            1 : int pbuf_rx_init(struct pbuf *pb);
     203              : 
     204              : /**
     205              :  * @brief Write specified amount of data to the packet buffer.
     206              :  *
     207              :  * This function call writes specified amount of data to the packet buffer if
     208              :  * the buffer will fit the data.
     209              :  *
     210              :  * @param pb    A buffer to which to write.
     211              :  * @param buf   Pointer to the data to be written to the buffer.
     212              :  * @param len   Number of bytes to be written to the buffer. Must be positive.
     213              :  * @retval int  Number of bytes written, negative error code on fail.
     214              :  *              -EINVAL, if any of input parameter is incorrect.
     215              :  *              -ENOMEM, if len is bigger than the buffer can fit.
     216              :  */
     217              : 
     218            1 : int pbuf_write(struct pbuf *pb, const char *buf, uint16_t len);
     219              : 
     220              : /**
     221              :  * @brief Read specified amount of data from the packet buffer.
     222              :  *
     223              :  * Single read allows to read the message send by the single write.
     224              :  * The provided %p buf must be big enough to store the whole message.
     225              :  *
     226              :  * @param pb    A buffer from which data will be read.
     227              :  * @param buf   Data pointer to which read data will be written.
     228              :  *              If NULL, len of stored message is returned.
     229              :  * @param len   Number of bytes to be read from the buffer.
     230              :  * @retval int  Bytes read, negative error code on fail.
     231              :  *              Bytes to be read, if buf == NULL.
     232              :  *              -EINVAL, if any of input parameter is incorrect.
     233              :  *              -ENOMEM, if message can not fit in provided buf.
     234              :  *              -EAGAIN, if not whole message is ready yet.
     235              :  */
     236            1 : int pbuf_read(struct pbuf *pb, char *buf, uint16_t len);
     237              : 
     238              : /**
     239              :  * @brief Read handshake word from pbuf.
     240              :  *
     241              :  * The pb must be defined with "PBUF_DEFINE" with "use_handshake" set.
     242              :  *
     243              :  * @param pb            A buffer from which data will be read.
     244              :  * @retval uint32_t     The handshake word value.
     245              :  */
     246            1 : uint32_t pbuf_handshake_read(struct pbuf *pb);
     247              : 
     248              : /**
     249              :  * @brief Write handshake word to pbuf.
     250              :  *
     251              :  * The pb must be defined with "PBUF_DEFINE" with "use_handshake" set.
     252              :  *
     253              :  * @param pb            A buffer to which data will be written.
     254              :  * @param value         A handshake value.
     255              :  */
     256            1 : void pbuf_handshake_write(struct pbuf *pb, uint32_t value);
     257              : 
     258              : /**
     259              :  * @brief Get first buffer from pbuf.
     260              :  *
     261              :  * This function retrieves buffer located at the beginning of queue.
     262              :  * It will be continuous block since it is the first buffer.
     263              :  *
     264              :  * @param pb            A buffer from which data will be read.
     265              :  * @param[out] buf      A pointer to output pointer to the date of the first buffer.
     266              :  * @param[out] len      A pointer to output length the first buffer.
     267              :  * @retval              0 on success.
     268              :  *                      -EINVAL when there is no buffer at the beginning of queue.
     269              :  */
     270            1 : int pbuf_get_initial_buf(struct pbuf *pb, volatile char **buf, uint16_t *len);
     271              : 
     272              : /**
     273              :  * @}
     274              :  */
     275              : 
     276              : #ifdef __cplusplus
     277              : }
     278              : #endif
     279              : 
     280              : #endif /* ZEPHYR_INCLUDE_IPC_PBUF_H_ */
        

Generated by: LCOV version 2.0-1