@@ -26,6 +26,47 @@ extern "C" {
26
26
27
27
/**@} */
28
28
29
+ #ifndef CONFIG_SPSC_PBUF_CACHE_LINE
30
+ #define CONFIG_SPSC_PBUF_CACHE_LINE 0
31
+ #endif
32
+
33
+ /** @brief Maximum packet length. */
34
+ #define SPSC_PBUF_MAX_LEN 0xFF00
35
+
36
+ /** @brief First part of packet buffer control block.
37
+ *
38
+ * This part contains only data set during the initialization and data touched
39
+ * by the reader. If packet is shared between to cores then data changed by
40
+ * the reader should be on different cache line than the data changed by the
41
+ * writer.
42
+ */
43
+ struct spsc_pbuf_common {
44
+ uint32_t len ; /* Length of data[] in bytes. */
45
+ uint32_t flags ; /* Flags. See @ref SPSC_PBUF_FLAGS */
46
+ uint32_t rd_idx ; /* Index of the first valid byte in data[] */
47
+ };
48
+
49
+ /* Padding to fill cache line. */
50
+ #define Z_SPSC_PBUF_PADDING \
51
+ MAX(0, CONFIG_SPSC_PBUF_CACHE_LINE - (int)sizeof(struct spsc_pbuf_common))
52
+
53
+ /** @brief Remaining part of a packet buffer when cache is used.
54
+ *
55
+ * It contains data that is only changed by the writer. A gap is added to ensure
56
+ * that it is in different cache line than the data changed by the reader.
57
+ */
58
+ struct spsc_pbuf_ext_cache {
59
+ uint8_t reserved [Z_SPSC_PBUF_PADDING ];
60
+ uint32_t wr_idx ; /* Index of the first free byte in data[] */
61
+ uint8_t data []; /* Buffer data. */
62
+ };
63
+
64
+ /** @brief Remaining part of a packet buffer when cache is not used. */
65
+ struct spsc_pbuf_ext_nocache {
66
+ uint32_t wr_idx ; /* Index of the first free byte in data[] */
67
+ uint8_t data []; /* Buffer data. */
68
+ };
69
+
29
70
/**
30
71
* @brief Single producer, single consumer packet buffer
31
72
*
@@ -39,20 +80,27 @@ extern "C" {
39
80
*
40
81
*/
41
82
struct spsc_pbuf {
42
- uint32_t len ; /* Length of data[] in bytes. */
43
- uint32_t wr_idx ; /* Index of the first free byte in data[] */
44
- uint32_t rd_idx ; /* Index of the first valid byte in data[] */
45
- uint32_t flags ; /* Flags. See @ref SPSC_PBUF_FLAGS */
46
- uint8_t data []; /* Buffer data. */
83
+ struct spsc_pbuf_common common ;
84
+ union {
85
+ struct spsc_pbuf_ext_cache cache ;
86
+ struct spsc_pbuf_ext_nocache nocache ;
87
+ } ext ;
47
88
};
48
89
49
90
/** @brief Get buffer capacity.
50
91
*
51
- * @param blen Length of the buffer dedicated for the packet buffer.
92
+ * This value is the amount of data that is dedicated for storing packets. Since
93
+ * each packet is prefixed with 2 byte length header, longest possible packet is
94
+ * less than that.
95
+ *
96
+ * @param pb A buffer.
52
97
*
53
98
* @return Packet buffer capacity.
54
99
*/
55
- #define SPSC_PBUF_CAPACITY (blen ) ((blen) - offsetof(struct spsc_pbuf, data))
100
+ static inline uint32_t spsc_pbuf_capacity (struct spsc_pbuf * pb )
101
+ {
102
+ return pb -> common .len - sizeof (uint32_t );
103
+ }
56
104
57
105
/**
58
106
* @brief Initialize the packet buffer.
@@ -61,36 +109,85 @@ struct spsc_pbuf {
61
109
* memory region.
62
110
*
63
111
* @param buf Pointer to a memory region on which buffer is
64
- * created.
112
+ * created. When cache is used it must be aligned to
113
+ * CONFIG_SPSC_PBUF_CACHE_LINE, otherwise it must
114
+ * be 32 bit word aligned.
65
115
* @param blen Length of the buffer. Must be large enough to
66
116
* contain the internal structure and at least two
67
117
* bytes of data (one is reserved for written
68
118
* messages length).
69
119
* @param flags Option flags. See @ref SPSC_PBUF_FLAGS.
70
120
* @retval struct spsc_pbuf* Pointer to the created buffer. The pointer
71
121
* points to the same address as buf.
122
+ * @retval NULL Invalid buffer alignment.
72
123
*/
73
124
struct spsc_pbuf * spsc_pbuf_init (void * buf , size_t blen , uint32_t flags );
74
125
75
126
/**
76
127
* @brief Write specified amount of data to the packet buffer.
77
128
*
129
+ * It combines @ref spsc_pbuf_alloc and @ref spsc_pbuf_commit into a single call.
130
+ *
78
131
* @param pb A buffer to which to write.
79
132
* @param buf Pointer to the data to be written to the buffer.
80
- * @param len Number of bytes to be written to the buffer.
133
+ * @param len Number of bytes to be written to the buffer. Must be positive
134
+ * but less than @ref SPSC_PBUF_MAX_LEN.
81
135
* @retval int Number of bytes written, negative error code on fail.
82
136
* -EINVAL, if len == 0.
83
137
* -ENOMEM, if len is bigger than the buffer can fit.
84
138
*/
85
139
int spsc_pbuf_write (struct spsc_pbuf * pb , const char * buf , uint16_t len );
86
140
141
+ /**
142
+ * @brief Allocate space in the packet buffer.
143
+ *
144
+ * This function attempts to allocate @p len bytes of continuous memory within
145
+ * the packet buffer. An internal padding is added at the end of the buffer, if
146
+ * wrapping occurred during allocation. Apart from padding, allocation does not
147
+ * change the state of the buffer so if after allocation packet is not needed
148
+ * a commit is not needed.
149
+ *
150
+ * Allocated buffer must be committed (@ref spsc_pbuf_commit) to make the packet
151
+ * available for reading.
152
+ *
153
+ * Packet buffer ensures that allocated buffers are 32 bit word aligned.
154
+ *
155
+ * @note If data cache is used, it is the user responsibility to write back the
156
+ * new data.
157
+ *
158
+ * @param[in] pb A buffer to which to write.
159
+ * @param[in] len Allocation length. Must be positive. If less than @ref SPSC_PBUF_MAX_LEN
160
+ * then if requested length cannot be allocated, an attempt to allocate
161
+ * largest possible is performed (which may include adding wrap padding).
162
+ * If @ref SPSC_PBUF_MAX_LEN is used then an attempt to allocate largest
163
+ * buffer without applying wrap padding is performed.
164
+ * @param[out] buf Location where buffer address is written on successful allocation.
165
+ *
166
+ * @retval non-negative Amount of space that got allocated. Can be equal or smaller than %p len.
167
+ * @retval -EINVAL if @p len is forbidden.
168
+ */
169
+ int spsc_pbuf_alloc (struct spsc_pbuf * pb , uint16_t len , char * * buf );
170
+
171
+ /**
172
+ * @brief Commit packet to the buffer.
173
+ *
174
+ * Commit a packet which was previously allocated (@ref spsc_pbuf_alloc).
175
+ * If cache is used, cache writeback is perfromed on the written data.
176
+ *
177
+ * @param pb A buffer to which to write.
178
+ * @param len Packet length. Must be equal or less than the length used for allocation.
179
+ */
180
+ void spsc_pbuf_commit (struct spsc_pbuf * pb , uint16_t len );
181
+
87
182
/**
88
183
* @brief Read specified amount of data from the packet buffer.
89
184
*
90
185
* Single read allows to read the message send by the single write.
91
- * The provided buf must be big enough to store the whole message.
186
+ * The provided %p buf must be big enough to store the whole message.
92
187
*
93
- * @param pb A buffer from which data is to be read.
188
+ * It combines @ref spsc_pbuf_claim and @ref spsc_pbuf_free into a single call.
189
+ *
190
+ * @param pb A buffer from which data will be read.
94
191
* @param buf Data pointer to which read data will be written.
95
192
* If NULL, len of stored message is returned.
96
193
* @param len Number of bytes to be read from the buffer.
@@ -101,6 +198,30 @@ int spsc_pbuf_write(struct spsc_pbuf *pb, const char *buf, uint16_t len);
101
198
*/
102
199
int spsc_pbuf_read (struct spsc_pbuf * pb , char * buf , uint16_t len );
103
200
201
+ /**
202
+ * @brief Claim packet from the buffer.
203
+ *
204
+ * Claimed packet must be freed using @ref spsc_pbuf_free.
205
+ *
206
+ * @note If data cache is used, cache is invalidate on the packet.
207
+ *
208
+ * @param[in] pb A buffer from which packet will be claimed.
209
+ * @param[in,out] buf A location where claimed packet address is written.
210
+ *
211
+ * @retval 0 No packets in the buffer.
212
+ * @retval positive packet length.
213
+ */
214
+ uint16_t spsc_pbuf_claim (struct spsc_pbuf * pb , char * * buf );
215
+
216
+ /**
217
+ * @brief Free the packet to the buffer.
218
+ *
219
+ * Packet must be claimed (@ref spsc_pbuf_claim) before it can be freed.
220
+ *
221
+ * @param pb A packet buffer from which packet was claimed.
222
+ * @param len Claimed packet length.
223
+ */
224
+ void spsc_pbuf_free (struct spsc_pbuf * pb , uint16_t len );
104
225
105
226
/**
106
227
* @}
0 commit comments