Hallo,
weiß hier jemand was im inneren eines J-Link Debuggers steckt? Mich
würde vor allem interessieren, wie es sein kann, dass man damit fast
unendlich viele breakpoints setzen kann und der ST-Link dagegen nur 3
unterstützt.
ARM Controller unterstützen je nach Modell unterschiedlich viele
Hardware Breakpoints. Typischerweise weniger als 10. Daran kann der
Programmieradapter nicht ändern. Hardware Breakpoints beruhen darauf,
das eine spezielle Funktionseinheit in der CPU den Programm-Zähler mit
einer Tabelle vergleicht und bei einem Treffer entsprechend reagiert.
Dann gibt es noch Software Breakpoints:
Der Programmierer muss dazu in seinen Quelltext Haltepunkte einfügen:
1
__BKPT(n);
Die CPU hält das Programm dann dort an und sendet den Programmieradapter
das Signal "Ich habe einen Soft-Breakpoint n erreicht".
Im Gegensatz zum Hardware Breakpoint muss man für die Nutzung von
Software Breakpoints die Software modifizieren, was eventuell
unerwartete Seiteneffekte mit sich bringt. Vor allem darf man nicht
vergessen, alle Software Breakpoints zu entfernen, bevor man das fertige
Programm abliefert.
Von einem AVR kenne ich noch eine andere Variante: Der Debugger ersetzt
direkt im Flash einen "normalen" Befehl durch einen Break Befehl. Wenn
die CPU dann dort anhält, muss wieder der ursprüngliche Befehl
hingeschrieben werden, um es fortzusetzen. Es finden also ziemlich viele
Flash-Zugriffe statt.
Stefanus F. schrieb:> Der Programmierer muss dazu in seinen Quelltext Haltepunkte einfügen
Nö, muss er nicht.
Das macht der JLink automatisch wenn man im Debugger an Stelle xyz einen
Breakpoint haben will.
Die schreibt er auch nicht in den Programmcode, sondern direkt in
Flash/RAM.
Bei Prozessoren die aus dem Flash laufen dauert das dann natürlich etwas
länger, beim laufen aus RAM merkt mans nicht.
Stefanus F. schrieb:> Der Debugger ersetzt> direkt im Flash einen "normalen" Befehl durch einen Break Befehl. Wenn> die CPU dann dort anhält, muss wieder der ursprüngliche Befehl> hingeschrieben werden, um es fortzusetzen. Es finden also ziemlich viele> Flash-Zugriffe statt.
Das muss man beim AVR machen, weil die CPU keine Befehle aus dem RAM
ausführen kann.
Ich bin mir ziemlich sicher das beim JLink ein anderer Weg für Flash
Breakpoints gewählt wurde: Die mit Breakpoints überschriebenen Befehle
werden "simuliert",d.h. deren Seiteneffekte direkt vom Debugger in die
Hardware geschrieben.
Danke schon mal für die Antworten. Wie kann man sich das mit dem Setzen
im Flash vorstellen? Der Maschinencode vom Compiler wird vom J-Link beim
draufflashen "erweitert"?
Mw E. schrieb:> Stefanus F. schrieb:>> Der Programmierer muss dazu in seinen Quelltext Haltepunkte einfügen>> Nö, muss er nicht.> Das macht der JLink automatisch wenn man im Debugger an Stelle xyz einen> Breakpoint haben will.
?? Das heißt, ich setze den Brakepoint nicht explizit im Quellcode,
sondern der Debugger liest meine Gedanken?
> Bei Prozessoren die aus dem Flash laufen dauert das dann natürlich etwas> länger, beim laufen aus RAM merkt mans nicht.
Auch beim Ausführen aus dem RAM kostet das extra Zeit, die ggf. ein
Timing durcheinander bringen kann.
Rolf M. schrieb:> Das heißt, ich setze den Brakepoint nicht explizit im Quellcode,> sondern der Debugger liest meine Gedanken?
Nein, der Debugger ändert das Programm im Chip, bevor er es ausführt,
aber nachdem du ihm gesagt hast, wo du den Breakpoint haben willst.
Genau deswegen hat x86 auch eine besondere Codierung für "int 3". Für
alle anderen Werte braucht er ein zusätzliches Byte...
Rolf M. schrieb:> Mw E. schrieb:>> Stefanus F. schrieb:>>> Der Programmierer muss dazu in seinen Quelltext Haltepunkte einfügen>>>> Nö, muss er nicht.>> Das macht der JLink automatisch wenn man im Debugger an Stelle xyz einen>> Breakpoint haben will.>> ?? Das heißt, ich setze den Brakepoint nicht explizit im Quellcode,> sondern der Debugger liest meine Gedanken?
Nein in der IDE / im Debugger klickste wie gewohnt die Codezeile an.
Aber ein "__BKPT(n);" muss man eben nicht vorm Compilieren eintippen.
ka mit was stefanus da arbeitet.
Rolf M. schrieb:> Auch beim Ausführen aus dem RAM kostet das extra Zeit, die ggf. ein> Timing durcheinander bringen kann.
Mir gings da eher um die Schreibzeit für die Binäränderung im Flash mit
vorherigem erase.
Beim Flash Breakpoints setzen auf STM32 mit dem JLink blitzt dann mal
kurz der Programmerfortschrittsbalken auf.
Das allgemeine Timing vom Programm wird natürlich immer beinträchtigt.
Wenn man das nicht will muss man tracen.
Rolf M. schrieb:>> Nö, muss er nicht.>> Das macht der JLink automatisch wenn man im Debugger an Stelle xyz einen>> Breakpoint haben will.>> ?? Das heißt, ich setze den Brakepoint nicht explizit im Quellcode,> sondern der Debugger liest meine Gedanken?
Der Eine muss es hinschreiben, der Andere setzt nur ein Häkchen in der
IDE.....
Meine Aussage, dass Breakpoints in das Programm eingefügt werden ist
aber doch prinzipiell richtig, oder?
Frage dazu: Muss das Programm dazu neu compiliert werden? Wenn nicht,
stelle ich mir vor, dass der Breakpoint einen bestehenden Befehl
überschreibt. Wie wird der ursprüngliche Befehl dann beim Fortsetzen
ausgeführt?
Jim M. schrieb:> Die mit Breakpoints überschriebenen Befehle> werden "simuliert",d.h. deren Seiteneffekte direkt vom Debugger in die> Hardware geschrieben.
Das klingt für mich sehr überraschend. Ist es wirklich so?
> Den Komfort eines J-Links
Ein J-Link ist nicht komfortabel. Der kann gerademal das
Allernotwendigste. Ein Trace-Buffer fehlt z.B. voellig.
> Muss das Programm dazu neu compiliert werden?
[ ]
> Wie wird der ursprüngliche Befehl dann beim Fortsetzen> ausgeführt?
Indem er da wieder hingeschrieben wird wo er hingehoert.
Sprung drauf, fertig.
> dass Breakpoints in das Programm eingefügt werden ist> aber doch prinzipiell richtig, oder?
Eine vor vielen Moeglichkeiten. Es gibt noch in der Hardware
Matchregister die auch unterbrechen koennen.
Stefanus F. schrieb:> Frage dazu: Muss das Programm dazu neu compiliert werden?
Normalerweise nicht. Ein "Breakpoint"-Befehl ist meistens so lang wie
der kürzeste Befehl des Instruction Sets (z.B. x86: "int 3" ist ein
1-Byte-Befehl). Den kann man also immer irgendwo hinsetzen.
> Wenn nicht, stelle ich mir vor, dass der Breakpoint einen> bestehenden Befehl überschreibt. Wie wird der ursprüngliche> Befehl dann beim Fortsetzen ausgeführt?
Der Debugger merkt sich beim Setzen des Breakpoints einfach, welcher
Befehl da vorher stand. Entweder, er schreibt den Befehl zurück, setzt
den Program Counter einen Befehl zurück und lässt die CPU weiterlaufen -
oder er führt den Befehl schlicht selbst aus.
Ersteres macht z.B. DOS DEBUG: Es überschreibt den RAM mit "int 3",
fängt den Debug-Interrupt ab, stellt das Byte wieder her, repariert den
CPU-Zustand und setzt die Ausführung fort. Dadurch können auch Programme
untersucht werden, die Befehle benutzen, die DEBUG nicht kennt.
> Jim M. schrieb:>> Die mit Breakpoints überschriebenen Befehle werden>> "simuliert", d.h. deren Seiteneffekte direkt vom Debugger>> in die Hardware geschrieben.> Das klingt für mich sehr überraschend. Ist es wirklich so?
Für die meisten Befehle sind die Nebeneffekte überschaubar (Arithmetik,
Sprünge), daher ist das eine gute Optimierung. Geht natürlich
prinzipbedingt nicht für alle Befehle.
... schrieb:>> Den Komfort eines J-Links>> Ein J-Link ist nicht komfortabel. Der kann gerademal das> Allernotwendigste. Ein Trace-Buffer fehlt z.B. voellig.
Du hast hier im Forum schon öfter gezeigt, dass du von nix ne Ahnung
hast ;)
So langsam sollteste einfach ma leise sein.
Der Jlink is super zum debuggen.
Zum tracen gibts den J-Trace und der kost dann aber richtig Knete.
Stefanus F. schrieb:> Meine Aussage, dass Breakpoints in das Programm eingefügt werden ist> aber doch prinzipiell richtig, oder?
Nur bei Softwarebreakpoints ist deine Aussage richtig.
Stefanus F. schrieb:> Frage dazu: Muss das Programm dazu neu compiliert werden? Wenn nicht,> stelle ich mir vor, dass der Breakpoint einen bestehenden Befehl> überschreibt. Wie wird der ursprüngliche Befehl dann beim Fortsetzen> ausgeführt?
Ein SW Breakpoint im Flash wird nicht zurückgeschrieben sondern
simuliert vom Jlink.
Jedenfalls kommt beim steppen duurch Flash SW Breakpoints kein
aufblitzen des Programmierbalkens vom Jlink und es geht auch richtig fix
drüber.
Den break wieder durch den vorherigen Befehl zu ersetzen gibts aber
auch.
Der Debugger macht das was grade am sinnvollsten ist.
> Der Jlink is super zum debuggen.> Zum tracen gibts den J-Trace und der kost dann aber richtig Knete.
Aha. Was macht das super denn aus?
Ich habe hier 2 J-Links plus einen auf einem Renesas-Board.
Die tun was sie sollen, aber super?
Kann ein RTOS weiterlaufen beim Debuggen?
Oder werden alle Timerinterrupts beim Debuggen abgewuergt?
Kann der J-Link auf wundersame Weise HW-Register auslesen
ohne das das Auslesen bereits Zustaende der Hardware
veraendert?
Mit den J-Links geht im wesentlichen auch nicht mehr, als mit einem
Monitorprogramm aus dem letzten Jahrtausend.
Erleuchte mich doch mal...
Jim M. schrieb:> Die mit Breakpoints überschriebenen Befehle> werden "simuliert",d.h. deren Seiteneffekte direkt vom Debugger in die> Hardware geschrieben.
Ich kann aber mitten im Debuggen den Spannung ausschalten und den
Debugger abstöpseln, nach einem Neustart läuft das Binary auf dem
Cotroller ohne jede Beeinträchtigung.
... schrieb:> Kann ein RTOS weiterlaufen beim Debuggen?> Oder werden alle Timerinterrupts beim Debuggen abgewuergt?> Kann der J-Link auf wundersame Weise HW-Register auslesen> ohne das das Auslesen bereits Zustaende der Hardware> veraendert?
Und mit welchem Debugger arbeitest Du der das obige alles beherrscht,
inklusive der wundersamen lesen-ohne-zu-lesen-Funktion? Wieviel kostet
der?
Mw E. schrieb:> @Bernd:> Ja welche CPU denn?> Läuft die ausm Flash oder RAM?
Aus dem Flash, RAM wäre gar nicht genug drin bei den kleinen die ich
benutze.
> Waren kleiner/gleich Breakpoints gesetzt als die CPU Hardwarebreakpoints> hat?
Eine handvoll. Ehrlich gesagt hab ich noch nicht nachgezählt und mit dem
Datenblatt verglichen. Mir ist halt noch nie aufgefallen daß nach nem
Power-Cycle noch irgendwelche Breakpoints aktiv waren oder daß der
J-Link sonst jemals was mit dem Controller gemacht hätte was nicht durch
Aus/Einschalten wieder weggegangen wäre.
Ich werd das aber sobald ich wieder an meinem Arbeitsplatz sitze gleich
mal explizit testen: Mehr Breakpoints setzen als die CPU kann, dann hart
abstöpseln, Debugger beenden, anstöpseln und das komplette Flash
auslesen und vergleichen.
Bernd K. schrieb:> Ich kann aber mitten im Debuggen den Spannung ausschalten und den> Debugger abstöpseln, nach einem Neustart läuft das Binary auf dem> Cotroller ohne jede Beeinträchtigung.
Das überrascht mich, denn ich habe auf der Seite von ARM selbst gelesen,
dass genau hier ein wesentlicher Nachteil der Soft-Breakpoint läge: Man
könnte vergessen, die Breakpoints zu entfernen.
OK, ihr habt recht.
Manchmal(!) patcht er das Flash. Aber nicht immer, und auch nicht immer
sofort wenn ich den Breakpoint setze sondern irgendwann beim
Durchsteppen! Und ich sehe ständig Meldungen durchrauschen daß er auch
Breakpoints entfernt wenn ich von Breakpoint zu Breakpoint springe.
Im obigen Fall habe ich laut IDE insgesamt 21 Breakpoints gesetzt aber
er hat nur an 3 Stellen ein bkpt #0 eingefügt.
@Bernd
Ab und zu brauchts eben mal eine Gegenprobe um die Theorie zu bestätigen
;)
Demnächst wirds für mich auch ernst einen GDB Server zu proggen, der den
MIPS TTL Rechner debuggen kann.
Für den eigenbau MIPS Emulator mit der Emulation der MIPS TTL Rechner
Peripherie gibts ja schon einen GDB Server.
Aber der hat natürlich unendlich "Hardware" Breakpoints.
Da der MIPS1 Befehlssatz bereits einen break Befehl hat wird der auch
genutzt.
Ich weis nur noch nicht ob ich den Befehl dann simuliere oder das break
ersetze gegen den Original Befehl und drauf springe.
(Der MUL/DIV Befehl ist da doch eher speziell)
Am FPGA Nachbau läuft zumindest schonmal das CPU Anhalten und der
Singlestep Betrieb mit dem Auslesen aller wichtigen Register.
Was nur etwas nervt ist, dass der GDB immer alle Breakpoints gelöscht
haben will, weil die Verbindung könnte abbrechen.
Da würde ich gerne mal wissen wie der Jlink damit umgeht (es gibt ja nen
GDB Server fürn JLink).
Immer alle Breakpoints ausm Flash löschen tut er ja nicht wenn die CPU
angehalten wurde.
Warscheinlich eine kleine "Heuristik":
Wenn breakpoint erwischt und CPU gestoppt und dann mehrere Breakpoints
auf einmal gelöscht werden sollen, dann diese gesetzt lassen.
Erst wenn beim weiterlaufen ein Breakpoint fehlt, dann wirklich löschen
oder wenn nur einer gelöscht werden soll.
? Ich habe keine Ahnung, aber so würd ichs wohl machen.
Im weiteren Verlauf muss der GDB Server Eigenbau dann auch noch OS aware
werden, aua. (eigenbau OS)
Hallo,
der J-Link ist an das Limit des Controller gebunden, was echte
Breakpoints angeht. Alle darüber hinaus platzierten Breakpoints macht
er, indem er den Befehl an der Stelle durch einen Breakpoint-Befehl
ersetz. Kommt der Prozesseor nun an diese Stelle wird der Breakpoint
getriggert.
Beim Fortfahren, emuliert dann der Segger den eigentlichen Befehl, der
an dieser Stelle stehen sollte nach und lässt den Prozessor
weiterlaufen.
Stefanus F. schrieb:> Das klingt für mich sehr überraschend. Ist es wirklich so?
Ja. Es gibt schlicht keine andere Möglichkeit. Der J-Link flasht ja
nicht nach jedem breakpoint wieder den befehl rein, führt ihn aus und
flasht wieder einen Breakpoint drüber. Das Emulieren ist auch kein
großes Hexenwerk bei einem RISC Prozessor; der J-Link hat ja auch
Zugriff auf alles und der Befehlssatz ist kein Problem.
Herausfinden kann man das, indem man einfach ganz viele Breakpoints
platziert und danach den Flash ausliest und disassembliert. Da sind dann
an den entsprechenden stellen Breakpoint-Befehle.
Das Ganze hat den Nachteil, dass der Controller ohne den Debugger nicht
mehr selbstständig läuft, da er stehen bleibt, sobald der Breakpoint
ausgelöst wird und diese Breakpoints sich logischerweise auch durch
Resets nicht löschen. Deshalb sollte man, wenn man den Controller
einfach so laufen lassen will darauf achten, dass keine Breakpoints mehr
gesetzt sind.