eprintf mit irq
Diff: eprintf.c
- Revision:
- 2:f63032cc0c0a
- Parent:
- 1:50fdadc001ef
- Child:
- 3:de07cab9fc01
--- 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