Hallo Ich würde gerne die im GDB verfügbaren Kommandos und deren Syntax wissen. Eventuell kann damit dann das Wiki erweitert werden. Ich habe einen mega32 und einen AVR Dragon welche per JTAG verbunden sind. Auf Softwareseite wird avarice 2.7 und avr-gdb 6.7.1 unter Linux verwendet. Mit google habe ich bereits folgende Kommandos in Erfahrung gebracht: Ausführung starten/fortsetzen: continue breakpoints setzen: break symbol bzw break *adresse watchpoints setzen: watch symbol bzw watch *adresse break/watchpoints anzeigen: info breakpoints break/watchpoints löschen: delete breakpoints [x] daten im stack betrachten info frame [x] und backtrace Mit diesen Kommandos kommt man bestimmt schon sehr weit. Jedoch fehlt mir noch etwas. Im Datenblatt zum mega32 wird unter "Using the On-chip Debug System" ein "Break Point with mask(“range Break Point”)" erwähnt. Wenn ich den Sourcecode von avarice richtig interpretiere kann zu einem Watchpoint eine länge übergeben werden. Jedoch hab ich keine ahnung wie ich das im gdb eingeben muss. Google und die hilfe des gdbs haben mir bisher leider keine Antwort geliefert. Gruß Florian
Danke für den tollen Link. Das Pdf werd ich mir sofort ausdrucken. Jedoch steht da nichts zum "range Break Point" Oder ist das mit dem gdb nicht möglich? Gruß Florian
Florian wrote: > Jedoch steht da nichts zum "range Break Point" > Oder ist das mit dem gdb nicht möglich? Der GDB nennt das einen watchpoint. Der range breakpoint, den manche ICEs beherrschen, ist eine sehr stark eingeschränkte Version eines watchpoints, bei der man eine Basisadresse und eine Bitmaske angibt, wobei die Basisadresse alle Maskenbits 0 hat. Der Watchpoint des GDB orientiert sich stärker an den Belangen der Hochsprache, indem die Intention ist, dass man ihn auf eine bestimmte Variable ansetzt, die man überwachen will (egal, wie groß sie ist). Daraus entsteht natür- lich das Dilemma, dass nicht alle möglichen Watchpoints in der Hardware des ICE abgebildet werden können. Die anderen kann der GDB zwar trotzdem noch über eine Emulation benutzen, aber sowas will man schon auf einem schnellen PC nicht wirklich haben, auf einem Controller mit einem ICE dazu würde das Debuggen damit wahrscheinlich Wochen in Anspruch nehmen. Man kann aber GDB-typisch ja völlig beliebige Ausdrücke für den Watchpoint angeben und auf diese Weise auch einen Datentyp der entsprechenden Größe per typecast auf die gewünschte Adresse ansetzen.
> Ich würde gerne die im GDB verfügbaren Kommandos und deren Syntax > wissen. Schon mal in GDB selbst "help" versucht?
@Rolf Magnus: Entweder ist mein Englisch so verdammt schlecht, oder mit der Hilfe im gdb lässt sich meine Frage nicht beantworten. ;-) @Jörg Wunsch: Danke das hat mir für das Verständnis der Funktionsweise sehr geholfen. Jedoch weiß ich immernoch nicht wie ich das genau eingeben soll/kann. Wie würde der Befehl aussehen, um einen "range watchpoint" auf 4 byte im Sram ab adresse 0x60 zu setzen? watch (*4*sizeof(char))0x800060 könnte das so klappen? Kann das erst morgen testen, da die Hardware in der Firma ist.
watch *(uint32_t *)0x800060 würde ich mal aus dem Hut sagen. Kann's auch gerade nicht testen.
Das scheint so nicht zu funktionieren. Mit
1 | watch uart_tx_buffer |
wird nur ein Software Watchpoint gesetzt der sehr sehr langsam ist. Mit
1 | watch *uart_tx_buffer |
bzw
1 | watch uart_tx_buffer[0] |
kann ich einen Hardware watchpoint auf den buffer setzen. Jedoch reagiert er nur, wenn sich das 0. Element ändert. Durch einsetzen von (uint32_t) oder (uint32_t*) ändert sich nur, wie gdb den Inhalt von uart_tx_buffer[0] darstellt. Wenn uart_tx_buffer im Sram ab adresse 0x9e liegt dann sollte mit
1 | watch *0x80009e |
doch das selbe Ergebnis herauskommen? Das Klappt aber nicht. Laut debug output von avarice wird der watchpoint zwar gesetzt aber es passiert nichts und das Programm läuft. Breche ich dann das Programm ab meckert gdb, dass der watchpüoint nicht entfernt werden konnte. Hier die Ausgbabe von avarice.
1 | ... |
2 | GDB: <Z2,80009e,2> |
3 | BP ADD type: 3 addr: 0x80009e BP ADD type: 6 addr: 0xfffffffe Slot 0 full |
4 | Slot 0 full |
5 | range BP ADDED: 0x80009e/0xfffffffe |
6 | Slot 0 full |
7 | Slot 0 full |
8 | ->GDB: OK |
9 | GDB: <vCont?> |
10 | ->GDB: |
11 | GDB: <Hc0> |
12 | ->GDB: |
13 | GDB: <c> |
14 | Slot 0 full |
15 | Slot 0 full |
16 | Breakpoint added in ICE. slot: 2 type: -2147483645 addr: 0xfffffffe |
17 | ... |
18 | Breakpoint added in ICE. slot: 3 type: 6 addr: 0xfffffffe |
19 | ... |
20 | ->GDB: T0220:82;21:5508;22:9c000000; |
21 | GDB: <z2,80009e,2> |
22 | BP DEL type: 3 addr: 0x80009e FAILED |
23 | ->GDB: E01 |
24 | ... |
Florian wrote: > Durch einsetzen von (uint32_t) oder (uint32_t*) ändert sich nur, wie > gdb den Inhalt von uart_tx_buffer[0] darstellt. watch *(uint32_t *)uart_tx_buffer Wird aber nicht funktionieren, weil das ICE das nicht kann: > Wenn uart_tx_buffer im Sram ab adresse 0x9e liegt dann sollte > mit watch *0x80009e 0x9e kann man nämlich bestenfalls mit einer Maske von 0x01 (also als uint16_t) zu einem range breakpoint erweitern, mehr geht nicht. Das ist das Dilemma der einfachen Implementierung im ICE als Offset + Maske: der AVR selbst benötigt ja kein Alignment für seine Daten (sodass der Compiler auch keins benutzt), aber die range breakpoints benötigen Daten, die sauber ausgerichtet sind, sonst kann man sie nicht benutzen, da die Objektgrenze über einen darstellbaren range hinaus geht.
Hallo Die Einschränkungen der range breakpoints auf seiten des Controllers sind mir klar. Der breakpoint kann immer nur 2 hoch x byte anschauen wobei das x durch die Maske bestimmt wird. Die Einschränkungen des avarice noch nicht ganz. Durch einen Blick in die sourcen weiß ich: range bp nur im sram (address & mask) muss 0 sein Ich verstehe aber immer noch nicht wie ich das in den gdb eingeben muss. Laut avarice debug Ausgaben sind diese breakpoints identisch
1 | watch *(uint32_t)0x80009c |
2 | watch *0x8009c |
1 | range BP ADDED: 0x80009c/0xfffffffe |
bei uint32_t hätte ich aber 0xfffffffc als Maske erwartet Gruß Florian PS: in jtag2bp.cc scheint in Zeile 287 ein Tippfehler zu sein. Oder soll da eine Zuweisung im if sein?
Florian wrote: > Ich verstehe aber immer noch nicht wie ich das in den gdb eingeben muss. > Laut avarice debug Ausgaben sind diese breakpoints identisch > watch *(uint32_t)0x80009c Ich meinte auch *(uint32_t *)0x80009c Aber: jetzt sitze ich selbst vorm GDB, und er kann in der Tat offenbar nicht mehr als 16 bits auf einmal in einen hardware watchpoint nehmen. Er fragt auch gar nicht erst das AVaRICE, an diesem kann es also nicht liegen. Nun habe ich mich mal durch den GDB-Code gehangelt, und es sieht mir so aus, als hätte niemand da je eine Anpassung für den AVR geschrieben. Damit fällt das Ganze letztlich zurück auf das hier (in target.c):
1 | static int |
2 | default_region_size_ok_for_hw_watchpoint (int byte_count) |
3 | {
|
4 | return (byte_count <= TYPE_LENGTH (builtin_type_void_data_ptr)); |
5 | }
|
Damit ist klar, warum man nur 1- oder 2-Byte-Bereiche als Hardware-Watchpoint aktiviert bekommt. :-/ Da außerdem das default-Scenario nur die Länge, nicht aber die Adresse des watchpoints betrachtet, genügt das für den AVR und das JTAG ICE ohnehin nicht. Es gibt aber einen Makro TARGET_REGION_OK_FOR_HW_WATCHPOINT, den man offensichtlich irgendwie unter gdb/config/avr/nm-avr(?).h setzen kann um anzuzeigen, was man tatsächlich als hardware watchpoint unterstützen kann. Das könnte man sich ja mal ansehen... > in jtag2bp.cc scheint in Zeile 287 ein Tippfehler zu sein. > Oder soll da eine Zuweisung im if sein? Wo du Recht hast, hast du Recht. OK, danke sehr, ist repariert.
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.