Forum: Mikrocontroller und Digitale Elektronik Erfolgreich AVR Dragon + AVARICE + GDB verwendet unter Linux


von Gerhard G. (gergap)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

ich habe heute (mehr oder weniger) erfolgreich meinen AVR Dragon unter 
Linux in Betrieb genommen, und weil das nicht ganz einfach ist wollte 
ich meine Erfahrung hier mit euch teilen.

Hintergrund: Ich verwende seit einigen Jahren den USBasp Programmer mit 
avrdude um meine Programme zu flashen. Bauen tue ich das mit einfachen 
Makefiles. Kompilieren und flashen geht dann einfach mit "make" bzw. 
"make upload". Das geht auch aus Vim, KDevelop, oder <any other IDE>.

Das einzige was mir immer gefehlt hat war eine vernünftige 
Debug-Möglichkeit mit USBasp. Darum habe ich mir jetzt den AVR-Dragon 
zugelegt.

Siehe http://www.atmel.com/tools/avrdragon.aspx
Im wesentlichen ist das ein ICE mit JTAG Unterstützung, aber viel 
wichtiger für mich ist, dass er DebugWire unterstützt. Ich verwende 
nämlich hauptsächlich kleine ATMEGA8/168/328 o.ä. Diese unterstützen 
kein JTAG, aber dafür DebugWire. Bis auf den Atmega8, der kann nicht mal 
DebugWire. Siehe https://www.mikrocontroller.net/articles/DebugWIRE

Jetzt aber zur Verwendung:
Ich erkläre jetzt nicht wie man avr-gcc/gdb usw installiert, das setzte 
ich mal voraus (oder siehe hier: https://gergap.wordpress.com/tag/avr/)

Man muss die folgenden Tools installiert haben:
* avr toolchain: avr-gcc, avr-gdb, avrdude, GNU make
* avarice (gdbserver der mit dem Dragon kommuniziert)
* (optional) GDB Debugger Frontend wie cgdb, kdevelop, etc.

Eines der größten Probleme ist die Verkabelung. Der AVR-Dragon bietet 
hier sehr viele Möglichkeiten, die aber nicht besonders gut dokumentiert 
sind. Man findet alles, aber muss entsprechend suchen.
Die beste Übersicht, neben der offiziellen Doku ist diese Seite: 
http://www.trimension.de/wiki/AVR-Dragon

Der Dragon bietet die Möglichkeit einen Test-Sockel aufzulöten. Dies 
bietet die Möglichkeit einfach die µC auf den Sockel zu stecken, zu 
flashen und zu debuggen. Das Debuggen macht ohne Peripherie natürlich 
nur beschränkt Sinn.
Leider muss man sich um die Verdrahtung selber kümmern. Wer keinen Bock 
darauf hat mit Jump-Wires rum zu frickeln bastelt sich am besten eine 
Adapter-Platine, welche man auf die Stiftleisten aufstecken kann und so 
die Verdrahtung vornimmt. So kann man durch Wechsel der Adapter den 
Dragon umkonfigurieren.

In-System-Programing (ISP): Die meiner Meinung nach sinnvollsten 
Methode.
Der Dragon bietet dazu schon einen 6-poligen ISP Pfostenstecker.
Stolperfalle 1: der ISP kann die Platine mit dem µC nicht mit Spannung 
versorgen (das ist bei echter HW oft auch nicht gewünscht). Aber für das 
Steckbrett wäre das hilfreich. Hierfür gibt es auf dem Dragon einen 
zweiten 6 poligen Stecker mit VCC und GND. Man kann so das Board mit 
einer separaten Verkabelung mit Strom versorgen. Ich habe mir allerdings 
einfach mittels LM7805 eine Spgsversorgung auf das Steckbrett gebaut. 
Über den ISP bekommt der Dragon das Spannungs-Niveau und passt sich 
entsprechend an (Pegelwandler).

Problem 2) da ich auf dem Steckbrett meinen Adapter 10-poligen 
ISP-Stecker verwende, der zu meinem USBasp passt, habe ich mir ein 
ISP-Adapter-Kabel bestellt, welches von 6-polig auf 10-polig geht.
Leider hat das nicht geklappt. Nachdem ich schon Angst hatte durch das 
rum probieren den Dragon geschrottet zu haben, habe ich doch mal das 
Kabel durchgemessen. Wie sich raus gestellt hat ist das totaler 
Nonesense.
Jetzt habe ich zum Testen eine recht wilde Vedrahtung mit 6 poligen 
Kabel und Schaltdrähten vorgenommen. Und siehe da es funktioniert, wenn 
auch nicht zuverlässig.
Merke: Nächstes mal das Kabel selber machen!

avrdude: Das gute alte Tool zum Flashen wollte ich jetzt auch mit dem 
Dragon testen, bevor ich DebugWire aktiviere.
Im Prinzip bekommt man so ein Verbindung zu einem Atmega168:
1
avrdude -v -v -p atmega168 -c dragon_isp -P usb
Da durch die wilde Verkabelung das etwas wackelig ging, habe ich die 
Geschwindigkeit (Bitclock) gedrosselt von 1 µs (default) auf 10µs. Damit 
klappt es bei mir wunderbar.
1
avrdude -v -v -p atmega168 -c dragon_isp -P usb -B 10
So bekommt man beispielweise ein Programm auf den Chip:
1
avrdude -v -v -p atmega168 -c dragon_isp -P usb -B 10 -e -U flash:w:tempctrl.hex:i

Will man DebugWire aktivieren muss man DWEN fuse aktivieren. Die Seite
http://www.engbedded.com/fusecalc/ sei für Fuse Einstellungen jedem ans 
Herz gelegt, und das Datenblatt natürlich ;-)
Achtung: Ist DebugWire aktiv, funktioniert die Reset-Leitung nicht mehr, 
da diese für DebugWire verwendet wird. Normaler ISP-Betrieb wie mit 
USBasp geht dann nicht mehr. Über ein spezielles DebugWire Kommando kann 
der ISP Mode temporär wieder aktiviert werden (bis zum nächsten Reset). 
Um das dauerhaft wiederherzustellen muss DWEN wieder deaktiviert werden.
Zum Glück kann das alles avrdude, also keine Angst.

Ich habe mir hierfür folgende zwei Scripte angelegt:
Das ist natürlich nur ein Beispiel und muss an eigene Bedürfnisse 
angepasst werden.

enable_debugwire:
1
#!/bin/sh
2
avrdude -v -v -p atmega168 -c dragon_isp -P usb -B 10 -U hfuse:w:0x9f:m

disable_debugwire:
1
#!/bin/sh
2
avrdude -v -v -p atmega168 -c dragon_isp -P usb -B 10 -U hfuse:w:0xdf:m

Debuggen: Jetzt gehts endlich los.
Nachdem man DWEN aktiviert hat, kann man avarice starten.
Den Prozesser sollte man zuvor allerdings erst mal resetten.

Hier nochmal der Überblick über die Funktionsweise:
1
µC <--debugWire--> Dragon <--USB--> avarice <--TCP socket--> avr-gdb --- gdb-frontend (optional)

avarice starten:
1
$> avarice -g -w :4242
2
AVaRICE version 2.13, Apr 12 2015 13:50:38
3
4
JTAG config starting.
5
Found a device: AVRDRAGON
6
Serial number:  00:a2:00:06:24:72
7
Reported debugWire device ID: 0x9406
8
Configured for device ID: 0x9406 atmega168
9
JTAG config complete.
10
Preparing the target device for On Chip Debugging.
11
Waiting for connection on port 4242.
12
Connection opened by host 127.0.0.1, port 46828.

Erklärung der Optionen:
-g     : Dragon verwenden
-w     : DebugWire verwenden
 :4242 : die fehlende IP (localhost) getrennt vom Port 4242, welcher vom 
avarice GDB-Server verwendet wird. Hier wartet avarice auf eingehende 
Verbindungen vom GDB.

jetzt kann man sich schon mit dem GDB verbinden:
1
$> avr-gdb tempctrl.elf
2
target remote :4242
3
break main
4
c

Jetzt sollte man Anfang seines Programmes stehen.

Erklärung:
target remote :4242: Stellt die Verbindung zum avarice her
break main: setzt einen breackpoint in der Funktion main()
c: kurz für continue. Lässt den ICE los laufen bis er auf einen 
Breakpoint läuft.

Was man noch wissen sollte. DebugWire unterstützt keine HW-Breakpoints. 
D.h. beim Setzen eines Breakpoints wird eine Break-Anweisung im Code 
eingefügt, d.h. das Flash wird modifiziert. Das kann die Lebensdauer des 
Flashes negative beinträchtigen.
Das Steppen mit 'step' und 'next' geht sehr zäh. Im Endeffekt wird für 
jeden Schritt ein impliziter Breakpoint gesetzt und wieder entfernt.
Sinnvoller ist es auf dem kleinen µC selber Breakpoints zu setzen und 
mit 'continue' dort hinzulaufen.
Watchpoints werden von der HW ebenfalls nicht unterstützt.
Das inspizieren von Variablen und Registern mit 'print', 'display' und 
'info' geht einwandfrei.

CGDB-Frontend: Mein liebstes Frontend für solche Low-Level Dinge.
Es zeigt den Quellcode, breakpoints und Ausführungsposition schön an.
Man bedient es einfach mit normalen GDB Kommandos, d.h. geht der GDB 
geht auch CGDB. Keine von GUIs verursachten Probleme.

Man legt sich hierzu eine kleine Hilfsdatei an um sich Tipp-Arbeit zu 
sparen:
1
# load symbols from ELF file (needed for DDD)
2
file tempctrl.elf
3
# connect to GDB server
4
target remote localhost:4242
5
# run to main (optional)
6
break main
7
c

Dann startet man CGDB folgendermaßen:
1
cgdb -d /usr/bin/avr-gdb tempctrl.elf -x gdb.conf

DDD: Leider klappt es damit nicht. Sobald ich mich damit verbinde crasht 
avarice. Irgendwas macht DDD, was avarice nicht gefällt.
Im Prinzip ginge es aber so:
1
ddd --debugger "avr-gdb -x gdb.conf"

KDevelop: Funktioniert auch. Hier muss man halt in der GUI rum klickern 
um alles einzustellen. Es lässt sich im Debug Lauchner unter Debugger in 
der Sektion "Remote Debugging" auch das gdb.conf Script wiederverwenden. 
Die Textbox heißt "Run gdb Script:"

Was gibt es noch zu beachten?
1.) Natürlich sollte man mit "-O0 -g" bauen. Die Optimierung erzeugt 
schwer nachvollziehbaren Code. Man sollte höchstens O1 verwenden. -g 
erzeugt die Debug Info.
2.) Der Debugger will das ELF file mit der Debug Info. Mit dem HEX file, 
welches man zum Flashen verwendet kann der Debugger nix anfangen.


Ich hoffe ich konnte mit dem Beitrag jemanden helfen.

PS: Was mich noch interessieren würde: Mit AVR Studio unter Windows und 
AVR Dragon. Geht dort das Steppen auf einem m168 besser, oder genauso 
zäh? Das Modifizieren des Flash dauert seine Zeit, deswegen würde mich 
das wundern. Bei mir dauert ein Step so etwa 2-3 Sekunden.

von schwerer Weg (Gast)


Lesenswert?

Und was willst du uns damit sagen?
Nimm was modernes, was Anständiges und gut isses. Läuft unter Win, unter 
Linux, unter...

von Mike (Gast)


Lesenswert?

Vielen Dank für deine Mühe und die umfangreiche Beschreibung.

Nun habe ich endlich mal einen Überblick darüber, wie das Debuggen in 
Linux generell abläuft und welche Tools ich benötige. Ich werde das 
Ganze mal mit dem JTAGICE MKII versuchen.

Mit Gruß

Mike

von Gerhard G. (gergap)


Lesenswert?

Freut mich, dass es jemanden geholfen hat.

Ich habe mittlerweile übrigens eine anständige Platine geätzt mit dem 
richtigen 6-poligen Pfostenstecker. Damit geht das jetzt auch ohne das 
"-B10" mit normaler Geschwindigkeit ;-)

Gruß,
Gerhard

von zufall (Gast)


Lesenswert?

Auch von mir danke, für diese sehr umfangreiche Beschreibung. Ich wollte 
ebenfalls bald anfangen AVR-Controller unter Linux zu programmieren. Das 
Debuggen hatte mich aber schon etwas nervös gemacht. Dank dir wird es 
jetzt einfacher werden

von Roland (Gast)


Lesenswert?

Hallo Gerhard
Vielen Dank für deine ausführliche Erklärung.
Damit war ich in der Lage meinen AVR zu debuggen.

von Gerhard (Gast)


Lesenswert?

Sehr schön, so war es gedacht.
So viel zu dem Kommentar oben "Und was willst du uns damit sagen?" ;-)

von Marc S. (marc_s86)


Lesenswert?

Gerhard schrieb:
> Sehr schön, so war es gedacht.
> So viel zu dem Kommentar oben "Und was willst du uns damit sagen?" ;-)

Überlese das einfach. ich werde das demnächst auch mal alles 
nachvollziehen, das macht dann nämlich meine windows installation 
überflüssig :)

von Gerhard G. (gergap)


Angehängte Dateien:

Lesenswert?

Hallo,

hier noch ein Nachtrag und Infos darüber wie man einen AVRDragon retten 
kann, wenn das AVR Studio das vermurkst hat...

Nachdem ich beim Schreiben des obigen Artikels noch einige Probleme 
hatte mit meiner Freiluftverdrahtung und die Übertragungsgeschwindigkeit 
reduzieren musste, wollte ich wissen ob das mit der Originalsoftware 
nicht besser geht. (Übrigens geht es mit der fertigen Platine auch mit 
Fullspeed,
und ich konnte sogar die Defaults noch etwas erhöhen.)

Also habe ich Windows installiert in einer VM, und dann das AVR Studio 
drauf. Mit Entsetzen habe ich festgestellt, dass dies mittlerweile auf 
Visual Studio aufesetzt und auch noch .Net benötigt. Also rießengroß und 
saulangsam.
Irgendwann nach Stunden des Downloads und Installationsorgie lief es 
dann und ich versuchte den ersten Debug-Vorgang.
Leider wollte das AVRStudio nun unbedingt die Firmware des Dragon 
updaten, also machte ich das. BOOM, der Update-Vorgang ist eingefroren, 
AVR Studio war unbedienbar so dass nur noch der Task Manager half. 
(Genau wegen dem Mist habe ich vor Jahren schon Windows abgeschworen und 
bin mit Linux glücklich).
Der Dragon war erst mal Schrott und kommunizierte von da an auch nicht 
mehr mit avrdude oder avarice. Ein erneutes Firmwareupdate ging auch 
nicht mehr.
Man hab ich das bereut überhaupt wieder Stunden mit dieser MS Sch.... zu 
vergeuden.


Nach ziemlich langer Suche bin ich dann auf eine Lösung gestoßen. Ein 
undokumentiertes Feature erlaubt es nämlich doch wieder eine Firmware 
einzuspielen. Dazu müssen zwei Kontakte überbrückt werden wenn das USB 
Kabel eingesteckt wird (power up). Zuvor muss natürlich alles 
ausgesteckt werden, damit der Dragon stromlos ist.
Das ist ein ziemliches Gefummel die Kontakte zu überbrücken und 
gleichzeitig das USB Kabel einzustecken, aber es hat funktioniert.
Siehe Bild für die Kontakte.
Quelle:
http://www.avrfreaks.net/forum/firmware-upgrade-killed-dragon

Nachdem der Dragon wieder Heile war hat es auch mit dem AVRStudio 
geklappt. Das Ergebnis war ernüchternd. Alles genauso lahm wie mit 
avarice. Ich sehe da keine Vorteile, also habe ich die VM wieder 
gelöscht und verbuche die vergeudete Zeit unter Erfahrung.

Die kleinen ATMEGAs sind halt etwas bescheiden zu debuggen über 
DebugWire. Die Tinys können das gar nicht. Größere Chips mit JTAG sind 
da schon bequemer, aber zum Glück muss ich zumindest eher selten 
Debuggen, und bei meinen kleinen Progrämmchen reicht oft eine Debug-LED, 
oder ein Oszi...

von bernd (Gast)


Lesenswert?

Danke für die Anleitung!

Meine Stolperfallen waren: Versehentlich manchmal gdb statt avr-gdb zu 
verwenden, leider zetert da nichts, es fällt nur an komischen Fehlern 
auf.
Powercycle nach dem Anschalten von DebugWire zu vergessen.

Lässt sich der Reset irgendwie per ISP oder sonst wie machen?

Zum Ausschalten von Debugwire: Es reicht einfach avrdude zu starten, der 
versucht zuerst ISP und bei Fehlschlag danach DebugWire um dort ISP zu 
starten.  Und anscheinend löscht er auch ungefragt das DWEN Bit.

Alternativ kann man auch über DebugWire programmieren: -c dragon_dw

von Gerhard G. (gergap)


Lesenswert?

bernd schrieb:
> Lässt sich der Reset irgendwie per ISP oder sonst wie machen?

Nicht wen debugwire aktiv ist, da hierfür ja die Resetleitung verwendet 
wird.

Dafür müsste man schon was basteln und die Software dafür patchen:
Man könnte z.b. ein USB-Adapter bauen, bei dem sich die Power an das 
Gerät per Rechner an/abschalten lässt. Sowas hätte ich schon öfter 
gebraucht für Resets in autom. Buildsystemen. Mangels Zeit aber noch nie 
realisiert.

So eine HW vorausgesetzt liesse sich avrdude natürlich leicht dafür 
anpassen.
Ich denke aber nicht das sich das hierfür lohnt. Aber für Leute auf der 
Suche nach Bastel-Ideen wäre das natürlich was.

Übrigens, eine ähnliche Idee habe ich mal bei Elektor gesehen, 
allerdings mit manuellem Schalter. 
https://www.elektor.de/310-schaltungen
Ich würde das wie gesagt über USB selber steuerbar machen. Entweder mit 
einem eigenen USB tauglichen µC wie IO-Warrior oder einfach mit einem 
AVR und V-USB.

von TM F. (p_richner)


Lesenswert?

Hallo

Ich benutze auch den Dragon, jedoch mit avarice.
Weil in diesem Thread über den Dragon berichtet wird, möchte ich ein 
wenig ergänzen:)

Programmieren mit avarice:
1
avarice --dragon --debugwire --erase --program --file ${TARGET_OUTPUT_DIR}${TARGET_OUTPUT_BASENAME}.hex

Debuggen mit avarice:
1
avarice --dragon --jtag usb localhost:4242 --debugwire

Ich benutze die Tools in CodeBlocks und danach kann man den CodeBlocks 
Debugger starten und alles funktioniert wunderbar.

MfG

von Stefan F. (Gast)


Lesenswert?

Tolle Anleitung, das werde ich mal ausprobieren.

> Was mich noch interessieren würde: Mit AVR Studio unter Windows
> und AVR Dragon. Geht dort das Steppen auf einem m168 besser, oder
> genauso zäh?

Genau so zäh.

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
Noch kein Account? Hier anmelden.