LCOV - code coverage report
Current view: top level - zephyr/ipc - pbuf.h Hit Total Coverage
Test: new.info Lines: 11 22 50.0 %
Date: 2024-12-22 00:14:23

          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 *wr_idx_loc;  /* Address of the variable holding
      55             :                                          * index value of the first free byte
      56             :                                          * in data[].
      57             :                                          */
      58           0 :         uint32_t dcache_alignment;      /* CPU data cache line size in bytes.
      59             :                                          * Used for validation - TODO: To be
      60             :                                          * replaced by flags.
      61             :                                          */
      62           0 :         uint32_t len;                   /* Length of data[] in bytes. */
      63           0 :         uint8_t *data_loc;              /* Location of the data[]. */
      64             : };
      65             : 
      66             : /**
      67             :  * @brief Data block of the packed buffer.
      68             :  *
      69             :  * The structure contains local copies of wr and rd indexes used by writer and
      70             :  * reader respectively.
      71             :  */
      72           1 : struct pbuf_data {
      73           0 :         volatile uint32_t wr_idx;       /* Index of the first holding first
      74             :                                          * free byte in data[]. Used for
      75             :                                          * writing.
      76             :                                          */
      77           0 :         volatile uint32_t rd_idx;       /* Index of the first holding first
      78             :                                          * valid byte in data[]. Used for
      79             :                                          * reading.
      80             :                                          */
      81             : };
      82             : 
      83             : 
      84             : /**
      85             :  * @brief Scure packed buffer.
      86             :  *
      87             :  * The packet buffer implements lightweight unidirectional packet
      88             :  * buffer with read/write semantics on top of a memory region shared
      89             :  * by the reader and writer. It embeds cache and memory barrier management to
      90             :  * ensure correct data access.
      91             :  *
      92             :  * This structure supports single writer and reader. Data stored in the buffer
      93             :  * is encapsulated to a message (with length header). The read/write API is
      94             :  * written in a way to protect the data from being corrupted.
      95             :  */
      96           1 : struct pbuf {
      97           0 :         PBUF_MAYBE_CONST struct pbuf_cfg *const cfg; /* Configuration of the
      98             :                                                       * buffer.
      99             :                                                       */
     100           0 :         struct pbuf_data data;                  /* Data used to read and write
     101             :                                                  * to the buffer
     102             :                                                  */
     103             : };
     104             : 
     105             : /**
     106             :  * @brief Macro for configuration initialization.
     107             :  *
     108             :  * It is recommended to use this macro to initialize packed buffer
     109             :  * configuration.
     110             :  *
     111             :  * @param mem_addr      Memory address for pbuf.
     112             :  * @param size          Size of the memory.
     113             :  * @param dcache_align  Data cache alignment.
     114             :  */
     115           1 : #define PBUF_CFG_INIT(mem_addr, size, dcache_align)                                     \
     116             : {                                                                                       \
     117             :         .rd_idx_loc = (uint32_t *)(mem_addr),                                           \
     118             :         .wr_idx_loc = (uint32_t *)((uint8_t *)(mem_addr) +                              \
     119             :                                 MAX(dcache_align, _PBUF_IDX_SIZE)),                     \
     120             :         .data_loc = (uint8_t *)((uint8_t *)(mem_addr) +                                 \
     121             :                                 MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE),    \
     122             :         .len = (uint32_t)((uint32_t)(size) - MAX(dcache_align, _PBUF_IDX_SIZE) -        \
     123             :                                 _PBUF_IDX_SIZE),                                        \
     124             :         .dcache_alignment = (dcache_align),                                             \
     125             : }
     126             : 
     127             : /**
     128             :  * @brief Macro calculates memory overhead taken by the header in shared memory.
     129             :  *
     130             :  * It contains the read index, write index and padding.
     131             :  *
     132             :  * @param dcache_align  Data cache alignment.
     133             :  */
     134           1 : #define PBUF_HEADER_OVERHEAD(dcache_align) \
     135             :         (MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE)
     136             : 
     137             : /**
     138             :  * @brief Statically define and initialize pbuf.
     139             :  *
     140             :  * @param name                  Name of the pbuf.
     141             :  * @param mem_addr              Memory address for pbuf.
     142             :  * @param size                  Size of the memory.
     143             :  * @param dcache_align  Data cache line size.
     144             :  */
     145           1 : #define PBUF_DEFINE(name, mem_addr, size, dcache_align)                                 \
     146             :         BUILD_ASSERT(dcache_align >= 0,                                                      \
     147             :                         "Cache line size must be non negative.");                     \
     148             :         BUILD_ASSERT((size) > 0 && IS_PTR_ALIGNED_BYTES(size, _PBUF_IDX_SIZE),               \
     149             :                         "Incorrect size.");                                           \
     150             :         BUILD_ASSERT(IS_PTR_ALIGNED_BYTES(mem_addr, MAX(dcache_align, _PBUF_IDX_SIZE)), \
     151             :                         "Misaligned memory.");                                                \
     152             :         BUILD_ASSERT(size >= (MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE +   \
     153             :                         _PBUF_MIN_DATA_LEN), "Insufficient size.");                   \
     154             :         static PBUF_MAYBE_CONST struct pbuf_cfg cfg_##name =                            \
     155             :                         PBUF_CFG_INIT(mem_addr, size, dcache_align);                    \
     156             :         static struct pbuf name = {                                                     \
     157             :                 .cfg = &cfg_##name,                                                 \
     158             :         }
     159             : 
     160             : /**
     161             :  * @brief Initialize the Tx packet buffer.
     162             :  *
     163             :  * This function initializes the Tx packet buffer based on provided configuration.
     164             :  * If the configuration is incorrect, the function will return error.
     165             :  *
     166             :  * It is recommended to use PBUF_DEFINE macro for build time initialization.
     167             :  *
     168             :  * @param pb    Pointer to the packed buffer containing
     169             :  *              configuration and data. Configuration has to be
     170             :  *              fixed before the initialization.
     171             :  * @retval 0 on success.
     172             :  * @retval -EINVAL when the input parameter is incorrect.
     173             :  */
     174           1 : int pbuf_tx_init(struct pbuf *pb);
     175             : 
     176             : /**
     177             :  * @brief Initialize the Rx packet buffer.
     178             :  *
     179             :  * This function initializes the Rx packet buffer.
     180             :  * If the configuration is incorrect, the function will return error.
     181             :  *
     182             :  * It is recommended to use PBUF_DEFINE macro for build time initialization.
     183             :  *
     184             :  * @param pb    Pointer to the packed buffer containing
     185             :  *              configuration and data. Configuration has to be
     186             :  *              fixed before the initialization.
     187             :  * @retval 0 on success.
     188             :  * @retval -EINVAL when the input parameter is incorrect.
     189             :  */
     190           1 : int pbuf_rx_init(struct pbuf *pb);
     191             : 
     192             : /**
     193             :  * @brief Write specified amount of data to the packet buffer.
     194             :  *
     195             :  * This function call writes specified amount of data to the packet buffer if
     196             :  * the buffer will fit the data.
     197             :  *
     198             :  * @param pb    A buffer to which to write.
     199             :  * @param buf   Pointer to the data to be written to the buffer.
     200             :  * @param len   Number of bytes to be written to the buffer. Must be positive.
     201             :  * @retval int  Number of bytes written, negative error code on fail.
     202             :  *              -EINVAL, if any of input parameter is incorrect.
     203             :  *              -ENOMEM, if len is bigger than the buffer can fit.
     204             :  */
     205             : 
     206           1 : int pbuf_write(struct pbuf *pb, const char *buf, uint16_t len);
     207             : 
     208             : /**
     209             :  * @brief Read specified amount of data from the packet buffer.
     210             :  *
     211             :  * Single read allows to read the message send by the single write.
     212             :  * The provided %p buf must be big enough to store the whole message.
     213             :  *
     214             :  * @param pb    A buffer from which data will be read.
     215             :  * @param buf   Data pointer to which read data will be written.
     216             :  *              If NULL, len of stored message is returned.
     217             :  * @param len   Number of bytes to be read from the buffer.
     218             :  * @retval int  Bytes read, negative error code on fail.
     219             :  *              Bytes to be read, if buf == NULL.
     220             :  *              -EINVAL, if any of input parameter is incorrect.
     221             :  *              -ENOMEM, if message can not fit in provided buf.
     222             :  *              -EAGAIN, if not whole message is ready yet.
     223             :  */
     224           1 : int pbuf_read(struct pbuf *pb, char *buf, uint16_t len);
     225             : 
     226             : /**
     227             :  * @}
     228             :  */
     229             : 
     230             : #ifdef __cplusplus
     231             : }
     232             : #endif
     233             : 
     234             : #endif /* ZEPHYR_INCLUDE_IPC_PBUF_H_ */

Generated by: LCOV version 1.14