Hallo Ich programmiere zur Zeit gerade einen Atmega2561 Controller. Jetzt wollte ich mich mal erkundigen, ob es möglich ist diesen life zu debuggen? Also, dass man das Programm Schritt für Schritt durchlaufen kann? Google hat mir da leider nicht recht weiterhelfen können. Vielen Dank! Gruss
Moin! Ja, den ATmega2561 kann man debuggen. Geht z.B. mit dem JTAGICE Mk II. Gruß, Thorsten
Sind das einfach Plug and Play Bausteine, die man zwischen die serielle Verbindung hängt? Oder muss man da noch rumprogrammieren oder sogar den Kontroller ausbauen, damit der debugger läuft?
Es sind über JTAG anzubindende Debug-Adapter, die der Debugger auf dem Host auch benutzen können muss. Aber es handelt sich um in- system-debugging.
also mal ander gefragt, ist es für einen laien, der noch nie etwas von JTAG oder dergelichen gehört hat, theoretisch möglich dieses gerät am controller anzuschliessen und zu benutzen?
Es ist immer nützlich, das Laien-Stadium durch Aufschlauen zu verlassen. Wenn Du den Link hinter JTAG anklickst, kommt der hiesige Artikel zum Thema hervor, der sich auch mit AVRs befaßt. Und einen Überblick kann man sich auch bei [1] verschaffen. Meine kurzes gurgeln mit AVR und JTAG brachte 278000 Treffer hervor, bei denen die ersten durchaus vielversprechend aussahen. Zudem ist das Thema hier im Forum auch schon das eine oder andere Mal dran gewesen; ein kleiner Spaziergang hier lohnt also auch. Grüße, Jan. [1] http://de.wikipedia.org/wiki/JTAG
Du musst nicht wissen, wie JTAG funktioniert, aber du solltest eine Vorstellung davon haben, wie man eine "embedded"-Applikation debugt. Das geht nicht 1:1 so wie auf einem PC, da du sehr viel mehr von der Umgebung des Controllers abhängst (Echtzeitforderungen, Reaktion auf das, was an den Controller angeschlossen ist etc. pp.). Außerdem bietet ein AVR dem Compiler sehr viel mehr Potenzial zur Optimierung des compilierten Codes als ein i386 (& Co.), was zur Folge hat, dass der generierte Assemblercode alles andere als eine irgendwie lineare Abbildung des C-Codes ist. Der Compiler generiert funktionskompatiblen Code, aber wenn man den versucht, in Einzel- schritten abzuarbeiten, hüpft der Befehlszähler scheinbar wild hin und her. (Ähnliche Effekte hat man auch bei "großen" Computern, die mit einem RISC-Prozessor arbeiten.)
>Der Compiler generiert funktionskompatiblen Code, aber wenn man den versucht, in >Einzelschritten abzuarbeiten, hüpft der Befehlszähler scheinbar wild hin und her. Aber wenn ich meinen normal geschriebenen Code debuggen möchte, dann sollte dies mit den Einzelschritten schon funktionieren oder?
Buell24 schrieb: > Aber wenn ich meinen normal geschriebenen Code debuggen möchte, dann > sollte dies mit den Einzelschritten schon funktionieren oder? Nein. "Normal geschriebener Code" wird hemmungslos optimiert, und genau das willst du ja am Ende auch haben. Ein Beispiel, das ich gerade gefunden habe: eine Arbeits-Funktion wird aus zwei ISRs benötigt, wobei jeweils nur die Adressen zweier verschiedener Strukturen übergeben werden, je nachdem, welcher der beiden Interrupts eintraf. Der Compiler hat sich entschlossen, die Arbeitsfunktion inline zweimal zu implementieren, da das nach den Optimierungs- vorgaben den besseren (schnelleren bzw. kleineren) Code ergab. Wenn man nun im Debugger einen Breakpoint auf die eigentliche Funktion setzen will, dann kann der das nicht, weil er dafür keine Implementierung findet. Der Compiler eliminiert auch gern Zwischenvariablen, sodass du deren Zuweisungen nicht im Code in einer Form wiederfindest, die man schrittweise abarbeiten kann. Gemeinsame Teilausdrücke werden zusammengefasst, auch das ist schwer in einem Debugger zu verfolgen. Es ist besser, wenn man den Code erstmal in großen Schritten abarbeitet und dabei versucht, das Problem einzukreisen. Man lernt im Laufe der Zeit auch ein paar Tricks, wie man während des Debuggens zusätzliche Dinge einbauen kann, um mit dem Debugger etwas mehr "Einblick ins Geschehen" zu erhalten, weil der Compiler dort nichts optimieren kann. Beispielsweise kann man sich Zwischenergebnisse in als "volatile" markierte Variablen reinlegen lassen, oder wenn man an einer bestimmten Stelle ein Statement haben möchte, das garantiert auch Code erzeugt, kann man sowas wie
1 | asm volatile("nop"); |
einbauen. Auf eine solche Anweisung lässt sich immer ein Breakpoint setzen, genau wie auf sowas wie
1 | PORTB = 42; |
Letzteres kann man auch benutzen, um ein Triggersignal für einen Logikanalysator oder sowas zu erzeugen. Diese kleinen Debughilfen machen den Code natürlich schlechter (wirken also der Optimierung entgegen), aber sie ändern insgesamt sehr viel weniger, als wenn man gleich ganz ohne Optimierungen arbeitet, nur damit man hübsch debuggen kann. Nachdem man das entsprechende Teilstück debuggt hat, fliegen diese Hilfsmittel natürlich wieder raus. Wie gesagt, die Vorgehensweise, um eine Applikation auf einem Controller zu debuggen, unterscheidet sich zuweilen heftig von dem, wie man auf einem PC debuggen würde, selbst dann, wenn man (wie mit dem JTAG ICE) "in den Controller hinein sehen" kann.
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.