eprintf mit irq
eprintf.c
- Committer:
- est2fe
- Date:
- 2011-07-21
- Revision:
- 2:f63032cc0c0a
- Parent:
- 1:50fdadc001ef
- Child:
- 3:de07cab9fc01
File content as of revision 2:f63032cc0c0a:
#ifdef __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__