eprintf mit irq

Files at this revision

API Documentation at this revision

Comitter:
est2fe
Date:
Thu Jul 21 07:09:17 2011 +0000
Parent:
1:50fdadc001ef
Child:
3:de07cab9fc01
Commit message:
V0.3

Changed in this revision

eprintf.c Show annotated file Show diff for this revision Revisions of this file
eprintf.h Show annotated file Show diff for this revision Revisions of this file
--- a/eprintf.c	Thu Jun 23 13:58:03 2011 +0000
+++ b/eprintf.c	Thu Jul 21 07:09:17 2011 +0000
@@ -1,68 +1,133 @@
-#ifndef  __os_printf_c__ 
- #define __os_printf_c__ 
- 
-#include "mbed.h" 
+#ifdef  __EPRINTF_C__ 
+#define __EPRINTF_C__ 
+
 #include "eprintf.h" 
-#include "stdarg.h"
 
-void printf_verarbeitung (void) 
-  {
-    //char c; 
-      // Den printf-Buffer leeren (ausgeben) 
-      // Das wird nur hier einzig und allein gemacht! 
-    /* while (printbuffer->anzahl) 
-         { 
-           c = getchar_from_ringbuffer (printbuffer); 
-           putchar (stderror, c); 
-         } 
-    */ 
-    
+static int eprintf_fehlerzaehler = 0; 
+
+void TX_irq_eprintf (void) { 
+      // Wird bei Tx-Empty oder explizit aufgerufen 
+    os.SetEvent (EV_EPRINTF, TASK_EPRINTF_ID); 
+    return; 
   } 
-  
-  // Definition wie printf selber
-  
-int eprintf (char *fmt, ...) 
-  { 
-/*
-int printf(const char *fmt, ...)
-{
-	va_list ap;
-	int i;
 
-	va_start(ap, fmt);
-	i = vfprintf(stdout, fmt, ap);
-	va_end(ap);
-
-	return i;
-} 
-
-   va_list args; 
-   va_start(args, fmt); // Zeiger auf die "..." 
-           
-           vfprintf (stdout, fmt, args);   // alles andere geht zur Zeit nicht, warum auch immer! 
-
-
-*/   
+int  eprintf (char *format_str, ...) {
+     // Soll in den Printbuffer drucken, aber nur, wenn er nicht voll ist. 
+     // Returnwert: 
+     //   0 = ok 
+     //  !0 = Fehler -> siehe defines 
+    int zeit; 
+    int  letzter_Fehler = 0; 
+    Timer tout; 
+    tout.reset();
+    tout.start();
+    while (os.TestResource (RESOURCE_EPRINTF)) 
+      { 
+          // warten bis Resource (eprintf selber) wieder frei ist. 
+        zeit = tout.read_us(); 
+        if (zeit > TO_LockResource) 
+          { 
+            // Timeout 
+            letzter_Fehler = FEHLER_EPRINTF_TEST_RESOURCE; 
+            //eprintf ("\n\rletzer_Fehler = %d, in Zeile %d", letzter_Fehler, __LINE__); 
+            goto eprintf_end_fehler; 
+          } 
+         else 
+          { 
+            // warten
+          } 
+      } 
+    tout.reset (); 
+    tout.start (); 
+    while (!os.LockResource (RESOURCE_EPRINTF)) 
+      { 
+        // warten bis Resource gelockt ist 
+        zeit = tout.read_us (); 
+        if (zeit > TO_LockResource) 
+          { 
+            // Timeout 
+            letzter_Fehler = FEHLER_EPRINTF_LOCK_RESOURCE; 
+            //eprintf ("\n\rletzer_Fehler = %d, in Zeile %d", letzter_Fehler, __LINE__); 
+            goto eprintf_end_fehler; 
+          } 
+         else 
+          { 
+            // warten
+          } 
+      } 
+    if ((printbuf->flags & FAST_VOLL)) 
+      {  
+          // Wenn der Stecker raus ist, laeuft der Buffer voll -> nichts mehr drucken! 
+        letzter_Fehler = FEHLER_EPRINTF_FAST_VOLL; 
+        goto eprintf_end_fehler; 
+      } 
+     else 
+      { 
+        int slen;    // Stringlaenge 
+        va_list      args; 
+        va_start    (args,  format_str); // Zeiger auf die "..." 
+        vsnprintf   (cb,   (SB_GROESSE - 1), format_str, args); 
+        va_end      (args); 
+          // Jetzt den Inhalt vom Spoolbuffer (cb) noch in den printbuffer packen 
+        slen = strlen (cb); 
+        if (slen > (printbuf->buflen - printbuf->bufcnt - 2)) 
+          { 
+              // wenn es nicht reinpasst, gleich mit Fehler zurück 
+            letzter_Fehler = FEHLER_EPRINTF_STRING_ZU_GROSS; 
+            goto eprintf_end_fehler; 
+          } 
+         else 
+          { 
+              // es passt rein, also jedes Zeichen von cb in den Printbuffer 
+            int i; void *fehler; 
+            for (i = 0; i < slen; i++) 
+             { 
+                 // rbuf_put (kbdbuf, &c)
+               fehler = rbuf_put (printbuf, &cb[i]); 
+               if (!fehler) 
+                 {   // Fehler aufgetreten, warum auch immer! 
+                     // Sollte eigentlich nie vorkommen! 
+                   letzter_Fehler = FEHLER_EPRINTF_RBUF_PUT; 
+                   goto eprintf_end_fehler; 
+                 } 
+             } 
+             // Fertig! Nun noch melden, dass neue druckbare Zeichen 
+             // da sind und per Interrupt ausgegeben werden koennen. 
+            os.SetEvent (EV_EPRINTF, TASK_EPRINTF_ID); 
+           } 
+        } 
+    os.FreeResource (RESOURCE_EPRINTF); 
+    TX_irq_eprintf ();     // Und das erste Zeichen, falls möglich, gleich ausgeben 
+    return 0;                  // 0 = kein Fehler 
     
-    /*
-    os.GetResource (RES_PRINTF); 
-      // "fast voll" muss um _"Warning: Printbuffer voll!\n\r"_ = 32 Zeichen groesser sein! 
-    if (!printfbuffer_fast_voll()) 
-      {
-         printf_in_buffer (format); 
-      } 
-     else  
+eprintf_end_fehler: 
+    eprintf_fehlerzaehler++; 
+    os.FreeResource (RESOURCE_EPRINTF); 
+    return letzter_Fehler;     // Mit Fehler zurück 
+  } 
+void task_eprintf_verarbeitung (void) { 
+      // Grundsaetzlich gilt: Immer nur per os warten, wenn es nichts zu tun gibt! 
+    while (1) 
       { 
-        printf_in_buffer ("Warning: Printbuffer voll!\n\r"); 
-      } 
-    os_ReleaseResource 8RES_PRINTF); 
-    */
-   va_list args; 
-   va_start(args, fmt); // Zeiger auf die "..." 
-           
-           vfprintf (stdout, fmt, args);   // alles andere geht zur Zeit nicht, warum auch immer! 
-   return 0; 
-  } 
- 
+        eprintf_wait_event: // Bruch der Schleife while (printbuf->bufcnt > 0) 
+        os.WaitEvent (EV_EPRINTF); 
+        while ((printbuf->bufcnt > 0) && (pc.writeable ())) 
+          { 
+               // So lange was ausgeben bis nicht mehr moeglich 
+             int c;
+             void *z; 
+             z = rbuf_get (printbuf, &c); 
+             if (z == 0)  
+               {  
+                  // wenn Buffer leer, per os warten 
+                  goto eprintf_wait_event; 
+               } 
+             else 
+               {
+                  pc.putc (c); // Das sollte die einzige Stelle im Programm sein, wo was auf den pc ausgegeben wird! 
+               } 
+          } // von while ((printbuf->bufcnt > 0) && (pc.writeable ())) 
+      } // von while (1) 
+  } // void task_eprintf_verarbeitung (void) 
 
-#endif // von ifndef __os_printf_c__ 
+#endif  // von #ifdef __EPRINTF_C__ 
\ No newline at end of file
--- a/eprintf.h	Thu Jun 23 13:58:03 2011 +0000
+++ b/eprintf.h	Thu Jul 21 07:09:17 2011 +0000
@@ -1,10 +1,49 @@
-#ifndef  __os_printf_h__
- #define __os_printf_h__
- 
- // os.SendEvent (EV_PRINTF, &task_printf_Verarbeitung); 
+#ifdef      __EPRINTF_H__ 
+#define     __EPRINTF_H__ 
+
+#include   "extdef.h" 
+#include   "globals.h" 
+#include   "rbuf.h"   
+
+#define     TASK_EPRINTF_ID                2 
+#define     TASK_EPRINTF_PRIO              5 
+#define     TASK_EPRINTF_ID_STACK_SZ     128 
+
+  // Resourcen 
+#define     RESOURCE_EPRINTF               1 
+#define     RESOURCE_EPRINTF_PRIO         70 
+
+  // Events sind Bits innerhalb eines 32-Bit intgers 
+//#define   EV_KEYBOARD                   4 
+#define     EV_EPRINTF                    8 
+//#define   EV_SNIFFER                   16 
 
-void  printf_verarbeitung      (void); 
-int   eprintf                  (char *, ...); 
-void  PC_UART_USB_interrupt    (void); 
+  // Fehler 
+#define     FEHLER_RX_INT_OHNE_ZEICHEN     1 
+#define     FEHLER_RBUF_PUT_IN_RX_INT      2 
+#define     FEHLER_EV_KEYBOARD_OHNE_CHAR   3 
+#define     FEHLER_TX_PUTCHAR              4 
+#define     FEHLER_EPRINTF_TEST_RESOURCE   5 
+#define     FEHLER_EPRINTF_LOCK_RESOURCE   6 
+#define     FEHLER_EPRINTF_FAST_VOLL       7 
+#define     FEHLER_EPRINTF_STRING_ZU_GROSS 8 
+#define     FEHLER_EPRINTF_RBUF_PUT        9 
+
+ // Spoolbuffergroesse fuer eprintf 
+#define     SB_GROESSE                 1024
 
-#endif // von ifndef __os_printf_h__
+ // Timeout für LockResource und TestResource in [us] 
+#define     TO_LockResource            1000 
+
+EXTDEF      rbuf_t     *printbuf; 
+
+int         letzter_Fehler; 
+
+char        cb [SB_GROESSE];            // Der Spoolbuffer zum PC 
+static int  eprintf_fehlerzaehler = 0; 
+
+void        TX_irq_eprintf            (void); 
+int         eprintf                   (char *format, ...); 
+void        task_eprintf_verarbeitung (void); 
+
+#endif      // __EPRINTF_H__ 
\ No newline at end of file