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?
SWO ist output only. Wie soll da erkannt werden, ob ein Debugger anhgeschlossen werden. Du meinst wahrscheinlich einen anderen Arm Debug Mechanismus.
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.
1 | __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) |
2 | {
|
3 | if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ |
4 | ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ |
5 | {
|
6 | while (ITM->PORT[0U].u32 == 0UL) |
7 | {
|
8 | __NOP(); |
9 | }
|
10 | ITM->PORT[0U].u8 = (uint8_t)ch; |
11 | }
|
12 | return (ch); |
13 | }
|
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. > >
1 | > __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) |
2 | > { |
3 | > if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ |
4 | > ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 |
5 | > enabled */
|
6 | > { |
7 | > while (ITM->PORT[0U].u32 == 0UL) |
8 | > { |
9 | > __NOP(); |
10 | > } |
11 | > ITM->PORT[0U].u8 = (uint8_t)ch; |
12 | > } |
13 | > return (ch); |
14 | > } |
15 | >
|
> > 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).
Stefan U. schrieb: > 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. Ein STLINK/V2 Clone bei Aliexpress kostet sogar unter USD 2.- https://de.aliexpress.com/item/1PCS-ST-LINK-Stlink-ST-Link-V2-Mini-STM8-STM32-Simulator-Download-Programmer-Programming-With-Cover/32792513237.html
> 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?
nimm doch ein Lcd für Fehlermeldungen und gib einen kurzen Error-code aus.
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 ...
Stefan U. schrieb: > Moment mal, ich dachte ITM ist SWO. Falsch? Kläre mich auf, ich bin für > jede Erklärung dankbar! ETM und ITM sind die beiden Trace-Module, welche in der TPIU gebündelt werden und SWO ist dann eine der Schnittstellen der TPIU zur Ausenwelt. Habe mal ein BSB aus dem Technical Reference Manual des CM4 angehängt. Ergänzend zur Liste von Rüdiger würde ich noch das "CoresightComponents Technical Reference Manual" empfehlen: http://infocenter.arm.com/help/topic/com.arm.doc.ddi0314h/DDI0314H_coresight_components_trm.pdf Für ETM gibt es noch eigens die "Embedded Trace Macrocell Architecture Specification": https://static.docs.arm.com/ihi0064/d/IHI0064D_etm_v4_architecture_spec.pdf
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.
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.