ring buffer

rbuf.c

Committer:
est2fe
Date:
2012-02-28
Revision:
8:40af324896d9
Parent:
7:5e960f7b1f79

File content as of revision 8:40af324896d9:

#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_