ring buffer

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_