## Кольцевой буфер

Особенности:
- можно добавлять элемент практически любого размера (в том числе и структуры). Размер элемента задается через item_size.
- можно забрать первый элемент, прочитать или удалить.
- не поддерживается потоковое чтение\запись элементов.
- функции не защищены от повторного вызова (например, в прерывании). Об этом должен позаботиться пользователь. Рекомендуется отключать прерывания, если в один буфер асинхронно добавляются или забираются элементы в 2 и более местах.
Также, если в буфер добавляют элементы в прерывании, а забирают в обычном режиме, то отключать прерывания перед добавлением\чтением не обязательно.


### Примеры:

1) Инициализация
```
typedef struct
{
    uint32_t data1;
    uint32_t data2;
} st_data_t

ringbuf_t*  fifo;
ringbuf_t*  fifo_st;

uint8_t buffer[128];
uint8_t buffer_st[256];

int main()
{
    // Размер элемента = 1 байт
    fifo->item_size = sizeof(uint8_t);
    rb_init(fifo, buffer, sizeof(buffer)/sizeof(uint8_t));
    rb_clear(fifo);

    // Размер элемента = sizeof(st_data_t)
    fifo_st->item_size = sizeof(st_data_t);
    rb_init(fifo_st, buffer_st, sizeof(buffer_st)/sizeof(st_data_t));
    rb_clear(fifo_st);
}

```

2) Добавление и чтение элементов
```

// Записать и забрать элемент из очереди
u8 wr_data = 10;
u8 rcv_data;

// ...
rb_add_item(fifo, &wr_data);
rb_get_item(fifo, &rcv_data);

// Записать, прочитать и удалить элемент
st_data_t wr_struct;
st_data_t rcv_struct;

// ...
rb_add_item(fifo_st, &wr_struct);
rb_read_item(fifo_st, &rcv_struct, 1);
rb_delete_item(fifo_st);

```

3) Получение информации о буфере
```
rb_size_t qty;
rb_size_t free;

// Количество записанных элементов (не байт)
qty = rb_get_items_qty(fifo);

// Количество свободных ячеек (не байт) для записи элементов 
free = rb_get_free_size(fifo);
```