Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
circular_buffer.c
Go to the documentation of this file.
1 /*
2  * General purpose circular buffer
3  *
4  * Copyright (C) 2021 Fabien-B <fabien-b@github.com>
5  *
6  * This file is part of paparazzi. See LICENCE file.
7  */
8 
9 #include "circular_buffer.h"
10 #include <string.h>
11 
12 
13 void circular_buffer_init(struct circular_buffer *cb, uint8_t *buffer, size_t len)
14 {
15  cb->_buf = buffer;
16  cb->_buf_len = len;
17  cb->read_offset = 0;
18  cb->write_offset = 0;
19 }
20 
21 
22 int circular_buffer_get(struct circular_buffer *cb, uint8_t *buf, size_t len)
23 {
24  // buffer empty
25  if (cb->read_offset == cb->write_offset) { return CIR_ERROR_NO_MSG; }
26  // LEN| MSG...| LEN | MSG...
27  uint8_t msg_len = cb->_buf[cb->read_offset];
28  // output buffer too small
29  if (len < msg_len) { return CIR_ERROR_BUFFER_TOO_SMALL; }
30 
31  size_t end_offset = cb->read_offset + msg_len + 1;
32  if (end_offset >= cb->_buf_len) {
33  end_offset -= cb->_buf_len;
34  }
35  uint8_t *start = cb->_buf + cb->read_offset + 1;
36 
37  if (end_offset > cb->read_offset + 1) {
38  memcpy(buf, start, msg_len);
39  } else {
40  size_t len1 = cb->_buf_len - (cb->read_offset + 1);
41  size_t len2 = len - len1;
42  memcpy(buf, start, len1);
43  memcpy(buf + len1, cb->_buf, len2);
44  }
45 
46  int nb_bytes = msg_len;
47  cb->read_offset = end_offset;
48  return nb_bytes;
49 }
50 
51 int circular_buffer_put(struct circular_buffer *cb, uint8_t *buf, size_t len)
52 {
53  int available = 0;
54  if (cb->read_offset > cb->write_offset) {
55  available = cb->read_offset - cb->write_offset - 1;
56  } else {
57  available = cb->_buf_len - (cb->write_offset - cb->read_offset) - 1;
58  }
59 
64  if ((int)len >= available) {
66  }
67 
68  size_t end_offset = cb->write_offset + len + 1;
69  if (end_offset >= cb->_buf_len) {
70  end_offset -= cb->_buf_len;
71  }
72 
73  cb->_buf[cb->write_offset] = len;
74  if (end_offset > cb->write_offset) {
75  memcpy(cb->_buf + cb->write_offset + 1, buf, len);
76  } else {
77  size_t len1 = cb->_buf_len - (cb->write_offset + 1);
78  size_t len2 = len - len1;
79  memcpy(cb->_buf + cb->write_offset + 1, buf, len1);
80  memcpy(cb->_buf, buf + len1, len2);
81  }
82 
83  cb->write_offset = end_offset;
84  return 0;
85 }
86 
void circular_buffer_init(struct circular_buffer *cb, uint8_t *buffer, size_t len)
initialize a circular buffer.
int circular_buffer_put(struct circular_buffer *cb, uint8_t *buf, size_t len)
Copy buf in the circular buffer.
int circular_buffer_get(struct circular_buffer *cb, uint8_t *buf, size_t len)
copy the next buffer available in cb to buf.
@ CIR_ERROR_NO_MSG
circular buffer is empty
@ CIR_ERROR_NO_SPACE_AVAILABLE
no space available in the circular buffer
@ CIR_ERROR_BUFFER_TOO_SMALL
destination buffer is too small
This is a general purpose circular buffer for storing buffers in a FIFO order.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98