Embedded Debugging

CoreSight auf Cortex‑M: Debuggen ohne Eingriff in den Anwendungscode

Was die Hardware verrät und wie belastbar Trace-Aufnahmen wirklich sind

Geronimo Freese

Embedded-Software-Entwickler & Sales

· 9 Minuten Lesezeit

Der Fehler tritt nur beim Kunden auf. Eine zusätzliche Log-Ausgabe lässt ihn verschwinden, und ein Breakpoint verändert das Timing so stark, dass sich die Ursache nicht mehr reproduzieren lässt. Wer Embedded-Systeme debuggt, kennt dieses Muster.

Viele Cortex‑M-Mikrocontroller bringen Messhardware mit, die in solchen Situationen helfen kann. Arm fasst die zugehörigen Debug- und Trace-Bausteine unter CoreSight zusammen. Je nach Chip lassen sich damit Speicherzugriffe, Exceptions oder der Programmfluss beobachten, ohne die Firmware neu zu übersetzen oder zusätzliche Diagnoseaufrufe einzubauen.

Der entscheidende Zusatz lautet: je nach Chip. „Cortex‑M“ garantiert weder DWT noch ITM, ETM, MTB oder einen nutzbaren Trace-Ausgang. Was tatsächlich funktioniert, hängt vom konkreten Core und seiner Konfiguration, der Integration im MCU, den Zugriffsrechten, dem Board-Routing, der Probe und dem Decoder ab. Erst diese ganze Kette bestimmt, was eine Aufnahme belegt.

CoreSight ist kein einzelner Block

CoreSight ist modular: Debug-Zugriff, Trace-Erzeugung, Transport und Speicherung sind getrennte Aufgaben. Eine bewusst vereinfachte Anordnung sieht so aus:

Debug-Zugang
Probe ── SWD oder JTAG ──> Debug Port ──> Access Port ──> Core, Speicher,
                                                        CoreSight-Register

Instrumentation und Ereignisse
DWT-Hardwareereignisse ─┐
                        ├──> ITM-Paketpfad ──> SWO oder Trace-Infrastruktur
ITM-Softwaremeldungen ──┘

Programmfluss und System-Trace
ETM ─┐
STM ─┴──> ATB ──> Funnel/Replicator ──> TPIU + Trace-Port oder TMC-Sink

Lokaler Program-Trace
MTB ──> reservierter SRAM-Puffer ──> später über den Debug-Zugang lesen

Triggersteuerung, nicht Datentransport
CTI/CTM ──> Start-, Stopp- und Cross-Trigger-Signale

CoreSight-Architektur mit getrennten Pfaden für Debug-Zugang, Ereignis-Trace, Programmfluss-Trace, MTB und Cross-Trigger

Abbildung 1: Debugzugang, Trace-Daten und Cross-Trigger sind getrennte Pfade. Welche Blöcke tatsächlich vorhanden sind, bestimmt die konkrete MCU-Integration.

Das ist kein Schaltplan für jedes MCU. Wichtig ist: SWD, SWO und ein paralleler Trace-Port sind nicht austauschbar. SWD beziehungsweise JTAG verbindet die Probe mit dem Debug Access Port (DAP), der aus einem Debug Port und Access Ports besteht. Darüber erreicht das Werkzeug Core, Speicher und CoreSight-Register. SWO ist ein serieller Trace-Ausgang; ein paralleler Trace-Port ist ein eigener, breiterer Ausgang.

CoreSight-Trace setzt sich aus drei Gruppen zusammen:

  • Quellen erzeugen Trace. Die DWT kann je nach Ausführung Watchpoints, selektiven Daten-Trace, PC-Sampling, Exception-Ereignisse und Profiling-Zähler bereitstellen. Die ITM transportiert Softwaremeldungen; DWT-Pakete können denselben Paketpfad nutzen. Die ETM erzeugt komprimierten Program-Flow-Trace. Eine optionale STM kann systemweiten Instrumentation-Trace liefern.
  • Links verbinden Quellen und Ziele. Über den ATB (AMBA Trace Bus) können Funnel mehrere Ströme zusammenführen und Replicator einen Strom auf mehrere Ziele verteilen. CTI/CTM übertragen Trigger zwischen Komponenten, aber keine Trace-Daten.
  • Sinks nehmen Trace auf oder geben ihn aus. Dazu gehören ein serieller SWO-Pfad, eine TPIU (Trace Port Interface Unit) für den Trace-Ausgang sowie On-Chip-Puffer oder Speicherziele. Die Trace Memory Controller (TMC)-Architektur kann dabei als ETB, ETF oder ETR konfiguriert sein.

Die MTB (Micro Trace Buffer) steht abseits dieser Pipeline. Sie schreibt nicht-sequenzielle Programmflussänderungen in einen begrenzten SRAM-Bereich, den das Werkzeug später über Debug ausliest. MTB ist kein kontinuierlicher Stream.

Was muss ein Cortex‑M-Hersteller implementieren?

Die kurze Antwort: Es gibt keinen bestimmten CoreSight-Debug- oder Trace-Block, der ausnahmslos in jedem Cortex‑M-Chip vorhanden sein muss. Die CPU- und NVIC-Eigenschaften sowie Architekturkonformität garantieren noch keine nutzbare Trace-Ausstattung. Öffentliche Arm-Datenblätter zeigen für mehrere Cores ausdrücklich Konfigurationen ohne Debug oder Trace.

Architektur und Beispiele Öffentlich dokumentierter Spielraum Konsequenz für Anwender
Allgemein Die Komponenten sind modular und die zulässige Ausstattung hängt vom gewählten Core ab. Aus „Cortex‑M“ allein folgt keine DWT-, ITM-, ETM-, MTB-, SWO- oder Trace-Port-Garantie.
Armv6‑M: Cortex‑M0/M0+ Für M0 und M0+ sind Minimalkonfigurationen ohne Debug dokumentiert; beim M0+ ist MTB optional. Selbst Breakpoints und Watchpoints sind nicht allein durch den Core-Namen zugesichert.
Armv7‑M/Armv7E‑M: Cortex‑M3/M4/M7 M3 und M4 besitzen konfigurierbare Debug- und Trace-Level. Der M7 bietet reduzierte oder volle Watchpoint-/Breakpoint-Sätze; ITM/DWT-Trace und ETM können fehlen. DWT, ITM, TPIU und ETM dürfen nicht pauschal vorausgesetzt werden.
Armv8‑M: Cortex‑M23/M33 Beim M23 sind DWT-Watchpoints konfigurierbar und ETM/MTB optional. Der M33 bietet minimale, reduzierte und volle Debug-Varianten; ITM/DWT-Trace, ETM, MTB und CTI sind konfigurierbar. Security-Funktionen und ein moderner Core-Name bedeuten nicht automatisch „Full Trace“.
Armv8.1‑M, zum Beispiel Cortex‑M55 Auch beim M55 sind unter anderem DWT, ITM und ETM konfigurierbar. Maßgeblich bleiben immer das Datenblatt des Cores und das Reference Manual des konkreten MCUs.

Architekturregeln. Bedingte Architekturregeln greifen erst, wenn entsprechende Komponenten integriert werden: Hinter einem Access Port mit Debug-Komponenten gehört eine auffindbare ROM-Table-Hierarchie. Werden mehrere Trace-Quellen zusammengeführt, brauchen sie eindeutige Trace-IDs und eine passende Formatierung. Das verlangt eine konforme Integration der gewählten Ausstattung, macht die Ausstattung selbst aber nicht universell verpflichtend. Siehe CoreSight Basics: Discovery und CoreSight Basics: Trace.

Lizenzgrenzen. Welche Konfiguration ein Lizenznehmer rechtlich verwenden darf, ergibt sich zusätzlich aus Arm-Lizenzvertrag, Bill of Materials sowie Integration and Implementation Manual. Diese Unterlagen sind nicht vollständig öffentlich. Aus einem MCU-Datenblatt lässt sich deshalb keine allgemeine Aussage über vertragliche Pflichten anderer Hersteller ableiten.

Was sich damit beobachten lässt

Halt, Single-Step, Breakpoints sowie Register- und Speicherzugriff gehören zum invasiven Debug. Sie setzen vorhandene, erreichbare und autorisierte Debug-Hardware voraus. Security- oder Lifecycle-Zustände können den Zugriff beschränken oder abschalten.

Trace erfasst Ereignisse, während der Core weiterläuft. „Nicht haltend“ heißt dennoch nicht „ohne Einfluss“: Trace braucht Takt und Energie, Polling erzeugt Busverkehr und ITM-Softwaremeldungen kosten Instruktionen.

Wer hat diese Variable überschrieben?

Ein DWT-Komparator kann je nach Implementierung eine Adresse oder einen Bereich überwachen und bei einem Zugriff Trace erzeugen. Der Treffer belegt diesen Zugriff; zusätzliche Angaben zu Instruktionsadresse, Datenadresse oder Wert hängen von DWT-Version und Konfiguration ab. Wegen der wenigen Komparatoren und unterschiedlichen Paketmodi testet Daten-Trace eine konkrete Hypothese, nicht den gesamten Speicherverkehr. Ein haltender Watchpoint ist zudem kein nicht-haltendes DWT-Trace-Ereignis.

Was geschah während des Latenz-Ausreißers?

Unterstützte Exception-Trace-Pakete melden Eintritt, Austritt oder Rückkehr und können eine unerwartete Interrupt-Folge sichtbar machen. Exakte Dauern erfordern belastbare Zeitstempel oder eine bekannte Zeitbasis. Zeitstempel, Zyklusinformationen und eine gemeinsame Zeitbasis sind optional; ohne Synchronisierung entsteht keine exakte globale Timeline.

Wo verbringt die CPU ihre Zeit?

PC-Sampling liefert statistische Hotspot-Hinweise, aber weder lückenlose Aufrufhistorien noch exakte Laufzeiten. Ein Sample beweist auch keinen RTOS-Taskwechsel. Dafür braucht es ein Scheduler-Ereignis wie task_switch oder die gezielte Beobachtung von pxCurrentTCB; selbst dann sind Wechselgrenze und Task-Identität getrennte Aussagen.

ITM, ETM und MTB beantworten andere Fragen

ITM eignet sich für strukturierte Softwareereignisse oder printf-ähnliche Ausgaben. Das ist effizient, bleibt aber Instrumentierung.

ETM liefert komprimierten Programmfluss, den der Decoder mit dem exakten Codeabbild rekonstruiert. Ein falsches ELF, veränderter RAM-Code, Overlays oder nicht erfasste dynamische Änderungen verfälschen das Ergebnis. ETM sendet nicht einfach jeden Opcode und ist nicht automatisch verlustfrei.

MTB speichert ein begrenztes Fenster im SRAM. Nach dem Umlauf bleibt nur das aktuelle Fenster; Live-Streaming und eine unbegrenzte Historie bietet MTB nicht.

Cross-Trigger und systemweiter Trace kommen erst hinzu, wenn der Chip zusätzliche CTI/CTM- beziehungsweise STM-Komponenten integriert. Auch diese Fähigkeiten folgen nicht aus dem Cortex‑M-Namen.

Vorhanden, zugänglich und nutzbar sind drei verschiedene Dinge

Ein Datenblatt-Häkchen ist nur der Anfang. In der Praxis scheitert Trace häufig an einer anderen Stelle der Kette:

  • Der Block ist im Silizium vorhanden, sein Ausgang aber nicht auf einen Pin geroutet, nicht in das Gehäuse geführt oder auf dem Board nicht verbunden.
  • Lifecycle-State, TrustZone-Zuordnung oder Debug-Authentisierung erlauben nur einen Teilzugriff oder sperren Debug und Trace vollständig.
  • Clock- oder Power-Gating macht die Komponente in bestimmten Betriebszuständen unerreichbar.
  • Eine Quelle ist vorhanden, aber es fehlt ein geeigneter Sink, ein Transportweg oder eine Probe für Protokoll und Datenrate.
  • SWO-Bandbreite, interne FIFOs oder die Probe reichen nicht aus. Pakete gehen verloren, ein Puffer läuft um, die Synchronisation bricht ab, und nur einzelne Abschnitte bleiben dekodierbar.
  • Mehrere Quellen besitzen ohne gemeinsame Zeitbasis keine automatisch exakte zeitliche Ordnung.
  • Polling und Trace-Konfiguration verändern Takt-, Energie- oder Busverhalten. Nicht-haltend bedeutet nicht wirkungsfrei.
  • ETM-Daten passen nur zum tatsächlich ausgeführten Code. Ein ähnlich benanntes oder später neu gebautes ELF ist kein Identitätsnachweis.

Kette der Voraussetzungen von einer implementierten CoreSight-Komponente bis zur korrekten Dekodierung

Abbildung 2: „Im Silizium vorhanden“ ist nur das erste Glied. Autorisierung, Takt, Routing, Capture und das passende ELF müssen ebenfalls stimmen.

Diese Grenzen gehören in das Ergebnis. Eine teilweise dekodierbare Aufnahme ist nicht wertlos – aber sie darf nicht als vollständige Timeline erscheinen.

Von der Erkennung zum belastbaren Beleg

Statt sofort „Full Trace“ zu versprechen, lohnt sich eine Beweiskette in kleinen Schritten:

Stufe Was diese Stufe belegt Was sie noch nicht belegt
Erkennung Die Probe erreicht das Ziel; erreichbare Komponenten und Feature-Register wurden gelesen. Dass ein Trace-Ausgang, Sink oder Decoder funktioniert.
Debug und Polling Ein Register, Speicherwert oder PC wurde zu bestimmten Abfragezeitpunkten gesehen. Einen kontinuierlichen Ablauf, exakte Übergänge oder fehlende Zwischenereignisse.
SWO-Rohdaten Bytes kamen über den konfigurierten seriellen Pfad an der Probe an; Rohdaten und Verlustindikatoren können gesichert werden. Dass der Stream vollständig, synchron und korrekt einer DWT- oder ITM-Quelle zugeordnet ist.
DWT/ITM Ein unterstütztes DWT-Ereignis oder eine bewusst erzeugte ITM-Meldung wurde korrekt dekodiert. Dass alle Datenzugriffe, Exceptions oder Taskwechsel enthalten sind.
MTB Der ausgelesene SRAM-Puffer enthält rekonstruierbare Programmflussinformation für sein Aufnahmefenster. Live-Streaming, eine unbegrenzte Historie oder ETM-Funktionalität.
ETM Der nachgewiesene ETM-Pfad und das passende Codeabbild erlauben die Rekonstruktion gültiger Capture-Abschnitte. Dass nicht markierte Lücken vollständig sind oder jede Probe und jedes Cortex‑M-MCU Instruction Trace unterstützt.

Beweiskette von der DAP-Erkennung über Polling und SWO-Rohdaten bis zu DWT, ITM, MTB und ETM

Abbildung 3: Jede Stufe liefert stärkere Evidenz, bleibt aber begrenzt. Keine Stufe macht aus verlorenen oder nicht beobachteten Ereignissen automatisch eine vollständige Timeline.

Zu jeder Stufe gehören Rohbytes oder Pufferinhalt, Konfigurationsregister, Taktannahmen, Überlauf- und Synchronisationsstatus sowie die Firmware-Identität. Erst das passende ELF macht Adressen mit Symbolen oder DWARF lesbar; Build-ID, Hash, Speicherbereiche und Thumb-Bit-Behandlung helfen gegen Fehlzuordnungen.

Eine erkannte Probe beweist nur ihre Verbindung. Ein gültiges Paket belegt den Transport, die passende Dekodierung das Ereignis und bekannte Verlustgrenzen erst dessen mögliche Vollständigkeit.

Warum sich der Aufwand lohnt

CoreSight ersetzt nicht jedes Log oder jeden Breakpoint. Es hilft dort, wo zusätzlicher Code das Verhalten verändert: bei Datenkorruption, Interrupt-Stürmen, Latenzspitzen und Race Conditions.

Die beste Aufnahme beginnt mit einer Frage: Welches Hardwareereignis bestätigt oder widerlegt die Hypothese? Ein nachgewiesener Pfad, erhaltene Rohdaten und sichtbare Lücken machen aus der Timeline einen technischen Beleg.

Wie wir hardwarenahe Software von der Architektur bis zum Test begleiten, beschreibt unsere Seite zur Firmware-Entwicklung auf Zielhardware. Für die formale Prüfung verteilter Laufzeitdaten zeigt das Forschungsprojekt TRACE einen ergänzenden Ansatz.

Arm-Quellen und Einstiegspunkte