mirror of
https://github.com/peter-tanner/satellite-testing-system.git
synced 2024-11-30 12:30:16 +08:00
172 lines
6.1 KiB
C
172 lines
6.1 KiB
C
#include <stddef.h>
|
||
#include <stdint.h>
|
||
#include "main.h"
|
||
|
||
/**
|
||
* @file
|
||
* Prototypes and structures for the ring buffer module.
|
||
*
|
||
* The MIT License (MIT)
|
||
*
|
||
* Copyright (c) 2014 Anders Kalør
|
||
*
|
||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
* of this software and associated documentation files (the "Software"), to deal
|
||
* in the Software without restriction, including without limitation the rights
|
||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
* copies of the Software, and to permit persons to whom the Software is
|
||
* furnished to do so, subject to the following conditions:
|
||
*
|
||
* The above copyright notice and this permission notice shall be included in all
|
||
* copies or substantial portions of the Software.
|
||
*
|
||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||
* SOFTWARE.
|
||
*/
|
||
|
||
#ifndef RINGBUFFER_H
|
||
#define RINGBUFFER_H
|
||
|
||
#ifdef __cplusplus
|
||
extern "C"
|
||
{
|
||
#endif
|
||
|
||
#define RING_BUFFER_ASSERT(x) \
|
||
if (!(x)) \
|
||
Error_Handler();
|
||
|
||
/**
|
||
* Checks if the buffer_size is a power of two.
|
||
* Due to the design only <tt> RING_BUFFER_SIZE-1 </tt> items
|
||
* can be contained in the buffer.
|
||
* buffer_size must be a power of two.
|
||
*/
|
||
#define RING_BUFFER_IS_POWER_OF_TWO(buffer_size) ((buffer_size & (buffer_size - 1)) == 0)
|
||
|
||
/**
|
||
* The type which is used to hold the size
|
||
* and the indicies of the buffer.
|
||
*/
|
||
typedef uint32_t ring_buffer_size_t;
|
||
|
||
/**
|
||
* Used as a modulo operator
|
||
* as <tt> a % b = (a & (b − 1)) </tt>
|
||
* where \c a is a positive index in the buffer and
|
||
* \c b is the (power of two) size of the buffer.
|
||
*/
|
||
#define RING_BUFFER_MASK(rb) (rb->buffer_mask)
|
||
|
||
/**
|
||
* Simplifies the use of <tt>struct ring_buffer_t</tt>.
|
||
*/
|
||
typedef struct ring_buffer_t ring_buffer_t;
|
||
|
||
/**
|
||
* Structure which holds a ring buffer.
|
||
* The buffer contains a buffer array
|
||
* as well as metadata for the ring buffer.
|
||
*/
|
||
struct ring_buffer_t
|
||
{
|
||
/** Buffer memory. */
|
||
uint8_t *buffer;
|
||
/** Buffer mask. */
|
||
ring_buffer_size_t buffer_mask;
|
||
/** Index of tail. */
|
||
ring_buffer_size_t tail_index;
|
||
/** Index of head. */
|
||
ring_buffer_size_t head_index;
|
||
};
|
||
|
||
/**
|
||
* Initializes the ring buffer pointed to by <em>buffer</em>.
|
||
* This function can also be used to empty/reset the buffer.
|
||
* The resulting buffer can contain <em>buf_size-1</em> bytes.
|
||
* @param buffer The ring buffer to initialize.
|
||
* @param buf The buffer allocated for the ringbuffer.
|
||
* @param buf_size The size of the allocated ringbuffer.
|
||
*/
|
||
void ring_buffer_init(ring_buffer_t *buffer, uint8_t *buf, size_t buf_size);
|
||
|
||
/**
|
||
* Adds a byte to a ring buffer.
|
||
* @param buffer The buffer in which the data should be placed.
|
||
* @param data The byte to place.
|
||
*/
|
||
void ring_buffer_queue(ring_buffer_t *buffer, uint8_t data);
|
||
|
||
/**
|
||
* Adds an array of bytes to a ring buffer.
|
||
* @param buffer The buffer in which the data should be placed.
|
||
* @param data A pointer to the array of bytes to place in the queue.
|
||
* @param size The size of the array.
|
||
*/
|
||
void ring_buffer_queue_arr(ring_buffer_t *buffer, const uint8_t *data, ring_buffer_size_t size);
|
||
|
||
/**
|
||
* Returns the oldest byte in a ring buffer.
|
||
* @param buffer The buffer from which the data should be returned.
|
||
* @param data A pointer to the location at which the data should be placed.
|
||
* @return 1 if data was returned; 0 otherwise.
|
||
*/
|
||
uint8_t ring_buffer_dequeue(ring_buffer_t *buffer, uint8_t *data);
|
||
|
||
/**
|
||
* Returns the <em>len</em> oldest bytes in a ring buffer.
|
||
* @param buffer The buffer from which the data should be returned.
|
||
* @param data A pointer to the array at which the data should be placed.
|
||
* @param len The maximum number of bytes to return.
|
||
* @return The number of bytes returned.
|
||
*/
|
||
ring_buffer_size_t ring_buffer_dequeue_arr(ring_buffer_t *buffer, uint8_t *data, ring_buffer_size_t len);
|
||
/**
|
||
* Peeks a ring buffer, i.e. returns an element without removing it.
|
||
* @param buffer The buffer from which the data should be returned.
|
||
* @param data A pointer to the location at which the data should be placed.
|
||
* @param index The index to peek.
|
||
* @return 1 if data was returned; 0 otherwise.
|
||
*/
|
||
uint8_t ring_buffer_peek(ring_buffer_t *buffer, uint8_t *data, ring_buffer_size_t index);
|
||
|
||
/**
|
||
* Returns whether a ring buffer is empty.
|
||
* @param buffer The buffer for which it should be returned whether it is empty.
|
||
* @return 1 if empty; 0 otherwise.
|
||
*/
|
||
inline uint8_t ring_buffer_is_empty(ring_buffer_t *buffer)
|
||
{
|
||
return (buffer->head_index == buffer->tail_index);
|
||
}
|
||
|
||
/**
|
||
* Returns whether a ring buffer is full.
|
||
* @param buffer The buffer for which it should be returned whether it is full.
|
||
* @return 1 if full; 0 otherwise.
|
||
*/
|
||
inline uint8_t ring_buffer_is_full(ring_buffer_t *buffer)
|
||
{
|
||
return ((buffer->head_index - buffer->tail_index) & RING_BUFFER_MASK(buffer)) == RING_BUFFER_MASK(buffer);
|
||
}
|
||
|
||
/**
|
||
* Returns the number of items in a ring buffer.
|
||
* @param buffer The buffer for which the number of items should be returned.
|
||
* @return The number of items in the ring buffer.
|
||
*/
|
||
inline ring_buffer_size_t ring_buffer_num_items(ring_buffer_t *buffer)
|
||
{
|
||
return ((buffer->head_index - buffer->tail_index) & RING_BUFFER_MASK(buffer));
|
||
}
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#endif /* RINGBUFFER_H */ |