/** * @file * Prototypes and structures for the ring buffer module. */ #ifndef __RINGBUFFER_H__ #define __RINGBUFFER_H__ #include #include #include /** * The size of a ring buffer. * Due to the design only RING_BUFFER_SIZE-1 items * can be contained in the buffer. * The buffer size must be a power of two. */ // #define RING_BUFFER_SIZE 256U//512 // // #if (RING_BUFFER_SIZE & (RING_BUFFER_SIZE - 1)) != 0 // #error "RING_BUFFER_SIZE must be a power of two" // #endif /** * The type which is used to hold the size * and the indicies of the buffer. * Must be able to fit \c RING_BUFFER_SIZE . */ typedef uint32_t ring_buffer_size_t; /** * Used as a modulo operator * as a % b = (a & (b − 1)) * 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 (RING_BUFFER_SIZE-1) /** * Structure which holds a ring buffer. * The buffer contains a buffer array * as well as metadata for the ring buffer. */ typedef struct ring_buffer { /** Buffer memory. */ uint8_t *buffer; /** Buffer size. */ ring_buffer_size_t size; /** Index of tail. */ ring_buffer_size_t tail_index; /** Index of head. */ ring_buffer_size_t head_index; /** Rx Locker. */ bool rx_lock; } ring_buffer_t; // typedef struct ring_buffer { // /** Buffer memory. */ //// uint8_t *buffer; // unsigned char buffer[RING_BUFFER_SIZE]; // /** Index of tail. */ // ring_buffer_size_t tail_index; // /** Index of head. */ // ring_buffer_size_t head_index; // /** Rx Locker. */ // bool rx_lock; //}ring_buffer_t; // typedef struct ring_buffer { // /** Buffer memory. */ //// uint8_t *buffer; // unsigned char buffer[RING_BUFFER_SIZE]; // /** Index of tail. */ // ring_buffer_size_t tail_index; // /** Index of head. */ // ring_buffer_size_t head_index; // /** Rx Locker. */ // bool rx_lock; //}ring_buffer_t; /** * Initializes the ring buffer pointed to by buffer. * This function can also be used to empty/reset the buffer. * @param buffer The ring buffer to initialize. */ // void ring_buffer_init(ring_buffer_t *buffer); void ring_buffer_create(ring_buffer_t *rb, uint8_t *buffer, uint32_t 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 *rb, 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 *rb, 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. */ ring_buffer_size_t ring_buffer_dequeue(ring_buffer_t *rb, uint8_t *data); /** * Returns the len 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 *rb, 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. */ ring_buffer_size_t ring_buffer_peek(ring_buffer_t *rb, 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 ring_buffer_size_t ring_buffer_is_empty(ring_buffer_t *rb) { return (rb->head_index == rb->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 ring_buffer_size_t ring_buffer_is_full(ring_buffer_t *rb) { return ((rb->head_index - rb->tail_index) & (rb->size - 1)) == (rb->size - 1); } /** * 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 *rb) { return ((rb->head_index - rb->tail_index) & (rb->size - 1)); } #endif /* __RINGBUFFER_H__ */