Als Anfänger in Sachen STM32 Programmierung stellt sich mir die Frage
auf, ob ich zur Ausgabe von Debug Meldungen ITM/SWO oder UART verwenden
soll.
Während der Entwicklungszeit ist das ziemlich egal, da nehme ich einfach
den Anschluss, der gerade frei ist. Ob ich dazu einen Adapterkabel mehr
oder weniger brauche ist mir ziemlich wurscht. Interessanter finde ich
die Zeit danach.
Beruflich programmiere ich Backend Services. Dort kann ich nicht einfach
"male eben" einen Debugger an das produktive System anschließen. Daher
habe ich mich daran gewöhnt, mit Logfiles zu arbeiten, die der Betrieb
mir zusammen mit der Problembeschreibung zuschickt.
Ähnliche Situationen kann ich mir auch bei Mikrocontrollern vorstellen.
Mein Gerät versagt beim Kunden und ich hätte gerne ein Logfile, um nicht
blind raten zu müssen, woran es genau scheitert.
1) USB
Am Kundenfreundlichsten erscheint mir dazu der USB Anschluss, falls
vorhanden und frei. Dieser kann sich als serielles Device anmelden und
Meldungen ausgeben.
2) UART
Sofern ein UART dafür frei ist, könnte ich Debug Meldungen auf diesem
Anschluss ausgeben. Um sie auszulesen, braucht man allerdings einen
zusätzlichen Adapter, der jedoch leicht zu beschaffen ist. An dieser
Methode gefällt mir, dass sie bei fast allen µC anwendbar ist. Wenn ich
in meinem Gerät mehrere µC kombiniere (was ehrlich gesagt nicht oft
vorkommt) könnte man so mit einem Adapter alle µC untersuchen.
Im AVR Umfeld habe ich hierzu oft eine Soft-UART Emulation mit der
Bereitschafts-LED kombiniert. Ich lasse diese einfach flackern, um
Meldungen auszugeben, so kann man das Signal wahlweise elektrisch oder
gar optisch abnehmen.
3) ITM/SWO
Diese Schnittstelle finde ich wegen ihrer hohen Übertragungsrate
interessant und weil sie keinen UART belegt. Andererseits braucht man
dazu wiederum einen anderen Adapter der wesentlich kostet mehr als 3
Euro.
Außerdem bin ich unsicher, ob diese Schnittstelle wirklich so super
performant ist, denn sie überträgt jedes Zeichen scheinbar als 32Bit und
ich habe noch nicht herausgefunden, wie man einen Sendepuffer mit
Interrupts verwendet, falls das mal nötig werden sollte.
Um SWO zu benutzen, braucht man vermutlich mehr als 2 Leitungen
(GND+SWO), sonst wird die Schnittstelle nicht aktiviert, richtig?
Praktisch ist hier wiederum, dass diese ITM/SWO Schnittstelle bereits
einen standardisierten Mechanismus zum ein/aus Schalten mitbringt. Bei
USART müsste ich hingegen irgendeinen Schalter selbst implementieren.
Habe ich etwas vergessen, was ich bedenken sollte?
Ich hab auf meinen (AVR-) Boards eigentlich immer zwei Sachen drauf:
- den UART-TX "irgendwie" freigelegt (idealerweise als Jumper, oder
allermindestens als Löt-Pad), und schick da auch fast immer
Debug-Meldungen, egal ob wer zuhört oder nicht. Ein simpler
UART-to-USB-Adapter ist schnell angestöpselt...
- eine Power-Led, die eigentlich eine Heartbeat-Led ist, also regelmäßig
kurz aufblinkt. Diese nutze ich fürs Fehler-Reporting gern mit einem
4-Bit "Morse-Code" (kurz/lang).
beides ist natürlich weit von einem echten Logfile entfernt, aber 95%
der Standard-Situationen hab ich damit ganz passabel im Griff...
> beides ist natürlich weit von einem echten Logfile entfernt, aber 95%> der Standard-Situationen hab ich damit ganz passabel im Griff
Das denke ich auch. Diesen speziellen SWO Anschluss mit einem ST-Link
(nicht den billigen aus China) zu verwenden, macht die Anwendung für
nicht-Entwickler nur unnötig kompliziert. Oder nicht?
Wobei sich damit offensichtlich selbst die Entwickler der
Entwicklungstools schwer tun (nicht jeder kann sich Keil leisten).
Stefan U. schrieb:>> Habe ich etwas vergessen, was ich bedenken sollte?
Ja, die Softwareseite. Weniger invasiv als ITM geht's nicht. Du brauchst
auf dem Target keinerlei serielle Treiber, Interrupts oder
Peripherieinitialisierung, und die Ausgabe eines Zeichens ist genau ein
Maschinenbefehl. Einen passenden USB Device Stack auf einem Target zu
realisieren kostet schon anständigen footprint, von der
Hardwarebestückung mal ganz abgesehen...
Du brauchst allerdings eine Debug Probe und Hostsoftware, die die ITM
Befehle interpretieren und weiterverarbeiten kann. Das geht schon u.A.
mit enem ST Link und Open IDEs wie WinIdea. Wenn Du einen schnellen
Datendurchsatz willst, sollte es aber schon eine etwas bessere probe mit
lokaler Intelligenz sein (der Cortex Kern hat einen FIFO, den Du pollen
musst, bevor das nächste Zeichen heraus kann).
SWO geht auch, braucht aber extra pins, und der ST hat leider den
Designfehler, dass die SWO pins in "falscher Reihenfolge" mit höheren
Adressleitungen gemultiplext sind, d.h. mit einem externen Adressbus
einer gewissen Grösse kannst Du noch nicht mal mit 1 bit SWO Output
fahren, ohne deinen Adressbereich einzuschränken.
Ruediger A. schrieb:> Einen passenden USB Device Stack auf einem Target zu realisieren kostet> schon anständigen footprint, von der Hardwarebestückung mal ganz> abgesehen...
Vor allem könnte der ja vielleicht auch fehlerhaft sein... wenn das
Problem kein simpler Rechen/Algorithmus Fehler mehr ist sondern ein
hinterhältiges Timing Problem oder Absturz der Software, hilft USB auch
nicht bzw. macht's vielleicht sogar noch schlimmer.
> der Cortex Kern hat einen FIFO
Weißt du zufällig, wo man darüber etwas nachlesen kann? Ich habe in der
Doku von STM nicht gefunden. Kann aber auch sein, dass ich mich in den
tausenden Seiten Text verlaufen habe. Wenn der FIFO größer ist, als
meine Meldungen, dann wäre das ja schon ein starkes Argument für
ITM/SWO. Zur richtigen Anwendung sollte ich dann aber auch dessen Größe
kennen und berücksichtigen.
Schneller Durchsatz ist für mich nicht so sehr wichtig, eher dass der
Impact von gelegentlichen Ausgaben auf das laufende Programm möglichst
gering ist. Daher mein Interesse am Puffer.
> SWO geht auch
Moment mal, ich dachte ITM ist SWO. Falsch? Kläre mich auf, ich bin für
jede Erklärung dankbar!
> externen Adressbus
Oh, das ist sehr lange her, dass ich einen externen Adressbus verwenden
musste. Inzwischen bekommt man ja viele Sachen intern, für die man
früher ganze TTL Grabstätten zusammen löten musste. Dennoch gut zu
wissen, das sollte man im Hinterkopf behalten.
> wenn das Problem kein simpler Rechen/Algorithmus Fehler mehr> ist sondern ein hinterhältiges Timing Problem oder Absturz> der Software, hilft USB auch nicht
Gutes Argument gegen USB, daran hatte ich noch nicht gedacht. Das
Szenario finde ich sehr realistisch.
Stefan U. schrieb:>> der Cortex Kern hat einen FIFO>> Weißt du zufällig, wo man darüber etwas nachlesen kann? Ich habe in der> Doku von STM nicht gefunden. Kann aber auch sein, dass ich mich in den> tausenden Seiten Text verlaufen habe. Wenn der FIFO größer ist, als> meine Meldungen, dann wäre das ja schon ein starkes Argument für> ITM/SWO. Zur richtigen Anwendung sollte ich dann aber auch dessen Größe> kennen und berücksichtigen.>
Hallo Stefan,
probiere mal die folgenden Quellen:
- Yiu Kapitel 15
- ARM®v7-M Architecture Reference Manual
- ARM Debug and Trace Configuration and Usage Models, ARM Doc. DEN0034A
Man muss sich für manche Dokumente offiziell bei ARM registrieren, um
daran zu kommen...
allerdings müsstest Du für die konkrete Implementation z.B. des FIFOs
beim jeweiligen POD in der Doku suchen, also in deinem Fall im Referenz
Manual bzw. App Notes bei ST.
In meinem Buch gehe ich auch darauf ein, allerdings wird die Tiefe für
das, was Dich interessiert, vermutlich nicht ausreichen.
>>> SWO geht auch>> Moment mal, ich dachte ITM ist SWO. Falsch? Kläre mich auf, ich bin für> jede Erklärung dankbar!>
Nein, die Debug Architektur beim Cortex M ist etwas elaborierter, such
mal das o.E. Reference Manual, da ist der Zusammenhang zwischen den
Debug relevanten Modulen recht genau beschrieben.
Danke, ich schau gleich mal in das Architecture Reference Manual, das
habe ich vorliegen. Als ich es damals zum Einstieg überflogen hatte,
verstand ich nur Bahnhof, aber inzwischen habe ich ja schon etwas
Erfahrung, so dass ich es nochmal lesen sollte.
Ich habe drei Angaben zum ITM FIFO Buffer gefunden:
ARM sagt im Architektur Manual, dass die Puffergröße "implementation
dependent" sei.
Auf http://infocenter.arm.com hingegen steht: 10 Bytes
YIU sagt laut leseprobe auf Google Books in Appendix G, dass es
beispielsweise 4 Bytes sein können (diesen Anhang habe ich in meinem
gedruckten Buch nicht wieder gefunden).
Ist ja nicht gerade der große Knaller, wenn man bedenkt, dass da jedes
einzelne Textzeichen als 16bit gesendet wird.
SWO funktioniert nicht (=hängt), wenn kein passender Debugger
angeschlossen ist und läuft.
Du brauchst also normal verschiedene Software, eine mit SWO und eine
ohne. Es ist glaube ich möglich zur Laufzeit zu erkennen ob einer
angeschlossen ist, das gibt dann aber wieder Probleme wenn der im
Betrieb abgestekct wird.
Mir ist das zu viel Stress für wenig zusätzlichen Nutzen. Daher nehm ich
normal einen UART und zusätzlich eine LED für Heartbeat + Blinkcodes.
Wenn einfach möglich, führe ich auch noch 2 oder 3 freie GPIOs auf
Testpunkte raus. Da kann man dann bei Bedarf ein Oszi oder Logicanalyzer
ranhängen, die Pins an passenden Stellen toggeln und damit dann
Timingprobleme eingrenzen.
Michael R. schrieb:> - den UART-TX "irgendwie" freigelegt (idealerweise als Jumper, oder> allermindestens als Löt-Pad), und schick da auch fast immer> Debug-Meldungen, egal ob wer zuhört oder nicht.
Bereitet Dir das keine Probleme mit verlängerten Laufzeiten oder sind
Deine Anwendungen so langsam, dass es egal ist?
Uwe B. schrieb:> SWO ist output only. Wie soll da erkannt werden, ob ein Debugger> anhgeschlossen werden.
Es ist generell möglich zu erkennen ob ein Debugger dran ist. Das habe
ich auch schon genau dafür genutzt. Das hatte aber irgendein Problem,
ich meine der hatte den Debugger auch erkannt wenn der die SWO Daten
nicht abgeholt hat, und dann hängt das Programm...
> SWO funktioniert nicht (=hängt), wenn kein passender Debugger> angeschlossen ist und läuft.
Die Funktion in der CMSIS (zumindest meiner) prüft von dem Schreiben
jedes einzelnen Zeichens, ob die Schnittstelle aktiviert ist.
Das macht natürlich den Performance Vorteil zunichte. Da kann ich auch
gleich einen Debug Jumper vorsehen und einen USART Ausgang verwenden.
> Mir ist das zu viel Stress für wenig zusätzlichen Nutzen. Daher nehm ich> normal einen UART und zusätzlich eine LED für Heartbeat + Blinkcodes.
Ja, das denke ich momentan auch. Zumal sich diese Methode auch bei
anderen Controller bewährt hat.
> SWO ist output only. Wie soll da erkannt werden, ob ein Debugger> angeschlossen werden.
Die Ausgabe muss durch die SWD Schnittstelle vorher aktiviert werden. Ob
der SWO Ausgang mit dem Debugger verbunden ist, weiß der Chip in der Tat
nicht.
Stefan U. schrieb:>> SWO funktioniert nicht (=hängt), wenn kein passender Debugger>> angeschlossen ist und läuft.>> Die Funktion in der CMSIS (zumindest meiner) prüft von dem Schreiben> jedes einzelnen Zeichens, ob die Schnittstelle aktiviert ist.>>
>> Das macht natürlich den Performance Vorteil zunichte. Da kann ich auch> gleich einen Debug Jumper vorsehen und einen USART Ausgang verwenden.>
Ja, abgesehen von Dr. Sommer's Punkt, dass die UART Treiber Software
vermutlich mit dem Rest des Systems auch den Geist aufgibt, und lt.
Murphy genau dann, wenn Du einen Zyklus vor dem Pinpointen des Problems
bist...
;-)
Aber Du MUSST das ja nicht so implementieren. Die CMSIS Implementation
ist optional. Du kannst Dir natürlich auch eine Inline Funktion
schreiben, die mit #ifdef nur dann etwas tut (=das Register beschreibt),
wenn die Debugversion aktiviert ist, Du also weisst, dass ein Debugger
angeschlossen ist. Ich finde die CMSIS Version aus genau diesem Grunde
ziemlich unnötig.
Eine interessante, selten benutzte Eigenschaft der ITM ist, dass Du
jedes auszugebende Zeichen mit einem von 32 Endpunkten ("Stimulus")
taggen kannst. Wenn dein Debugger das kann, kannst Du somit mehrere
verschiedene Debugziele nebenläufig adressieren. Es kann sogar sein,
dass jedes Stimulus einen eigenen FIFO hat (das müsste ich aber
nachschlagen und ist vermutlich implementationsabhängig).
> ich meine der hatte den Debugger auch erkannt wenn der die SWO Daten> nicht abgeholt hat, und dann hängt das Programm...
Das war wohl eher das semihosting, da blockieren die Ausgaben ohne
Debugger.
Ich möchte da nochmal nachhaken:
Stefan U. schrieb:> Im AVR Umfeld habe ich hierzu oft eine Soft-UART Emulation mit der> Bereitschafts-LED kombiniert. Ich lasse diese einfach flackern, um> Meldungen auszugeben, so kann man das Signal wahlweise elektrisch oder> gar optisch abnehmen.
Die Idee mit dem "optisch abnehmen" gefällt mir... hat jemand sowas
schon mal gemacht?
was mich auch interessieren täte (hab nur grad nix rumliegen um es zu
probieren):
- sind (kurze) UART-Ausgaben einigermaßen gut an der LED erkennbar (ohne
den Inhalt "abzugreifen", also die klassische Heartbeat-LED
- kriegt man es hin, "normale" Blinkmuster und serielle Meldungen zu
kombinieren, oder macht man sich damit das serielle Protokoll kaputt?
Stefan U. schrieb:> Habe ich etwas vergessen, was ich bedenken sollte?
Wenn der Controller gegen Auslesen geschützt werden soll (RDP Level 2):
"JTAG, SWV (serial-wire viewer), ETM, and boundary scan are disabled."
Was bei RDP Level 1 im einzelnen noch geht, ist nicht ganz klar, das
muss man erst einmal genau prüfen, bevor man sich "auf ewig bindet".
Deshalb sollte man von vornherein nicht auf die normalen
Debug-Möglichkeiten beim Kunden setzten. Man muss also selbst
stricken ...
Michael R. schrieb:> Die Idee mit dem "optisch abnehmen" gefällt mir... hat jemand sowas> schon mal gemacht?
Macht fast jedes Handmultimeter so. Wenn ich mich richtig erinnere,
hatte ich irgendwo mal gesehen daß ein Kaffee-Vollautomat so Debug-Daten
ausgibt.
Wenn Du Dir nicht richtig viel Mühe gibst mit Umgebungslicht abschirmen,
tolle Fotodiodenschaltung etc., bist Du halt in der Bandbreite begrenzt.
19200 oder 38400 dürften noch so gehen, drüber wirds schon schwieriger.
Der ganze Aufwand lohnt sich also nur, wenn entweder jegliche
Durchbrüche ins Gehäuse sehr teuer sind, gute galvanische Trennung nötig
ist oder es wirklich auf den allerletzten Cent ankommt (Kaffeemaschine).
> - sind (kurze) UART-Ausgaben einigermaßen gut an der LED erkennbar (ohne> den Inhalt "abzugreifen", also die klassische Heartbeat-LED
Du siehst es klar flackern wenn was übertragen wird.
> - kriegt man es hin, "normale" Blinkmuster und serielle Meldungen zu> kombinieren, oder macht man sich damit das serielle Protokoll kaputt?
Du kannst spezielle Datenmuster übertragen, die gültige UART-Daten sind,
aber gleichzeitig deutlich sichtbar sind. Dann hast Du halt immer wieder
Blöcke mit diesen Müll-Daten im Protokoll. Aber wenn das immer die
selben sind, kann man die ja leicht per Software rausfiltern.
Wenn die Daten dagegen kein gültiges UART sind, kann es passieren daß
Deine serielle Schnittstelle beim Empfänger irgendwann mit Fehlern
aussteigt und echte Daten verloren gehen bis der sich wieder gefangen
hat.
>> 3) ITM/SWO ... Andererseits braucht man dazu wiederum einen>> anderen Adapter der wesentlich kostet mehr als 3 Euro.> Ein STLINK/V2 Clone bei Aliexpress kostet sogar unter USD 2.-
Der taugt aber nicht dazu, weil er keinen SWO Eingang hat.
> Die Idee mit dem "optisch abnehmen" gefällt mir... hat> jemand sowas schon mal gemacht?
Ja ich. Einen Schlauch über einen Fototransistor stecken und den dann
auf die LED drauf stecken. Klappt super.
> kriegt man es hin, "normale" Blinkmuster und serielle> Meldungen zu kombinieren
Klar das ist kein Problem. Bei jedem Blinken empfängt der USB-UART
allerdings ein ungültiges Zeichen. Das ist mir bei der
Debug-Schnittstelle ziemlich egal.
Stefan U. schrieb:> Ja ich. Einen Schlauch über einen Fototransistor stecken und den dann> auf die LED drauf stecken. Klappt super.
wird lästig bei SMD-LEDs...
anyway, ich hab das Mal in die Liste "Dinge die ich noch ausprobieren
will" eingetragen (leider ist die ziemlich lang, und bis zur pension
dauerts noch...)
Stefan U. schrieb:>> Ein STLINK/V2 Clone bei Aliexpress kostet sogar unter USD 2.->> Der taugt aber nicht dazu, weil er keinen SWO Eingang hat.
Bei ST-Chips wäre ein ST Demoboard günstig, die können auf J-Link
upgedatet werden (inkl. SWO Pin).
Wichtiger als die Wahl der Schnittstelle, ist es IMHO ein Debug
Interface
zu definieren, so dass später nur der entsprechende Treiber darunter
getauscht werden muss. Dann ist es egal, ob RS232, USB, ITM, Ethernet...
Bsp: DEBUG_MSG(DEBUG_WARNING, "tmax: %i", tmax);
Exceptions ins nirgendwo laufen bei mir normalerweise in eine
Endlosschleife, die die letzten verwertbaren Informationen endlos über
die Schnittstelle ausgeben.
Stefan U. schrieb:>> Ein STLINK/V2 Clone bei Aliexpress kostet sogar unter USD 2.->> Der taugt aber nicht dazu, weil er keinen SWO Eingang hat.
Alternativ kann man daraus auch eine Black Magic Probe machen, die soll
das auch können. Diese Seite hat mir da sehr geholfen:
https://wiki.cuvoodoo.info/doku.php?id=jtag
Einen seriellen Adapter (USB VCP) hat man da auch mit drin (zumindest
bei der Baite Version die einen 10 pol. Pfostenstecker auf der
Targetseite hat), das reduziert das Kabelwirrwarr.