Hallo, ich habe hier ein kleines selbst entworfenes ARM9-Board. Dieses verfügt über eine serielle RS-232 Verbindung zum PC, und ich möchte da einer Art Konsole entwerfen, um z.B. für Debug-Zwecke bestimmte Funktionen zu starten usw. Da ich ein RTOS einsetze, wird zwar vieles einfacher zum Programmieren, anderes ist dafür ein Krampf... Ich möchte gerne eine Ausgabe von Debug-Meldungen realisieren über die RS-232. Dabei soll jedoch derjenige Task, welcher eine Meldung ausgibt, so wenig wie nur irgend möglich gebremst werden, z.B. durch ein kompliziertes printf. Denn die Tasks führen z.T. Datenübertragungsprotokolle aus oder sollen Messwerte möglichst in Echtzeit verarbeiten. Wenn da ein Task eine Meldung ausgeben soll wie "Messwert 34: 3.25V", und dazu printf braucht, dann wird der Task erstens mal unnötig lange von diesem printf gebremst (das kann ja leider nur Zeichen für Zeichen verarbeiten) und dann wird auch noch ein unnötiger Buffer erstellt, wo der zu sendende String erst zwischengespeichert wird, bevor man damit auf den UART los kann. Mir will das nicht so recht gefallen; gibt es keine elegantere Lösung? Wie kann ich auf einfache Weise eine möglichst schnelle, einigermassen Speicher sparende Ausgabe formatierter Daten über UART ermöglichen, die RTOS tauglich ist?
>Wie kann ich auf einfache Weise eine möglichst schnelle, einigermassen >Speicher sparende Ausgabe formatierter Daten über UART ermöglichen, die >RTOS tauglich ist? Ganz einfach: Du überlegst dir wieviele Daten du wirklich zum debuggen brauchst. Du nimmst eine hohe Datenrate für deinen UART, zb. 115kBaud. Dann ein Sendepuffer der per Interrupt verschickt wird. Wenn der UART die Daten mit 115kBaud nicht schnell genug senden kann weil die eingehenden Daten schneller kommen hast du sowieso schon verloren.
Kleiner Nachtrag: >Wenn da ein Task eine Meldung ausgeben soll wie >"Messwert 34: 3.25V", und dazu printf braucht, dann wird der Task >erstens mal unnötig lange von diesem printf gebremst (das kann ja leider >nur Zeichen für Zeichen verarbeiten) und dann wird auch noch ein >unnötiger Buffer erstellt, wo der zu sendende String erst Ich glaube der ARM9 lacht sich tot über deine Vorstellungen von Verarbeitungszeit und Speicherbedarf von einem printf().
Hmm, okay... ist es denn auch eine elegante Lösung, wenn in diesem printf() jedes Zeichen einzeln ausgegeben wird? Toll wäre ja, wenn man den String erst in einen Buffer schreiben könnte, der dann in einem Rutsch gesendet wird. Aber dann muss ich wieder einen Buffer alloziieren, von dem ich im Vornherein ja sowieso nicht wissen kann, wie gross er sein muss. Hmm...
>ist es denn auch eine elegante Lösung, wenn in diesem >printf() jedes Zeichen einzeln ausgegeben wird? Was? Wie die Zeichen gesendet werden hängt nicht von deinem printf ab. printf benutzt normalerweise (oder auch nicht?) eine putchar Routine. Dort wird festgelegt wie die Zeichen gesendet werden. putchar kann die Zeichen von printf in einen UART Ringpuffer kopieren und gesendet werden sie dann per UART Interrupt. Wie effektiv printf ist hängt also unter Umständen von der Implementierung von putchar ab. Evtl. musst du dir ein putchar selber schreiben. Genaues kann man aber so nicht sagen.
Ein RTOS hat aber auch Queues, Mailboxen usw und auch Threads mit verschiedenen Prioritäten. Statt mit printf() zu arbeiten kann man auch mit sprintf() in einen Buffer schreiben und in eine Mailbox schreiben. Die Buffer einmal allozieren damit der Speicher nicht zerfranst wird. Und aufpassen das nicht langsames lesen das Schreiben blockiert.
tan delta schrieb: > Aber dann muss ich wieder einen Buffer > alloziieren, von dem ich im Vornherein ja sowieso nicht wissen kann, wie > gross er sein muss. Na wenn du als der Programmierer der Software nicht weißt, wie groß die Werte sind, dann hast du an viel früherer Stelle schon ein Problem. Du kennst bzw. schreibst den Debugstring selbst. Du legst auch den Datentyp darin fest. Sogar die Zahl eventueller Nachkommastellen. Debuggen über UART etc. hat halt seinen Preis; nicht umsonst gibt es "richtige" Debugschnittstellen (na ja, z.B. JTAG), teure Debugger und vor allem Breakpoints. Ein ARM9 sollte schon massig Reserven haben, aber das kommt natürlich ganz auf die Anwendung an. Wenn z.B. eine Sequenz wegen Timern etc. nicht vernüftig mit Breakpoints debuggt werden kann, kann man auch einen Sequenzbuffer einrichten, in dem die minimalsten Daten gespeichert werden. Dann nach der Sequenz einen Breakpoint und hier die Daten am Stück ausgeben und analysieren.
Printf() hat mit Echtzeit eh nichts zu suchen. Allenfalls eine feste Anzahl Stellen, zb 8 Hexziffern fuer eine 32bit Zahl.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.