ring buffer

rbuf.c

Committer:
est2fe
Date:
2011-06-23
Revision:
2:d1095a112328
Parent:
0:eae8cffdd121
Child:
3:c9c7c8e20336

File content as of revision 2:d1095a112328:

#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 Ojekte drin sind. 
   {
     return r->bufcnt; 
/*
     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_