http://tath.eu/code/ring-buffer-in-c/ Ring buffer is very common and useful data structure, excellent for storing asynchronous data from multiple sources in embedded devices. ringbuffer.h // Simple prove-of-concept ring buffer // Author: Adam Orcholski, www.tath.eu #pragma once // types typedef struct ring_buffer_s { unsigned char * data; // pointer to external buffer int size; // size of external buffer int head; // index of free space in external buffer int tail; // index of last item to be read int count; // hold number of items stored but not read } ring_buffer_t; // interface void RING_Init(ring_buffer_t * const buff_state, unsigned char * in_buffer, int buffer_size_in_bytes); void RING_Reset(ring_buffer_t * const buff_state); // note: does not clear external buffer int RING_IsEmpty(ring_buffer_t * const buff_state); // return non-zero if buffer is empty int RING_IsFull(ring_buffer_t * const buff_state); // return non-zero if buffer is full int RING_AddItem(ring_buffer_t * const buff_state, unsigned char new_item); // return non-zero if buffer is full int RING_GetItem(ring_buffer_t * const buff_state, unsigned char * const out_item); // return non-zero if buffer is empty ringbuffer.c // Simple prove-of-concept ring buffer // Author: Adam Orcholski, www.tath.eu #include #include // function definitions void RING_Init(ring_buffer_t * const buff_state, unsigned char * in_buffer, int buffer_size_in_bytes) { assert(0 != buff_state); assert(0 != in_buffer); assert(buffer_size_in_bytes > 0); buff_state->data = in_buffer; buff_state->size = buffer_size_in_bytes; buff_state->head = 0; buff_state->tail = 0; buff_state->count = 0; } void RING_Reset(ring_buffer_t * const buff_state) { assert(0 != buff_state); buff_state->head = 0; buff_state->tail = 0; buff_state->count = 0; } // return non-zero value if buffer is empty int RING_IsEmpty(ring_buffer_t * const buff_state) { int fBufferIsEmpty = 0; assert(0 != buff_state); if (0 == buff_state->count) { fBufferIsEmpty = 1; } return fBufferIsEmpty; } // return non-zero value if buffer is full int RING_IsFull(ring_buffer_t * const buff_state) { int fBufferIsFull = 0; assert(0 != buff_state); if (buff_state->count >= buff_state->size) { fBufferIsFull = 1; } return fBufferIsFull; } // return non-zero value if buffer is full int RING_AddItem(ring_buffer_t * const buff_state, unsigned char new_item) { int fBufferIsFull = 0; assert(0 != buff_state); fBufferIsFull = RING_IsFull(buff_state); if (!fBufferIsFull) { buff_state->data[buff_state->head] = new_item; buff_state->head++; buff_state->count++; if (buff_state->head >= buff_state->size) { buff_state->head = 0; } } return fBufferIsFull; } // return non-zero value if buffer is empty int RING_GetItem(ring_buffer_t * const buff_state, unsigned char * const out_item) { int fBufferIsEmpty = 0; assert(0 != buff_state); assert(0 != out_item); fBufferIsEmpty = RING_IsEmpty(buff_state); if (!fBufferIsEmpty) { *out_item = buff_state->data[buff_state->tail]; buff_state->tail++; buff_state->count--; if (buff_state->tail >= buff_state->size) { buff_state->tail = 0; } } return fBufferIsEmpty; } and example/test compiled in Microsoft Visual Studio: main.c // Simple prove-of-concept ring buffer example // Author: Adam Orcholski, www.tath.eu #include #include #define BUFF_SIZE 4 unsigned char bufffeeer[BUFF_SIZE]; ring_buffer_t buff; int main() { RING_Init(&buff, bufffeeer, sizeof(bufffeeer)); char c = 0; while (c != 'q') { static char write_char = 'a'; c = getchar(); int ret = 0; if (c == 'w') { ret = RING_AddItem(&buff, write_char); if (ret) { printf("buffer full\r\n"); } else { printf("written char = %c\r\n", write_char); } write_char++; if (write_char == 'z') { write_char = 'a'; } } else if (c == 's') { char out; ret = RING_GetItem(&buff, &out); if (ret) { printf("buffer empty\r\n"); } else { printf("read char = %c\r\n", out); } } } return 0; } Run example, and press W key to add item to buffer and S key to read last item. Press Q to quit.