TraceSWO

Ich bin vor einiger Zeit über die vielfältigen Debug Möglichkeiten eines ARM Cortex-M3 Mikrocontrollers gestoßen. Neben dem klassischen Step-by-Step debuggen mittels breakpoints bietet der Cortex-M3 einige Peripherie um die laufende Applikation in Echtzeit zu untersuchen.
Nun wie gesagt die Möglichkeiten sind vielfältig. Jeder einzelne Interruppt oder Methodenaufruf oder Taskwitch (wenn man ein RTOS benutzt) lässt sich in Echtzeit verfolgen.

Daher habe ich mich gefragt warum sind diese features noch so unbekannt? Warum findet man kaum was dazu im Internet? Meine persönliche Vermutung ist, weil die Tools dafür sehr teuer sind. Man ist schnell im Bereich von mehreren Tausend €. Als Hobbybastler ist man da erstmal außen vor. Aber vielleicht gibt es ja Alternativen? Oder vieleicht kann man zumindest ein Subset von den Möglichkeiten auch im Hobbybereich nutzen. Nach kurzer weiterer Recherche ist mir ein Feature besonders ins Auge gestoßen. Das sogenannte „Single Wire Output (SWO)“ und darum soll es in diesem Post gehen.

Das SWO Feature ist das Ergebnis vom Zusammenspiel zweier Peripherien des Cortex-M3. Einmal der ITM (Instrumentation Trace Macrocell) und der TPIU(Trace Port Interface Unit) eines Cortex-M3.

ITM ist eine Applikations gesteuerte debug Peripherie, die die Möglichkeit bietet mit bis zu 32 Kanälen gleichzeitig Daten auszugeben. Das altbekannte „printf“ kann leicht angepasst werden um Textnachrichten über SWO auszugeben.

  • Bei GCC muss lediglich die Methode „int _write (int fd, const void *buf, size_t count)“ angepasst werden.
  • Bei ARM Compiler ist es die „int fputc(int ch, FILE *f)“ Methode.

Die ARM eigene CMSIS lib bietet bereits die Funktion „uint32_t ITM_SendChar (uint32_t ch)“ welche ein einzelnes Zeichen über den ersten SWO Kanal (Port 0) ausgibt. Möchte man mehr als diesen einen Kanal gleichzeitig nutzen, braucht man eine eigene ITM_SendChar Methode. Der letzte Kanal ist inoffiziel für RTOS debugging reserviert. Viele RTOS wie das RTX, FreeRTOS machen bereits von diesem Feature gebrauch.
Nun was genau würde man auf dem SWO Pin sehen? Standardmäßig würde man ein Manchester codiertes UART ähnliches Signal in der halben Geschwindigkeit des Systemtaktes sehen. Allerdings lässt sich da auch noch einiges anpassen. Einmal lässt sich die Codierung auf NRZ (typische UART Codierung) umstellen. Weiterhin lässt sich mit einem Prescaler die Taktrate deutlich senken. Aber keine Sorge dieses Interface ist immernoch sehr schnell. Meist wird die Einstellung NRZ mit 2 MBaud benutzt. Es war ja auch von 32 Kanälen die Rede und das alles auf nur einem Pin? Ja! Da kommt die TPIU Peripherie ins Spiel. Diese serialisiert die ganzen Daten und verpackt sie in ein fixes Format. Und es kann noch mehr. Es können hardware TimeStamps hinzugefügt werden. Und falls die Applikation doch zu schnell ist, so dass die TPIU mit dem versenden nicht hitnerherkommt, dann gibt es ein „Overflow“ Paket, so dass der debugger mitbekommt wenn Daten verloren gegangen sind.

Spannenderweise unterstützen die ganzen günstigen ST-Link Adapter von ST bereits dieses feature. Sogar auf den ganzen Discoveryboards. Bei manchen Boards muss lediglich der SWO pin des Targets mit dem des ST-Link verbunden werden. Das ST-Link Utility hat ein einfaches Terminal Fenster auf dem alle Ausgaben angezeigt werden.

SWO

Allerdings hat das ganze auch einen Haken. Der interne Buffer des ST-Link Adapters scheint zu klein zu sein, so dass Daten verloren gehen wenn man zu viele Daten ausgibt. Bei meinen Tests musste ich meine Applikation auf 20 KBaud drosseln bis ich gar keine Daten mehr verliere. Also um den Faktor 100! Sehr schade!

Nun wie gesagt letztendlich ist es ein einfacher unidirektionaler UART also liegt die Vermutung naha einfach ein günstiges USB 2 UART kabel anzuschließen. Diese sehr günstigen adapter können bis zu 3 MBaud problemlos. Und siehe da , tatsächlich man bekommt alle Daten. Allerdings hat das wiederum 2 Nachteile. Einmal sieht man das rohe TPIU Datenformat, welches das ST-Link Utility entpackt, aber es ist recht simpel und mit einem einfachen Pyhton Script lässt sich das Format schnell umwandeln.

Der größte Nachteil ist: Man benötigt immer einen angeschlossenen Debugger. Die gesamte ITM+TPIU peripherie wird nur aktiviert wenn sich der Cortex-M3 im debug mode befindet. Und dieser lässt sich nur von außen mittels eines Debuggers aktivieren. Nun ist es wirklich umständlich erst einen Debugger anzuschließen und dann anschließend einen USB2UART. Daher habe ich noch weiter nach einer Alternative gesucht und bin dabei über das Black Magic Probe Projekt gestoßen. Ein opensource Debug Adapter über USB, welches gleichzeitig auch noch einen USB2UART enthält. Also alles was ich für das SWO brauche in einem. Lustigerweise funktioniert die Black Magic Probe Firmware auch auf den ST-Link Adaptern. Allerdings habe ich einfach ein STM32f103C8 Mini Board für 2€ aus China benutzt. Und es läuft wunderbar.

lib2

Nun die Frage ist wozu das ganze? Warum nicht einfach einen vorhanden UART benutzen? Mein Hauptgrund war, ich hatte schlichtweg kein UART mehr frei. Mein eingesetzter Mikrocontroller hat nur 4 und diese sind bereits alle in Benutzung.
Aber es gibt noch mehr:

Vorteile:

+ sehr schnell (theoretisch Systemtakt/2)
+ 32 parallele Kanälen
+ belastet CPU viel weniger als z.B. ein UART
+ Flow Controll by Hardware
+Hardware TimeStamps

Nachteile:

– Es muss immer ein Debugger angeschlossen sein
– Es gibt zwar die Möglichkeit über den SWO pin Daten auch zu empfangen aber dies ist sehr komplex

Advertisements

Gedanken dazu …

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s