Wie programmiert JTAG eine MCU?

Wie würde JTAG eine MCU mit Flash-Speicher programmieren? Mir ist klar, dass dies wahrscheinlich von Chip zu Chip unterschiedlich ist, aber ich gehe davon aus, dass es einen Prozess gibt, den sie alle gemeinsam haben. Insbesondere frage ich in Bezug auf den LPC1768, der im Datenblatt nicht angibt, wie Sie dies tun würden.

Schauen Sie sich die ARM JTAG-Dokumente an, z. ADIv5.2
@SpehroPefhany, danke. Mühe, es zu verstehen. Könnten Sie mich auf die Seiten verweisen, die die Flash-Programmierung erklären?
Sie sollten sich nicht nur die JTAG-Dokumente ansehen, die Sphero erklärt hat, sondern auch, welches Modul Sie für JTAG verwenden möchten, wie Keil oder Black Magic Probe usw. Dies ist eine vage Frage, da Sie eher eine Vorstellung von JTAG stellen als etwas Bestimmtes zu wählen.
Versuchen Sie, das JTAG-Protokoll zu verstehen oder wie ein Chip es implementiert?
@whatsisname, ich versuche, den Prozess zu verstehen, der zum Programmieren von Flash-Speicher auf einem LPC1768 über JTAG verwendet wird.

Antworten (5)

Wie würde JTAG eine MCU mit Flash-Speicher programmieren?

In den meisten MCUs ist JTAG nicht direkt mit Flash verbunden. Es gibt tatsächlich einen Stapel von Zugriffsmethoden, jede mit ihrem Protokoll. Ein Debugger / systeminterner Programmierer muss mit allen "sprechen", um tatsächlich den Flash zu erreichen.

Insbesondere frage ich in Bezug auf den LPC1768

LPCs basieren auf ARM Cortex-M. Sie nutzen die Debug-Infrastruktur von ARM . Der Weg von JTAG zu Flash ist:

JTAG -> JTAG-DP -> AHB-AP -> Haupt-AHB-Bus -> Flash

Aber diesen direkten Weg werden wir eigentlich nicht gehen. LPCs stellen die Blinkfunktion über IAP bereit.

Lassen Sie uns die Schritte im Detail beschreiben:

JTAG

JTAG ist der übliche Name für ein Drahtprotokoll, das eine Kette von TAPs (Test Access Ports) über 4 Drähte (TCK TMS TDI TDO) verfügbar macht. Eine JTAG-Kette ist eine große Kette von Schieberegistern mit einer standardisierten Methode zum Auswählen der Register jedes TAP und zum Zugreifen auf den Registerwert. TAPs können einen beliebigen Satz von Registern beliebiger Größe verfügbar machen.

JTAG-DP (JTAG Debug Port) ist ein von ARM spezifizierter TAP, der hauptsächlich zwei 32-Bit-Register namens DPACC und APACC (tatsächlich 35 Bit, wegen der Verkettung mit 3 Operationsbits) verwendet, die den Zugriff auf AP und DP ermöglichen. Dies ist der Einstiegspunkt für das ARM-Debug-Modell.

ARM Debug-Port und Access-Port

Der Debug-Port von ARM ist ein Gateway zu Zugriffsports. Zugriffsports legen die Schnittstelle für etwas anderes offen. DP kann Zugriffe auf 256 APs multiplexen. Die meisten MCUs im LPC-Bereich enthalten nur einen AP, der Zugriff auf die interne AHB (Amba Host Bridge) gewährt, dh die interne Schaltmatrix, die die CPU und alle anderen IPs miteinander verbindet. (Nun, eigentlich ist AHB-AP nicht direkt mit dem Hauptbus verbunden, sondern geht zu einem Debug-Bus, der eng mit der CPU gekoppelt ist, siehe Cortex-Designdokumente für blutige Details).

Das Design von ARM für das Cortex-M-Debugging ist speicherbasiert: Die Debugger-Schnittstelle ermöglicht den Zugriff auf den Speicher (Adresse + Daten, Lesen/Schreiben usw.), und die CPU-Debug-Verwaltung (Anhalten, Überprüfen von Registern usw.) erfolgt über Speicherzuordnung Register, auf die über die Speicherschnittstelle zugegriffen werden kann (siehe Kapitel 10 in Cortex-M3 TRM ).

Hauptbus

Wenn wir dort ankommen, haben wir Zugriff auf den Hauptspeicherbus und können die CPU steuern. Über den Speicherbus haben wir Zugriff auf alle internen IPs, als ob wir Code von der CPU ausführen würden.

Chipspezifische Init

Heutzutage verfügen die meisten MCUs über eine ordnungsgemäße Energieverwaltung. Dies beinhaltet im Allgemeinen zwei Hauptaspekte: Power-Gating (Entfernen von Strom von Teilen des Chips) und Clock-Management (Oszillator-Aktivierung und Clock-Routing).

Die meisten Chips aktivieren Power Gates und Clocks nicht auf magische Weise, wenn ein Debugger angeschlossen ist, daher muss der Debugger auch die Plattformverwaltung übernehmen und die ordnungsgemäße Initialisierung verschiedener MCU-IPs durchführen, bevor er tatsächlich den internen Flash erreicht.

Blinken

Können wir dann mit Flash IP sprechen?

Ja, aber nicht effizient.

Wenn wir alle Speicherzugriffe vom externen Debugger nach Vorschrift machen, wird das funktionieren, aber extrem langsam sein. Das Problem, das wir beim JTAG-Zugriff haben, besteht darin, dass im Allgemeinen eine USB-basierte Sonde mit einer großen (~ Millisekunden) Umlaufzeit durchlaufen wird. Flash-IP-Zugriffe beinhalten normalerweise einen Algorithmus wie:

  1. Schreibzugriff aktivieren
  2. Zieladresse schreiben
  3. Schreiben Sie ein Datenwort
  4. Warten Sie, bis die IP durch Polling bereit ist
  5. Schreibvorgang auslösen
  6. Warten Sie, bis die IP durch Polling bereit ist
  7. Gehen Sie zurück zu 2, ad libitum

Es gibt zu viele Abfragen, wenn wir ein paar Millisekunden für jede Iteration dieser Schleife verlieren, wird das Programmieren unserer paar Dutzend KiB Code ewig dauern. Wir werden versuchen, dies zu beseitigen.

Effizienter Flash-Zugriff

Der allgemeine Fall besteht darin, ein kleines Programm in den RAM der MCU hochzuladen, das Datenblöcke aus dem RAM in den Flash kopieren kann. Die Idee besteht darin, USB-Roundtrips zu vermeiden, indem große bedingungslose Uploads von Daten vom Debugger in den RAM durchgeführt werden (sie können in einer USB-Transaktion gestapelt werden) und die CPU die Kopie zum Flashen ausführen lässt (was im Allgemeinen Wort für Wort erfolgt).

Einige Hersteller (entweder weil sie Implementierungsdetails ihrer Flash-IP verbergen möchten oder weil sie das Leben ihrer Kunden erleichtern möchten) implementieren eine Reihe von ROM-basierten Routinen, die Sie direkt vom Debugger-Port aufrufen können, um verschiedene Arten von Aufgaben auszuführen, einschließlich Chip identifizieren, programmieren, löschen. NXP implementiert eine solche Art von ROM in der LPC-Reihe, sie nennen es IAP.

Variationen um dieses Muster herum

JTAG-Alternativen existieren. ARM hat eine solche Option namens SWD. SWD legt das gleiche Registermodell für DP (Debug Port) und AP (Access Port) offen. Es gibt SWD/JTAG-Varianten (als SWJ-DP bezeichnet), die dynamisch von JTAG auf SWD und umgekehrt umschalten können.

ARM DP/AP-Modellalternativen existieren. Frühere ARMs haben ein anderes Modell, und jeder andere CPU-Anbieter hat seine eigene Art, JTAG (oder ein anderes Debug-Wire-Protokoll) mit Interna zu verbinden.

Die Überbrückung des Debug-Zugriffsports zum Speicher ist eine Option, aber andere Anbieter sorgen dafür, dass der Debug-Port direkt auf die CPU-Register zugreift. Dann kann der Debugger auf den Speicher zugreifen, indem er entweder tatsächliche CPU-Anweisungen in die CPU einfügt (wie Laden und Speichern) oder über spezielle Pseudoregister verfügt, die Speicherzugriffe auslösen. Ti CC2xxx und Mips sind Beispiele für solche Architekturen.

Einige Anbieter haben sich auch für einen direkten Pfad vom Debug-Port zur Flash-IP entschieden, aber das ist ziemlich ungewöhnlich für heutige MCUs, bei denen wir sowieso eine Debug-Fähigkeit haben (weil es indirekten Zugriff auf Flash gibt). Dies war früher üblich für Teile, bei denen die interne CPU keinen Schreibzugriff auf den internen Flash hatte.

+1 Mindestens einige der ARM M7-Varianten von Microchip definieren JTAG-Pins, aber sie sind nur für Boundary-Scan. "Der JTAG-Debug-Port TDI, TDO, TMS und TCK ist inaktiv. Er wird nur für Boundary-Scan-Fertigungstestzwecke bereitgestellt."
Was meinst du mit IP, zB Flash IP?
@ B4039 Ja, in der Tat. In der SoC-Industrie werden alle internen Komponenten als IP bezeichnet. Blitz ist einer von ihnen.

Ich frage in Bezug auf den LPC1768, der im Datenblatt nicht angibt, wie Sie dies tun würden.

Tatsächlich steht es im Referenzhandbuch (UM10360.pdf). Sie legen einfach Daten in den RAM und führen die IAP- CopyRamToFlash()Funktion aus. Ja, auch bei Verwendung eines Debuggers.

Die Debug-Schnittstelle selbst wird vom Core IP-Anbieter (ARM) unter http://infocenter.arm.com dokumentiert (kann jedoch eine Registrierung für das vollständige Dokument erfordern).

Es gibt Unterstützung im Open Source OpenOCD-Projekt - man könnte hier in den Quellcode schauen.

Dies erfordert sicherlich, dass sich bereits eine Art Bootloader auf der MCU befindet, sonst wäre es kein In-Application-Proramming.
Diese MCU hat ihre ISP- und IAP-Funktionen bereits im (Masken-)ROM. Siehe erwähntes Handbuch UM10360.pdf Kapitel 32.8.
Auf welche Speicheradresse würden Sie beim Herunterladen eines Programms blinken?
Ich habe OpenOCD verwendet, um meinen LPC1768 zu flashen und zu debuggen.
Wird die Startadresse dann automatisch gewählt? Ich plane auch, OpenOCD zu verwenden, um meinen LPC1768 zu flashen. Hast du zufällig eine Anleitung dafür?

Ich gehe davon aus, dass es einen Prozess gibt, den sie alle gemeinsam haben.

Im Großen und Ganzen gibt es drei gängige Muster für die Programmierung von Flash über JTAG:

  1. Schreiben Sie Daten direkt in die Flash-Steuerregister, um sie zum Programmieren des Flash-Speichers zu befehlen. Dies ist oft langsam, stellt aber minimale Anforderungen an den Mikrocontroller.

  2. Schreiben Sie ein kleines temporäres Programm in den RAM (oder verwenden Sie den bereits im ROM vorhandenen Code), der die im RAM abgelegten Daten in den Flash kopiert.

  3. Verwenden Sie Mikrocontroller-spezifische JTAG-Operationen, um direkt in Flash zu schreiben.

Von diesen drei Mustern ist das zweite das häufigste. Und wie in der Antwort von Turbo J erläutert, ist dies diejenige, die der LPC1768 verwendet.

Ahhhh, vielleicht erklärt das, warum der OpenOCD-Code für den LPC1768 mehrere IAP-Routinen enthält. Schreibt es also im Wesentlichen ein temporäres Programm in den RAM, das dann IAP verwendet, um Flash zu programmieren? Sie sagen, Option 2 ist das, was der LPC1768 verwendet, aber sollte es nicht auch möglich sein, mit JTAG direkt auf Flash zu schreiben, ohne die Verwendung des temporären Programms?
@ B4039 Theoretisch ist es möglich, aber die Dokumentation für den LPC1768 behandelt nicht die Hardwareschnittstelle zum Flash-Speicher. Die Routinen im ROM (die als Teil des Bootloaders verwendet werden) scheinen die einzige dokumentierte Schnittstelle zum Schreiben in den Flash zu sein.

Als Cortex-m3-basiertes JTAG ist nicht unbedingt der richtige Begriff, SWD wäre eher so.

Es variiert von Chip zu Chip, Design zu Design. Dies ist eine sehr weit gefasste Frage.

Eine kürzere Antwort und vielleicht im Einklang mit etwas, das manchmal gemeinsam ist. Wenn ein Chip in der Anwendungsprogrammierung anbietet, was bedeutet, dass ein Programm, das auf diesem Prozessor ausgeführt wird, den Flash, den dieser Prozessor verwendet, und hoffentlich den Flash-Block, von dem er bootet, löschen/schreiben kann, dann können Sie mit einem On-Chip-Debugger, den der Cortex-m3 hat, zugreifen über eine Schnittstelle SWD/JTAG, was auch immer sie anbieten, um mit diesem Debugger zu kommunizieren. Sie teilen dem On-Chip-Debugger mit, dass er den Prozessor stoppen soll, obwohl dies prozessor- und debuggerspezifisch ist. In diesem Fall hat der On-Chip-Debugger vollen Zugriff auf die amba/axi/apb/etc-Busse am Rand des Cortex-m3, sodass Sie alles tun können, was Sie von einem Programm auf dem Cortex-m3 aus tun können, das Bustransaktionen für Sie generiert kann durch den Debugger über den Prozessorbus in den Herstellerbereich des Chips gelangen, einschließlich des Gesprächs mit dem Flash-Peripheriegerät.

Einige MCUs verfügen über eine spezielle Logikschnittstelle zum Zweck der In-Circuit-Programmierung, die nicht unbedingt (wahrscheinlich nicht) durch den Prozessorkern geht, sondern zum Flash selbst oder zu einem Teil der Peripherie umgeht. Schauen Sie sich die ISP-Schnittstelle für den AVR an (es gibt mehr als eine verschiedene AVR-Schnittstelle, übrigens die Xmegas gegenüber den Nicht-Xmegas), diese sind wahrscheinlich logikbasiert und kein Bootloader und kein JTAG.

Nicht ungewöhnlich, einen werkseitig gebrannten Bootloader im Chip zu haben, wie die NXP-Chips typischerweise, wie der, den Sie haben, der ST Cortex-ms auch, Atmel ARM7, aber sieht nicht wie der Cortex-ms aus und so weiter. Manchmal kann man den werkseitig installierten Bootloader ersetzen, manchmal nicht. Diese können jede Schnittstelle verwenden, in der sie entwerfen, manchmal uart, basierend, spi, i2c, usb, benutzerdefiniert.

Und dann gibt es reines JTAG, bei dem ich mich frage, ob diese Chips überhaupt haben, da viele MCUs nicht viele Pins haben und nur wenige/keine übrig haben. JTAG ist eine Zugriffsmethode, wenn Sie über JTAG-Debugger sprechen, JTAG ist der Weg, wie Sie zum Debugger gelangen, es ist nicht JTAG, das ist der Schlüssel, es ist, dass es einen Debugger gibt, der eine Schnittstelle hat und zufällig mit einem verbunden ist JTAG-Schnittstelle, sozusagen, ich habe einen Debugger, den ich mit einer SPI-abhängigen Schnittstelle verbunden habe. Es ist nur die Zugriffsmethode. JTAG wird im Allgemeinen für eine Reihe anderer Dinge verwendet und war für etwas anderes als das On-Chip-Debugging gedacht und wird immer noch sehr häufig für das Non-On-Chip-Debugging verwendet. Es ist also technisch möglich, dass eine JTAG-Kette an eine Flash-Schnittstelle angeschlossen werden könnte, Sie verbinden sich oft mit SRAM für On-Wafer und / oder nach Verpackungstests des SRAM (oder Starten und Überprüfen von mbist), sodass sie möglicherweise auch Zugriff auf einen Flash haben, wenn das Design so ist, und damit könnten Sie mit den richtigen Scan-Ketten Manipulieren Sie die Flash-Schnittstelle so, dass Sie sie programmieren können. Wenn es einen guten Anwendungsfall gäbe, um diesen Flash in der Schaltung zu programmieren, würden sie dort etwas Einfacheres einbauen, was sie für MCUs tun.

Jedes Prozessordesign kann einen On-Chip-Debugger haben oder auch nicht, und das Design dieses Debuggers ist das, was sie wählen, kein Grund anzunehmen, dass die Prozessordesigns zweier Anbieter entfernt gleich sind. Die FUNKTIONALITÄT ist oft dieselbe, Sie können oft durch den On-Chip-Debugger gehen, um auf den Prozessorbus zuzugreifen, um dann auf den Rest des Chips zuzugreifen, es sind nur der Kommunikationspfad und das Protokoll und die Funktionen, die sich unterscheiden. Einige Prozessoren verfügen möglicherweise nicht über einen On-Chip-Debugger. Man könnte sich ein Design vorstellen, bei dem ein Chipentwickler etwas auf dem Hauptbus des Prozessors platziert hat, das den Zugriff ermöglicht, diesen Bus als Hintertür um den Prozessor herum zu überschreiben und zu übernehmen.

Die ARM-Cortex-m-Debug-Schnittstelle ist bei ARM dokumentiert. Die Informationen des Chipherstellers werden vom Chiphersteller dokumentiert, oft können Sie sich durch den Prozessorbus zu den Peripheriegeräten durch die Vordertür einführen, sodass Zugriffe über die Hinter- / Seitentür, die ein Peripheriegerät nicht über die Prozessorbusse übernehmen, oft nicht benötigt werden, aber wenn Vorhanden wäre dann zu hoffen, dass der Chiphersteller dokumentiert, dass in Form der externen Schnittstelle / des Protokolls, das für diesen Zugriff benötigt wird, die tatsächliche Funktionsweise der Interna ihre IP ist und kein Grund, warum sie sie teilen müssen.

Jede „JTAG“-Schnittstelle verwendet eine modellspezifische Zugriffskontrolle, die auf ein bestimmtes Gerät ausgerichtet ist. Das Erstellen eines JTAG-Debuggers aus Rohspezifikationen übersteigt die Fähigkeiten eines Heimwerkerbenutzers und kann einige Sicherheitsmethoden verwenden, die eine gewisse Lizenzierung erfordern.

Gemäß Ihren anderen Fragen haben Sie das Board von einem No-Name-Hersteller auf einer faulen Internetseite gekauft. Als solches wird das Board anscheinend ohne Dokumentation oder Toolchain-Unterstützung geliefert.

Stattdessen sollten Sie sich an den Originalhersteller NXP/Freescale/Motorola wenden und dessen Entwicklungskit mit allen erforderlichen Tutorials und Tools und Unterstützung von Mouser oder ähnlich erhalten

Ich habe dieses Board bereits, aber es hat nicht alle Pins (insbesondere die QEI-Pins, die ich brauche). Egal, deshalb frage ich nicht. Es wäre natürlich einfacher, das Board mit ISP zu programmieren, aber ich bin daran interessiert, zu verstehen, wie der JTAG-Prozess funktioniert.
@ B4039, was meinst du mit "wie"? Ein Chip hat normalerweise einige dedizierte (oder gemeinsam genutzte) Pins, die TAP (Test Access Port oder so) einschalten, und dann übernimmt der Port serielle Befehle und Datenströme vom JTAG-Controller unter der Kontrolle einer bestimmten Anwendungssoftware (die sich der Besonderheiten dieses spezifischen bewusst ist). Prozessor) und kann alle abgedeckten F-Fs in eine oder mehrere JTAG-Ketten ablegen. Obwohl grundlegende JTAG-Befehle standardisiert sind, sind alle Bit-Zuordnungen und die Zugriffskontrolle darauf (insbesondere auf Flash) proprietär und gerätespezifisch.
Dies ist so ziemlich reine Fehlinformation der Art, die allgemein als „Angst, Unsicherheit und Zweifel“ bezeichnet wird, wenn sie nicht, wie in diesem Fall, aus einer Perspektive reiner Unwissenheit gesprochen würde . Tatsächlich sind alle notwendigen Informationen öffentlich, sowohl um einen JTAG-Adapter herzustellen, ihn für die Kommunikation zu verwenden und damit in den Flash-Speicher zu schreiben. Und alles hat vorhandene Open-Source-Implementierungen (für den Debug-Adapter Open Source von nicht weniger als Arm Holdings!), so dass, obwohl ursprüngliche Entwicklungsarbeit vollständig möglich ist, tatsächlich keine benötigt wird.
@ChrisStratton, das Dokument zur Debug-Schnittstellenarchitektur ( static.docs.arm.com/ihi0031/d/… ) scheint vorzuschlagen, dass die Programmierung des Flashs durchgeführt werden kann, indem zuerst DBGTMS auf Shift-IR umgeschaltet, das AP-Register ausgewählt und dann ausgewählt wird DRW- und TAR-Register zum Verschieben von Daten in die erforderlichen Adressen. Ist das richtig?
Wahrscheinlich so etwas für die Kommunikation mit viel mehr Schritten, um es zu verwenden, um tatsächlich in Flash zu schreiben. Aber zwischen Open-Source-CMSIS-DAP (oder Blackmagic oder einfach mit einem FT2232) und Open-Source-OpenOCD, um es zu steuern, müssen Sie sich nicht wirklich mit Implementierungsdetails befassen, es sei denn, Sie finden es interessant, sich damit zu beschäftigen, oder Sie sind es Verwendung eines hochmodernen Chips, der geringfügige Änderungen erfordert - in diesen Fällen, da der Code Open Source ist, steht es Ihnen völlig frei.
Ich habe nicht vor, es zu implementieren, möchte nur wissen, was "unter der Haube" von Implementierungen wie OpenOCD passiert.
@ChrisStratton, obwohl es mit OpenOCD nicht erforderlich ist, diesen "Prozess" zu definieren, wenn er für die Verwendung mit bestimmten Chips konfiguriert wird, die alle unterschiedliche Programmierprozesse haben?
Nun, TurboJ hat Ihnen ein Gefühl dafür gegeben - JTAG-Erweiterungen für die Rohkommunikation mit der ARM-Debug-Engine, dann gehen Sie durch etwas, das oft das Laden der Daten in den RAM, das Aufrufen von Delegate-Code im RAM oder sogar das Springen in ein Hersteller-ROM beinhaltet die tatsächlichen schreibt.
@ B4039 - jemand musste OpenOCD-Konfigurationsdateien erstellen und einen Flash-Algorithmus-spezifischen C-Code schreiben, aber das ist wahrscheinlich bereits für Ihren nicht ganz neuen Zielprozessor vorhanden. Hast du gesehen?
@ChrisStratton, ich konnte nur eine LPC1768-Konfigurationsdatei finden, keinen C-Code.
Die Algorithmen werden typischerweise von Familien ähnlicher Chips gemeinsam genutzt. Für den LPC1768 würde ich vermuten, dass er sich wahrscheinlich in src/flash/nor/lpc2000.c befindet, aber meine Version ist etwas alt und möglicherweise verschoben worden.
@ChrisStratton, ich habe es mir angesehen. Es scheint viele Aufrufe an IAP-Funktionen zu machen. Warum ist das so? Ist IAP nicht für vorhandene Programme zum Ändern/Löschen/Schreiben von Flash-Speicher, daher der Name? Wenn auf dem Flash nichts steht, warum dann IAP-Funktionen aufrufen?
@ B4039, weil die Nutzung des vorhandenen Blinkcodes der einfachste Weg ist. Es kann auch der einzige Weg sein, der funktioniert - Flash hat Überlegungen zum Timing.