реклама на сайте
подробности

 
 
> Проблема с Ring Buffer.
Jenya7
сообщение Aug 31 2016, 08:46
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Я сделал такую реализацию.
CODE
typedef enum CycBuffState {cbsOk = 0, cbsOverwrite = 1, cbsBuffFull = 2, cbsBuffEmpty = 3, cbsError = 4} enCycBuffState;

typedef struct
{
uint32_t MaxBufSize,
HeadIdx,
TailIdx;
enCycBuffState State;
uint8_t *Buffer;
} stRingBuffer;

void RingBuf_Init (stRingBuffer *ring_buf, uint8_t *buf, uint32_t max_size)
{
ring_buf->Buffer = buf;
ring_buf->MaxBufSize = max_size;
ring_buf->HeadIdx = ring_buf->TailIdx = 0;
ring_buf->State = cbsBuffEmpty;
}

enCycBuffState RingBuf_PushByte(stRingBuffer *ring_buf, uint8_t val, uint8_t allow_overwrite)
{
if ((ring_buf->HeadIdx+1) == ring_buf->TailIdx)
{
if (!allow_overwrite)
return cbsBuffFull;
}

ring_buf->Buffer[ring_buf->HeadIdx] = val;
ring_buf->HeadIdx++;

if (ring_buf->HeadIdx >= ring_buf->MaxBufSize)
ring_buf->HeadIdx = 0;

return cbsOk;
}

enCycBuffState RingBuf_PushBytes(stRingBuffer *ring_buf, uint8_t len, uint8_t *buf, uint8_t allow_overwrite)
{
uint32_t free_space;

if (ring_buf->HeadIdx == ring_buf->TailIdx)
{
free_space = ring_buf->MaxBufSize;
}
else
{
if (ring_buf->HeadIdx >= ring_buf->TailIdx)
free_space = ring_buf->HeadIdx - ring_buf->TailIdx;
else
free_space = (ring_buf->MaxBufSize - ring_buf->TailIdx) + ring_buf->HeadIdx;

if (free_space < len)
return cbsBuffFull;
}
while (len)
{
RingBuf_PushByte(ring_buf, *buf, allow_overwrite);
buf++;
len--;
}

return cbsOk;
}

enCycBuffState RingBuf_PopByte(stRingBuffer *ring_buf, uint8_t *val)
{
if (ring_buf->HeadIdx == ring_buf->TailIdx)
return cbsError;

*val = ring_buf->Buffer[ring_buf->TailIdx];
ring_buf->Buffer[ring_buf->TailIdx] = 0;
ring_buf->TailIdx++;

if (ring_buf->TailIdx >= ring_buf->MaxBufSize)
ring_buf->TailIdx = 0;

return cbsOk;
}

enCycBuffState RingBuf_PopBytes(stRingBuffer *ring_buf, uint8_t len, uint8_t *val)
{
while (len)
{
RingBuf_PopByte(ring_buf, val);
val++;
len--;
}

return cbsOk;
}


И потом проверяю (в IAR, в симуляторе)
Код
#include <string.h>
#include "ringbuf.h"

stRingBuffer ring_buf;

uint8_t *temp_buff;
uint8_t *test_buff = "Hello World";
uint8_t *read_buff;

int main()
{
  RingBuf_Init (&ring_buf, temp_buff, 32);
  while (1)
  {
     RingBuf_PushBytes(&ring_buf, strlen(test_buff), test_buff, 0);
    
     RingBuf_PopBytes(&ring_buf, strlen(test_buff), read_buff);
  }
}

Но несмотря на то что я отслеживаю наличие свободного места.
Код
uint32_t free_space;
  
  if (ring_buf->HeadIdx == ring_buf->TailIdx)
  {
    free_space = ring_buf->MaxBufSize;
  }
  else
  {
    if (ring_buf->HeadIdx >= ring_buf->TailIdx)
       free_space = ring_buf->HeadIdx - ring_buf->TailIdx;
     else
       free_space = (ring_buf->MaxBufSize - ring_buf->TailIdx) + ring_buf->HeadIdx;
  
    if (free_space < len)
      return cbsBuffFull;

В отладчике я вижу перезапись буфера. Что я упустил?

Сообщение отредактировал Jenya7 - Aug 31 2016, 08:51
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
DASM
сообщение Aug 31 2016, 14:53
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Чет мудреные какие-то реализации. Так не проще?
CODE
template <class T>
class RingBuf
{
public:
RingBuf (unsigned int size) : buf(new T[size]), head(0), sz_contains(0), SZ_MAX(size){};
~RingBuf() {
delete [] buf;
}
bool Pop (T &val)
{
if (sz_contains == 0)
return false;
else
{
val = buf[head++]; head %= SZ_MAX; sz_contains--;
return true;
}
}
bool Push (T val)
{
if (!GetFree())
return false;
else
{
buf[(head + sz_contains++) % SZ_MAX] = val;
return true;
}
}
bool Push (T val[] , unsigned int count)
{
if (count > GetFree())
return false;
for (unsigned int i = 0; i < count; i++)
Push(val[i]);
return true;
}
void Clear() {sz_contains = 0;}
unsigned int GetFree () {return SZ_MAX - sz_contains;}

private:
unsigned int sz_contains;
const unsigned int SZ_MAX;
T *buf;
unsigned int head;
};
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Aug 31 2016, 15:05
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(DASM @ Aug 31 2016, 20:53) *
Чет мудреные какие-то реализации. Так не проще?

Нет проверки влезет ли записываемый кусок в свободное место.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Jenya7   Проблема с Ring Buffer.   Aug 31 2016, 08:46
- - smalcom   Много чего, там и переполнение и... проще показать...   Aug 31 2016, 09:17
|- - Jenya7   Цитата(smalcom @ Aug 31 2016, 15:17) Мног...   Aug 31 2016, 10:23
|- - smalcom   Цитата(Jenya7 @ Aug 31 2016, 13:23) Но вы...   Aug 31 2016, 14:14
|- - Jenya7   Цитата(smalcom @ Aug 31 2016, 20:14) заме...   Aug 31 2016, 14:28
- - XVR   Кодuint8_t *temp_buff; uint8_t *read_buff;Ну и куд...   Aug 31 2016, 12:41
|- - Jenya7   Цитата(XVR @ Aug 31 2016, 18:41) Кодuint8...   Aug 31 2016, 14:13
|- - DASM   Цитата(Jenya7 @ Aug 31 2016, 18:05) Нет п...   Aug 31 2016, 15:09
- - smalcom   Кодbuf[(head + sz_contains++) % SZ_MAX...   Aug 31 2016, 18:03
|- - DASM   Цитата(smalcom @ Aug 31 2016, 21:03) Кодb...   Aug 31 2016, 18:12
- - smalcom   ЦитатаПосле 2^32 push? я так на волне паранойи и п...   Aug 31 2016, 19:24
- - brag   Хм. Зачем все так сложно мудрить, если есть уже да...   Sep 7 2016, 08:48
|- - Jenya7   Цитата(brag @ Sep 7 2016, 13:48) Хм. Заче...   Sep 11 2016, 17:58
- - smalcom   самое первое (а там и дальше так) Цитатаuint32_t w...   Sep 7 2016, 17:47
|- - brag   Цитата(smalcom @ Sep 7 2016, 20:47) это н...   Sep 7 2016, 17:51
- - smalcom   о, пардон. странно как-то - следующей строки с пр...   Sep 8 2016, 01:43
|- - brag   Цитата(smalcom @ Sep 8 2016, 04:43) о, па...   Sep 8 2016, 07:48
- - brag   Цитата(Jenya7 @ Sep 11 2016, 20:58) мне б...   Sep 11 2016, 22:06


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 15:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.01398 секунд с 7
ELECTRONIX ©2004-2016