Lely core libraries 2.3.4
buf.h
Go to the documentation of this file.
1
28#ifndef LELY_CAN_BUF_H_
29#define LELY_CAN_BUF_H_
30
31#include <lely/can/msg.h>
32#include <lely/util/util.h>
33
34#include <assert.h>
35#include <stddef.h>
36
37#ifndef LELY_CAN_BUF_INLINE
38#define LELY_CAN_BUF_INLINE static inline
39#endif
40
42struct can_buf {
44 struct can_msg *ptr;
51 size_t size;
57 size_t begin;
63 size_t end;
64};
65
67#define CAN_BUF_INIT \
68 { \
69 NULL, 0, 0, 0 \
70 }
71
72#ifdef __cplusplus
73extern "C" {
74#endif
75
89LELY_CAN_BUF_INLINE void can_buf_init(
90 struct can_buf *buf, struct can_msg *ptr, size_t size);
91
93void can_buf_fini(struct can_buf *buf);
94
96LELY_CAN_BUF_INLINE void can_buf_clear(struct can_buf *buf);
97
103LELY_CAN_BUF_INLINE size_t can_buf_size(const struct can_buf *buf);
104
110LELY_CAN_BUF_INLINE size_t can_buf_capacity(const struct can_buf *buf);
111
120size_t can_buf_reserve(struct can_buf *buf, size_t n);
121
133LELY_CAN_BUF_INLINE size_t can_buf_peek(
134 struct can_buf *buf, struct can_msg *ptr, size_t n);
135
147LELY_CAN_BUF_INLINE size_t can_buf_read(
148 struct can_buf *buf, struct can_msg *ptr, size_t n);
149
161LELY_CAN_BUF_INLINE size_t can_buf_write(
162 struct can_buf *buf, const struct can_msg *ptr, size_t n);
163
164LELY_CAN_BUF_INLINE void
165can_buf_init(struct can_buf *buf, struct can_msg *ptr, size_t size)
166{
167 assert(buf);
168 assert(ptr || !size);
169 assert(!size || powerof2(size));
170
171 buf->ptr = ptr;
172 buf->size = size ? size - 1 : 0;
173 buf->begin = 0;
174 buf->end = 0;
175}
176
177LELY_CAN_BUF_INLINE void
179{
180 assert(buf);
181
182 buf->end = buf->begin;
183}
184
185LELY_CAN_BUF_INLINE size_t
186can_buf_size(const struct can_buf *buf)
187{
188 assert(buf);
189 assert(powerof2(buf->size + 1));
190
191 return (buf->end - buf->begin) & buf->size;
192}
193
194LELY_CAN_BUF_INLINE size_t
195can_buf_capacity(const struct can_buf *buf)
196{
197 assert(buf);
198 assert(powerof2(buf->size + 1));
199
200 return (buf->begin - buf->end - 1) & buf->size;
201}
202
203LELY_CAN_BUF_INLINE size_t
204can_buf_peek(struct can_buf *buf, struct can_msg *ptr, size_t n)
205{
206 assert(buf);
207 assert(powerof2(buf->size + 1));
208
209 size_t begin = buf->begin;
210 for (size_t i = 0; i < n; i++) {
211 size_t end = buf->end;
212 if (!((end - begin) & buf->size))
213 return i;
214
215 if (ptr)
216 ptr[i] = buf->ptr[begin & buf->size];
217 begin++;
218 }
219
220 return n;
221}
222
223LELY_CAN_BUF_INLINE size_t
224can_buf_read(struct can_buf *buf, struct can_msg *ptr, size_t n)
225{
226 assert(buf);
227 assert(powerof2(buf->size + 1));
228
229 size_t begin = buf->begin;
230 for (size_t i = 0; i < n; i++) {
231 size_t end = buf->end;
232 if (!((end - begin) & buf->size))
233 return i;
234
235 if (ptr)
236 ptr[i] = buf->ptr[begin & buf->size];
237 begin++;
238
239 buf->begin = begin;
240 }
241
242 return n;
243}
244
245LELY_CAN_BUF_INLINE size_t
246can_buf_write(struct can_buf *buf, const struct can_msg *ptr, size_t n)
247{
248 assert(buf);
249 assert(powerof2(buf->size + 1));
250
251 size_t end = buf->end;
252 for (size_t i = 0; i < n; i++) {
253 size_t begin = buf->begin;
254 if (!((begin - end - 1) & buf->size))
255 return i;
256
257 buf->ptr[end++ & buf->size] = ptr[i];
258
259 buf->end = end;
260 }
261
262 return n;
263}
264
265#ifdef __cplusplus
266}
267#endif
268
269#endif // !LELY_CAN_BUF_H_
LELY_CAN_BUF_INLINE void can_buf_init(struct can_buf *buf, struct can_msg *ptr, size_t size)
Initializes a CAN frame buffer.
Definition buf.h:165
LELY_CAN_BUF_INLINE size_t can_buf_peek(struct can_buf *buf, struct can_msg *ptr, size_t n)
Reads, but does not remove, frames from a CAN frame buffer.
Definition buf.h:204
LELY_CAN_BUF_INLINE size_t can_buf_write(struct can_buf *buf, const struct can_msg *ptr, size_t n)
Writes frames to a CAN frame buffer.
Definition buf.h:246
LELY_CAN_BUF_INLINE size_t can_buf_capacity(const struct can_buf *buf)
Returns the number of frames available for writing in a CAN buffer.
Definition buf.h:195
size_t can_buf_reserve(struct can_buf *buf, size_t n)
Resizes a CAN frame buffer, if necessary, to make room for at least n additional frames.
Definition buf.c:53
LELY_CAN_BUF_INLINE size_t can_buf_size(const struct can_buf *buf)
Returns the number of frames available for reading in a CAN buffer.
Definition buf.h:186
LELY_CAN_BUF_INLINE size_t can_buf_read(struct can_buf *buf, struct can_msg *ptr, size_t n)
Reads, and removes, frames from a CAN frame buffer.
Definition buf.h:224
LELY_CAN_BUF_INLINE void can_buf_clear(struct can_buf *buf)
Clears a CAN frame buffer.
Definition buf.h:178
void can_buf_fini(struct can_buf *buf)
Finalizes a CAN frame buffer.
Definition buf.c:41
This header file is part of the CAN library; it contains the CAN frame declarations.
This is the public header file of the utilities library.
#define powerof2(x)
Returns 1 if x is a power of two, and 0 otherwise.
Definition util.h:78
This header file is part of the C11 and POSIX compatibility library; it includes <stddef....
A CAN frame buffer.
Definition buf.h:42
struct can_msg * ptr
A pointer to the allocated memory for the buffer.
Definition buf.h:44
size_t end
The offset (with respect to ptr) of one past the last value available for reading (and the first avai...
Definition buf.h:63
size_t begin
The offset (with respect to ptr) of the first value available for reading (and two past the last avai...
Definition buf.h:57
size_t size
The total size (in number of frames) of the buffer, excluding the unused frame used to distinguish be...
Definition buf.h:51
A CAN or CAN FD format frame.
Definition msg.h:87