ring buffer
Diff: rbuf.c
- Revision:
- 0:eae8cffdd121
- Child:
- 2:d1095a112328
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rbuf.c Thu Jun 23 19:44:23 2011 +0000 @@ -0,0 +1,314 @@ +#ifndef __charbuf_c_ + #define __charbuf_c_ + +#include "mbed.h" + +#include "globals.h" // Wegen g_display_error +#include "rbuf.h" +#include "eprintf.h" + +// int debug_create_charbuffer = 0; +int display_receive_io = 0; +int display_send_io = 0; +//int debug_add_pointer_Klartext = 0; +int debug_display_charbuffer_header = 0; + +void init_header (buffer_header_t *h, void *buf, uint16_t objektanzahl, uint16_t Schwelle, uint16_t objektgroesse) + { + if (g_display_Funktion) {eprintf ("In init_header: \r\n"); } + h->buflen = objektanzahl; + h->bufcnt = 0; + h->in = buf; + h->out = buf; + h->buf = buf; + h->anzahl = 0; + h->fehleranzahl = 0; + h->Schwelle = Schwelle; + h->flags = 0; + h->peak_max = 0; + h->blockgroesse = objektgroesse; + } + +buffer_header_t *charbuffer_init (uint16_t b_size, uint16_t b_schwelle, uint16_t blockgroesse) + { + void *buffer_p; + buffer_header_t *kopf_p; + + if (g_display_Funktion) {eprintf ("In create_charbuffer: \r\n"); } + + // Zuerst mal Speicher fuer die Verwaltungsstruktur holen + kopf_p = (buffer_header_t *) calloc (1, (sizeof(buffer_header_t))); + if (kopf_p > 0x00) + { + memset (kopf_p, 0x00, (sizeof(buffer_header_t))); + } + else + { + // Fehler! + eprintf ("Error: Kein Speicher mehr bei create_charbuffer-Verwaltungs-Strukt -> stop\n\r"); + stop++; + return 0x00; + } + + // Jetzt noch die eigentlichen Receive- und send-char-Speicher + size_t blen = b_size * blockgroesse; + buffer_p = calloc (1, blen); + if (buffer_p > 0x00) + { + memset (buffer_p, 0x00, blen); + } + else + { + // gibt es noch nichts! -> evtl. Fehlemeldung, dass nciht mehr genuegend Speicher vorhanden ist. + eprintf ("Error: Kein Speicher mehr bei create_charbuffer, r_buffer -> stop\n\r"); + stop++; + return 0x00; + } + + // Und die Buffer-Verwaltung noch initialisieren + + init_header (kopf_p, buffer_p, b_size, b_schwelle, blockgroesse); + return kopf_p; + } + +io_buf_s *create_charbuffer_io (uint16_t r_size, uint16_t s_size, uint16_t r_schwelle, uint16_t s_schwelle, uint16_t blockgroesse) + { + io_buf_s *rbio; // Ring-Bufferpaar I/O + void *r_buffer_p; + void *s_buffer_p; + if (g_display_Funktion) {eprintf ("In create_charbuffer: \r\n"); } + + // Zuerst mal Speicher fuer die 2 I/O-Verwaltungsstrukturen holen + + rbio = (io_buf_s *) calloc (1, (sizeof(io_buf_s))); + if (rbio > 0x00) + { + memset (rbio, 0x00, (sizeof(io_buf_s))); + } + else + { + // Fehler! + eprintf ("Error: Kein Speicher mehr bei create_charbuffer-Verwaltungs-Strukt -> stop\n\r"); + stop++; + return 0x00; + } + // Jetzt noch die eigentlichen Receive- und send-char-Speicher + size_t blen = r_size * blockgroesse; + r_buffer_p = calloc (1, blen); + if (r_buffer_p > 0x00) + { + memset (r_buffer_p, 0x00, blen); + } + else + { + // gibt es noch nichts! -> evtl. Fehlemeldung, dass nciht mehr genuegend Speicher vorhanden ist. + eprintf ("Error: Kein Speicher mehr bei create_charbuffer, r_buffer -> stop\n\r"); + stop++; + return 0x00; + } + + // pointer_add_check_null (r_buffer, "create_charbuffer receive_buffer"); + size_t slen = s_size * blockgroesse; + s_buffer_p = (char *) calloc (1, blockgroesse); + if (s_buffer_p > 0x00) + { + memset (s_buffer_p, 0x00, slen); + } + else + { + // evtl. Fehlermeldung, dass nicht genuegend Speicher vorhanden ist. + eprintf ("Error: Kein Speicher mehr bei create_charbuffer, s_buffer -> stop\n\r"); + stop++; + return 0x00; + } + // Jetzt noch die Bufferzeiger in die Verwaltungsstrukturen eintragen + // Und die Buffer-Verwaltung noch initialisieren + + init_header (&(rbio->in), r_buffer_p, r_size, r_schwelle, blockgroesse); + init_header (&(rbio->out), s_buffer_p, s_size, s_schwelle, blockgroesse); + return rbio; + } + +void *charbuffer_readable (buffer_header_t * r) // Nur schauen, ob im Buffer neue chars drin sind. + { + if (r->bufcnt == 0) + { + return 0; + } + else + { + return r->out; // ?!? + } + } + +void *charbuffer_get (buffer_header_t *r, void *target) // Einen char/Block rausholen mit Readzeiger++ + { + void *p_b; // Pointer block + if (g_display_Funktion) {eprintf ("In charbuffer_get: \r\n"); } + if (r->bufcnt == 0) + { + r->flags = r->flags & ((uint8_t) (~NOT_EMPTY)); + return 0; + } + // else + // p_b = r->out++; // ?!? // zuerst rausholen, dann Read-Zeiger versetzen + p_b = r->out; + r->out = (void *) (((char *) r->out) + r->blockgroesse ); + r->bufcnt--; // Ein char weniger im Buffer + if (r->bufcnt >= r->Schwelle) + { + r->flags = r->flags | ((uint8_t) (FAST_VOLL)); + } + else + { + r->flags = r->flags & ((uint8_t) (~FAST_VOLL)); + } + if (r->bufcnt == 0) + { + r->flags = r->flags & ((uint8_t) (~NOT_EMPTY)); + } + memcpy (target, p_b, r->blockgroesse); + + // (1 - 8) + // if (r->out >= r->buf + (r->buflen)) // ?? Hier ist die Zeigerarithmetik noch unklar! + if (r->out >= (void *)(((char *)(r->buf)) + (r->buflen * r->blockgroesse))) // ?? Hier ist die Zeigerarithmetik noch unklar! + { + // wrap around to beginning + r->out = r->buf; + } + return p_b; // ?!? + } + +void charbuffer_copy (void *qf, void *zf, uint16_t groesse) // Quelle -> Ziel kopieren // ?!? noch ben�tigt? + { + // + if (g_display_Funktion) {eprintf ("In charbuffer_copy: \r\n"); } + memcpy (zf, qf, groesse); + return; + } + +void charbuffer_move (void *qf, void *zf, uint16_t groesse) // Quelle -> Ziel (Move char mit anschliessendem loeschen der Quelle) + { + if (g_display_Funktion) {eprintf ("In charbuffer_move: \r\n"); } + charbuffer_copy (qf, zf, groesse); + memset (qf, 0x00, groesse); + //?!? evtl. noch get machen? + } + +char *charbuffer_put (buffer_header_t *r, void *b_p) // Ein Zeichen/Block einstellen + { + // b_p = Block-Pointer + void *target; + if (g_display_Funktion) {eprintf ("In charbuffer_put: \r\n"); } + if (r->bufcnt >= r->buflen) + { + r->fehleranzahl++; + r->flags = r->flags | ((uint8_t) (FEHLER)); + return 0; // Wenn Buffer voll dann mit Nullpointer zurueck + } + target = r->in; + memcpy (r->in, b_p, r->blockgroesse); + r->bufcnt++; if (r->bufcnt > r->peak_max) {r->peak_max = r->bufcnt;} + if (r->bufcnt >= r->Schwelle) + { + r->flags = r->flags | ((uint8_t) (FAST_VOLL)); + } + else + { + r->flags = r->flags & ((uint8_t) (~FAST_VOLL)); + } + r->anzahl++; // Anzahl aller Zeichen/Bloecke aufsummiert + r->flags = r->flags | ((uint8_t) (NOT_EMPTY)); + + // r->in++; // Falls er das zuerst machen sollte! + r->in = (void *) (((char *) r->in) + r->blockgroesse ); + //if (r->in >= r->buf + r->buflen) + if (r->in >= (void *) (((char *)r->buf) + (r->buflen * r->blockgroesse))) + { + // Bei Zeiger > Buffer, Zeiger wieder an Anfang vom Buffer + r->in = r->buf; + } + return (char *)target; + } + +void print_verwaltung (buffer_header_t *rbk_p) + { + if (rbk_p > 0x00) + { + eprintf (" charbufferverwaltung Zeiger = 0x%08X\r\n", rbk_p); + eprintf (" buflen = %d\r\n", rbk_p->buflen); + eprintf (" bufcnt = %d\r\n", rbk_p->bufcnt); + eprintf (" Zeiger *in = 0x%08X\r\n", rbk_p->in); + eprintf (" Zeiger *out = 0x%08X\r\n", rbk_p->out); + eprintf (" Zeiger *buf = 0x%08X\r\n", rbk_p->buf); + eprintf (" charanzahl = %d\r\n", rbk_p->anzahl); + eprintf (" Fehleranzahl = %d\r\n", rbk_p->fehleranzahl); + eprintf (" Schwelle = %d\r\n", rbk_p->Schwelle); + eprintf (" Flags = 0x%08X\r\n", rbk_p->flags); + eprintf (" Max.Fuellst. = %d\r\n", rbk_p->peak_max); + eprintf (" Blockgroesse = %d\r\n", rbk_p->blockgroesse); + } + else + { + if (g_display_error) + { + eprintf ("Error: In print_verwaltung: Zeiger rbk_p ist ungueltig! \r\n"); + } + } + return; + } + +void display_rbuffer_header (io_buf_s *rb) + { + buffer_header_t *rbk_p; + if (g_display_Funktion) {eprintf ("In print_verwaltung: \r\n"); } + if (rb > 0x00) + { + if (debug_display_charbuffer_header) + { + eprintf ("In display charbuffer charbufferspeicherzeiger = 0x%08X\r\n", rb); + } + if (display_receive_io) + { + rbk_p = &rb->in; + if (rbk_p > 0x00) + { + eprintf (" Receive Struktur: rbk_p = 0x%08X\r\n", rbk_p); + print_verwaltung (rbk_p); + } + else + { + if (g_display_error) + { + eprintf ("Error: In display_charbuffer_verwaltung: *rbk_p ist ungueltig! \r\n"); + } + } + } + if (display_send_io) + { + rbk_p = &rb->out; + if (rbk_p > 0x00) + { + eprintf (" Send Struktur: rbk_p = 0x%08X\r\n", rbk_p); + print_verwaltung (rbk_p); + } + else + { + if (g_display_error) + { + eprintf ("Error: In display_charbuffer_verwaltung display_send: *rbk_p ist ungueltig! \r\n"); + } + } + } + } + else + { + if (g_display_error) + { + eprintf ("Eror: In display_charbuffer_verwaltung: *rb ist ungueltig! \r\n"); + } + } + return; + } + +#endif // von __charbuf_c_