N
c.rackwitz schrieb:
hab ich selber mal an einem ringpuffer versucht. das kam raus: http://cracki.incast-security.de/pub/projects/beispiele/060131 C ringpuffer/ringbuf.c
ich nehm immer das hier:
#ifndef QUE_INCLUDED
#define QUE_INCLUDED
#include "standard_types.h"
#include "features.h"
////////////////////////////////////////// QUEUE /////////////////////////////////////////
/* Synchronization options */
typedef enum
{
QS_NOSYNC, /* Not synchronized */
QS_SYNC /* Synchronized */
} QUE_SYNC;
/*
Code to be executed when synchronization is enabled
Hardware/platform specific !!!
*/
#define QUE_SYNC_ENTRY __asm sei
#define QUE_SYNC_EXIT __asm cli
/* Layout of a QUE */
typedef struct
{
volatile UINT16 readidx; /* Read index */
volatile UINT16 writeidx; /* Write index */
volatile UINT16 count; /* Number of bytes actually queued */
UINT16 size; /* Buffersize */
QUE_SYNC sync; /* interrupt sync? */
UINT8 PTR buffer; /* Data field */
} QUE_T;
/* Prototypes */
extern UINT16 QUE_Write (QUE_T PTR f, UINT8 PTR data, UINT16 size);
extern UINT16 QUE_Read (QUE_T PTR f, UINT8 PTR data, UINT16 size);
extern void QUE_Initialize (QUE_T PTR q, UINT8 PTR mem, UINT16 size, QUE_SYNC sync);
extern UINT16 QUE_Peek (QUE_T PTR f, UINT8 PTR data, UINT16 size);
extern UINT16 QUE_Delete (QUE_T PTR f, UINT16 size);
/* Informational macros */
#define QUE_GetCount(__q__) ((__q__)->count)
#define QUE_GetFree(__q__) ((__q__)->size-(__q__)->count)
/* Macros that are too small to be a function */
#define QUE_Purge(__q__) {(__q__)->count=0;(__q__)->readidx=0;(__q__)->writeidx=0;}
#endif // QUE_INCLUDED
#include "que.h"
//////////////////////////////// QUEUE ///////////////////////////////////////////
/*
Enqueues some bytes
-----------------
IN: f - The queue object
data - Where the bytes are
size - Number of bytes which should be queued
OUT: Number of bytes actually enqueued
INFO: The number of queued bytes may be smaller as requested
*/
UINT16 QUE_Write (QUE_T PTR f, UINT8 PTR data, UINT16 size)
{
UINT16 s; /* Iterator */
/* Queue full? */
if (f->count == f->size)
return 0;
/* Do for all the bytes */
for (s=0; s<size; s++)
{
/* Store that content */
f->buffer[f->writeidx] = data[s];
f->count++;
f->writeidx++;
/* Wrap around */
if (f->writeidx == f->size)
f->writeidx = 0;
/* The queue is full now */
if (f->count == f->size)
{
s++;
break;
}
}
/* Return number of bytes stored */
return s;
}
/*
Dequeues some bytes
-------------------
IN: f - The queue object
data - Where the bytes should be written
size - Number of bytes to transfer
OUT: Number of bytes actually dequeued
INFO: The number of transferred bytes may be smaller than requested
*/
UINT16 QUE_Read (QUE_T PTR f, UINT8 PTR data, UINT16 size)
{
UINT16 s;
/* The queue is empty */
if (f->count == 0)
return 0;
/* Possibly disable calling the write function */
if (f->sync == QS_SYNC)
QUE_SYNC_ENTRY;
/* Try to dequeue all that stuff */
for (s=0; s<size; s++)
{
/* Transfer */
data[s] = f->buffer[f->readidx];
f->count--;
f->readidx++;
/* Wrap around */
if (f->readidx == f->size)
f->readidx = 0;
/* The queue is empty now */
if (f->count == 0)
{
s++;
break;
}
}
/* Re-Enable calls to the write function */
if (f->sync == QS_SYNC)
QUE_SYNC_EXIT;
/* Return number of bytes transferred */
return s;
}
UINT16 QUE_Peek (QUE_T PTR f, UINT8 PTR data, UINT16 size)
{
UINT16 s;
UINT16 count;
UINT16 readidx;
/* The queue is empty */
if (f->count == 0)
return 0;
count = f->count;
readidx = f->readidx;
/* Try to dequeue all that stuff */
for (s=0; s<size; s++)
{
/* Transfer */
data[s] = f->buffer[readidx];
count--;
readidx++;
/* Wrap around */
if (readidx == f->size)
readidx = 0;
/* The queue is empty now */
if (count == 0)
{
s++;
break;
}
}
/* Return number of bytes transferred */
return s;
}
UINT16 QUE_Delete (QUE_T PTR f, UINT16 size)
{
UINT16 s;
/* The queue is empty */
if (f->count == 0)
return 0;
for (s=0; s<size; s++)
{
f->count--;
f->readidx++;
/* Wrap around */
if (f->readidx == f->size)
f->readidx = 0;
/* The queue is empty now */
if (f->count == 0)
{
s++;
break;
}
}
/* Return number of bytes transferred */
return s;
}
/*
Allocates a queue object
------------------------
IN: q - The que object
mem - A pointer to memory for that queue
size - Size of memory (mem, see above)
sync - QS_SYNC == Disable interrupts on reads
*/
void QUE_Initialize (QUE_T PTR q, UINT8 PTR mem, UINT16 size, QUE_SYNC sync)
{
q->sync = sync;
q->size = size;
q->buffer = mem;
QUE_Purge (q);
}