eprintf mit irq

eprintf.c

Committer:
est2fe
Date:
2011-07-21
Revision:
3:de07cab9fc01
Parent:
2:f63032cc0c0a
Child:
4:5138a20c4989

File content as of revision 3:de07cab9fc01:

#ifndef  __EPRINTF_C__ 
 #define __EPRINTF_C__ 

#include "eprintf.h" 

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; 
  } 

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 
    
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) 
      { 
        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 #ifdef __EPRINTF_C__