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 
42 struct 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
73 extern "C" {
74 #endif
75 
89 LELY_CAN_BUF_INLINE void can_buf_init(
90  struct can_buf *buf, struct can_msg *ptr, size_t size);
91 
93 void can_buf_fini(struct can_buf *buf);
94 
96 LELY_CAN_BUF_INLINE void can_buf_clear(struct can_buf *buf);
97 
103 LELY_CAN_BUF_INLINE size_t can_buf_size(const struct can_buf *buf);
104 
110 LELY_CAN_BUF_INLINE size_t can_buf_capacity(const struct can_buf *buf);
111 
120 size_t can_buf_reserve(struct can_buf *buf, size_t n);
121 
133 LELY_CAN_BUF_INLINE size_t can_buf_peek(
134  struct can_buf *buf, struct can_msg *ptr, size_t n);
135 
147 LELY_CAN_BUF_INLINE size_t can_buf_read(
148  struct can_buf *buf, struct can_msg *ptr, size_t n);
149 
161 LELY_CAN_BUF_INLINE size_t can_buf_write(
162  struct can_buf *buf, const struct can_msg *ptr, size_t n);
163 
164 LELY_CAN_BUF_INLINE void
165 can_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 
177 LELY_CAN_BUF_INLINE void
178 can_buf_clear(struct can_buf *buf)
179 {
180  assert(buf);
181 
182  buf->end = buf->begin;
183 }
184 
185 LELY_CAN_BUF_INLINE size_t
186 can_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 
194 LELY_CAN_BUF_INLINE size_t
195 can_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 
203 LELY_CAN_BUF_INLINE size_t
204 can_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 
223 LELY_CAN_BUF_INLINE size_t
224 can_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 
245 LELY_CAN_BUF_INLINE size_t
246 can_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