ring buffer
rbuf.c
- Committer:
- est2fe
- Date:
- 2011-11-01
- Revision:
- 7:5e960f7b1f79
- Parent:
- 5:ddc33cb62d27
- Child:
- 8:40af324896d9
File content as of revision 7:5e960f7b1f79:
#ifndef __rbuf_c_ #define __rbuf_c_ #include "mbed.h" #include "rbuf.h" void init_header (rbuf_t *h, void *buf, uint16_t objektanzahl, uint16_t Schwelle, uint16_t objektgroesse) { 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; } rbuf_t *rbuf_init (uint16_t b_size, uint16_t b_schwelle, uint16_t blockgroesse) { void *buffer_p; rbuf_t *kopf_p; // Zuerst mal Speicher fuer die Verwaltungsstruktur holen kopf_p = (rbuf_t *) calloc (1, (sizeof(rbuf_t))); if (kopf_p > 0x00) { memset (kopf_p, 0x00, (sizeof(rbuf_t))); } else { 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 nicht mehr genuegend Speicher vorhanden ist. return 0x00; } // Und die Buffer-Verwaltung noch initialisieren init_header (kopf_p, buffer_p, b_size, b_schwelle, blockgroesse); return kopf_p; } void *rbuf_look (rbuf_t * r) // Nur schauen, ob im Buffer neue Ojekte drin sind. { // return r->bufcnt; if (r->bufcnt == 0) { return 0; } else { return r->out; // ?!? } } void *rbuf_get (rbuf_t *r, void *target) // Einen char/Block rausholen mit Readzeiger++ { void *p_b = r->out; // Pointer block if (r->bufcnt == 0) { r->flags = r->flags & ((uint8_t) (~NOT_EMPTY)); return 0; } __disable_irq(); // Disable Interrupts r->bufcnt--; // Ein Objekt weniger im Buffer __enable_irq(); // Enable Interrupts p_b = (void *) (((char *) p_b) + r->blockgroesse ); 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, r->out, r->blockgroesse); // (1 - 8) // if (r->out >= r->buf + (r->buflen)) // ?? Hier ist die Zeigerarithmetik noch unklar! if (p_b >= (void *)(((char *)(r->buf)) + (r->buflen * r->blockgroesse))) // ?? Hier ist die Zeigerarithmetik noch unklar! { // wrap around to beginning p_b = r->buf; } r->out = p_b; return p_b; // ?!? } void *rbuf_put (rbuf_t *r, void *b_p) // Ein Zeichen/Block einstellen { void *p_alt = r->in; void *p_neu = p_alt; int cnt = r->bufcnt; if (cnt >= r->buflen) { r->fehleranzahl++; r->flags = r->flags | ((uint8_t) (FEHLER)); return 0; // Wenn Buffer voll dann mit Nullpointer zurueck } memcpy (p_alt, b_p, r->blockgroesse); cnt++; if ((cnt) > r->peak_max) {r->peak_max = cnt;} if (cnt >= 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! p_neu = (void *) (((char *) p_neu) + r->blockgroesse ); if (p_neu >= (void *) (((char *)r->buf) + (r->buflen * r->blockgroesse))) { // Bei Zeiger > Buffer, Zeiger wieder an Anfang vom Buffer p_neu = r->buf; } r->in = p_neu; __disable_irq(); // Disable Interrupts r->bufcnt++; // = cnt; __enable_irq(); // Enable Interrupts return p_alt; } uint32_t rbuf_getcnt (rbuf_t *buffer) { return buffer->bufcnt; } uint32_t rbuf_getflags (rbuf_t *buffer) { return buffer->flags; } uint32_t rbuf_getfehler (rbuf_t *buffer) { return buffer->fehleranzahl; } uint32_t rbuf_leer (rbuf_t *buffer) { return !(buffer->flags && NOT_EMPTY); } uint32_t rbuf_fast_voll (rbuf_t *buffer) { return (buffer->flags && FAST_VOLL); } uint32_t rbuf_fehler (rbuf_t *buffer) { return (buffer->flags && FEHLER); } uint32_t rbuf_getfehleranz (rbuf_t *buffer) { return buffer->fehleranzahl; } uint32_t rbuf_get_gesendet (rbuf_t *buffer) { return buffer->anzahl; } #endif // von __rbuf_c_