Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
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
13void 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
22int 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...
28 // output buffer too small
29 if (len < *msg_len_p) { return CIR_ERROR_BUFFER_TOO_SMALL; }
30
31 size_t end_offset = cb->read_offset + *msg_len_p + 2;
32 if (end_offset >= cb->_buf_len) {
33 end_offset -= cb->_buf_len;
34 }
35 uint8_t *start = cb->_buf + cb->read_offset + 2;
36
37 if (end_offset >= cb->read_offset + 2) {
38 memcpy(buf, start, *msg_len_p);
39 } else {
40 size_t len1 = cb->_buf_len - (cb->read_offset + 2);
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_p;
48 return nb_bytes;
49}
50
51int circular_buffer_put(struct circular_buffer *cb, const 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 - 2;
56 } else {
57 available = cb->_buf_len - (cb->write_offset - cb->read_offset) - 2;
58 }
59
64 if ((int)len >= available) {
66 }
67
68 size_t end_offset = cb->write_offset + len + 2;
69 if (end_offset >= cb->_buf_len) {
70 end_offset -= cb->_buf_len;
71 }
72
73
75 *len_p = len;
76 if (end_offset > cb->write_offset) {
77 memcpy(cb->_buf + cb->write_offset + 2, buf, len);
78 } else {
79 size_t len1 = cb->_buf_len - (cb->write_offset + 2);
80 size_t len2 = len - len1;
81 memcpy(cb->_buf + cb->write_offset + 2, buf, len1);
82 memcpy(cb->_buf, buf + len1, len2);
83 }
84
86 return 0;
87}
88
90 // buffer empty
91 if (cb->read_offset == cb->write_offset) { return CIR_ERROR_NO_MSG; }
92
94 size_t end_offset = cb->read_offset;
95
96 while(end_offset != cb->write_offset) {
100 if (end_offset >= cb->_buf_len) {
101 end_offset -= cb->_buf_len;
102 }
103 }
104
106 return 0;
107}
int circular_buffer_put(struct circular_buffer *cb, const uint8_t *buf, size_t len)
Copy buf in the circular buffer.
void circular_buffer_init(struct circular_buffer *cb, uint8_t *buffer, size_t len)
initialize a 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.
int circular_buffer_drop(struct circular_buffer *cb)
Drop last inserted record.
@ 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 variable lenght buffers in a FIFO order.
uint16_t foo
Definition main_demo5.c:58
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.