Kann mir das jemand erklären? Ich weiß, dass die itoa Funktion kein Sinn macht, aber genau da ist das Problem! Wenn der Debugger in dieser Zeile ist, springt er zum folgenden Unterprogramm!:siehe Abbildung 1 Wie kann das sein? Abbildung 1 /*********************************************************************** ***** Function: uart1_puts_p() Purpose: transmit string from program memory to UART1 Input: program memory string to be transmitted Returns: none ************************************************************************ ****/ void uart1_puts_p(const char *progmem_s ) { register char c; while( (c = pgm_read_byte(progmem_s++)) ) uart1_putc(c); }/* uart1_puts_p */ Programm: ISR(TIMER2_OVF_vect) { time++; int h=0; char b[3]; PORTC=time; itoa(h,b,10); if(time==14) time=0; } int main() { DDRC=0xff; uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); uart1_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); timer2_init(); sei(); while(1) { PORTC=time; if(time==5) { uart1_puts("Hello world\r\n"); time=0; } } }
Das ist ein Manko des Debugger Systems. Typisch bei Atmel. Wenn Interrups laufen bringt es das Durchsteppen durcheinander. Du musst handwerklich anders arbeiten. Geht mit der Maus auf die nächste interessante Zeile im Programm und selektiere mit der rechten Maustaste die Option „Run to Cursor“ oder so ähnlich.
Hier hat der Compiler vermutlich das itoa wegoptimiert, da er der Ansicht ist, dass es "sinnlos" ist 1. Variablen welche im ISR und im Hauptprogramm verwendet werden, müssen als "volatile" deklariert sein 2. Debuggen mit eingeschalteter Optimierung (-Os) geht praktisch gar nicht, da der Compiler Befehle umsortiert, Variablen nicht in den Speicher zurück schreibt usw. Schalt mal die Optimierung aus und versuche es nochmal. Gruß Roland
Wichtig ist noch, das KOMPLETTE Projekt dann neu zu compilieren...
Klappt auch nicht! Hab die Optimierung rausgenommen. Hab für h mal volatile int global Deklariert, klappt auch nicht. Und hab mal die itoa Funktion ins Hauptprogramm verschoben, springt trotzdem in die Routine Gruß Tommy
Ne das ist es wohl auch nicht! Selbst nach dem Compilieren springt er in die Routine
Vorausgesetzt ich habe das komplette Projekt compiliert! Ich glaube man kann im AVR Studio nur das ganze Prjekt compilieren. Bzw. AVR Studio compiliert automatisch beim drücken der F7 Taste das ganze Projekt
was steht im Disassembler fenster? Ich hatte mal ein ähnliches Problemm mit printf=> 4 Tage Fehlersuchen Ergebniss: Die frische Version Des GCC war an dieser Stelle fehlerhaft. Neue Version( die meine wurde ja ein paar tage zurückgenommen) drauf und dann ging alles.
Also im AVR-Studio heißt die Option "Build / Rebuild all" Beim drücken der F7 Taste werden nur geänderte Sachen compiliert, d.h. in den ungeänderten sind noch die alten Optimierungseinstellungen drin dass der MK2 in die Interrupts beim single-step springt, scheint normal zu sein und auch (teilweise) logisch (hier hilft nur der "run to cursor trick")
1 | ISR(TIMER2_OVF_vect) |
2 | { time++; |
3 | int h=0; |
4 | char b[3]; |
5 | PORTC=time; |
6 | itoa(h,b,10); |
7 | |
8 | if(time==14) |
9 | time=0; |
10 | } |
Das Problem dürfte hier die Variable "b" sein. b wird im Anschluß nicht mehr verwendet, eine itoa Konvertierung ist deshalb "sinnlos". Hake mal "generate list file" in den Projektoptionen ab und schau dir mal die default\*.lss Datei an, in der stehen alle Zeilen des Programms sowie der entsprechende ASM Code. Fehlt die "itoa"-Zeile wurde sie vermutlich wegoptimiert (was bei -O0 aber AFAIK nicht sein sollte) Gruß Roland
Das heißt also, wenn ich b einfach im Hauptprogramm eine andere Variable zuweise müsste es dann gehen? Vorausgesetzt ich Compiliere alles! Gruß Tommy
Ich kann die default\*.lss Datei nicht finden! Im Order meines Projektes steht sie nicht drin! Habe aber das Häkchen bei generate list file gemacht. Bzw. war schon Gruß Tommy
Habs verstanden,:) du meintest mit default den Namen, den ich der Datei gegeben habe! Hab sie gefunden!
In Zeile 118 hab ich das hier gefunden: 118: 0e 94 17 04 call 0x82e ; 0x82e <itoa>
Mit dem MK2-Debugger kannst auch das Assembler listing debuggen (einfach auf "Disassembler" umschalten) und an entsprechende Stelle einen Breakpoint setzen, evtl hilft dir das weiter. Ich behaupte jetzt mal, dass das Programm so wie es oben steht ja korrekt arbeitet, aber du den Debugger fehlinterpretierst. Evtl solltest du mal genauer dein eigentliches Problem näher beschreiben. Gruß Roland
Anscheinend zeigt der Debugger etwas anderes an, als der MC macht! Kommt der Debugger zur itoa Funktion springt er zur folgenden Routine: Abbildung 1 /*********************************************************************** ***** Function: uart1_puts_p() Purpose: transmit string from program memory to UART1 Input: program memory string to be transmitted Returns: none ************************************************************************ ****/ void uart1_puts_p(const char *progmem_s ) { register char c; while(1) !!habe diese Zeilen hinzugefügt!! {} while( (c = pgm_read_byte(progmem_s++)) ) uart1_putc(c); }/* uart1_puts_p */ Normalerweise müsste sich ja jetzt der MC in einer Endlosschleife befinden! Tut er aber nicht. Er arbeitet ganz normal weiter. Demzufolge, der Debugger zeigt nicht das an, was der MC macht. Ist doch die logische Konsequenz oder? Gruß Tommy
Habe jetzt mal die uart1_init() komplett rausgenommen und die Ausgaben über die uart_puts() Funktion gemacht und trotzdem springt der Debugger in diese Routine, obwohl sie noch nicht mal initialisiert ist. Ich versuche nur den JTAG Debugger zu verstehen! Ich arbeite an einem großen Projekt und will diesen Debugger benutzen. Nur muss ich mir sicher sein, dass der Debugger 100%ig funktioniert sonst suche ich nachher nach Fehlern, die nicht existieren. Gruß Tommy
Hi
>Ich versuche nur den JTAG Debugger zu verstehen!
Also der Debugger arbeitet den von deinem Compiler erzeugten
Assemblercode ab. Und das macht er ,meiner Erfahrung nach, absolut
zuverlässig. Wenn das Verhalten nicht mit deinem C-Programm
übereinstimmt, dann liegt es mit grosser Sicherheit an deinem Programm,
deinen Einstellungen....
MfG Spess
Ich habe nur überhaupt keine Idee woran das liegen kann! Wie kann es sein, dass der Debugger an eine solche Stelle springt? Wie hoch ist denn die Wahrscheinlichkeit, dass es trozdem an der Software liegt? Eigentlich müsste das doch ausgeschlossen sein oder? Insofern müsstetst du recht haben und es sollte dann eine Einstellungssache sein, oder? Gruß Tommy
Na dann hab ich ja glück, dass ich dahinter sitze! ;-) Gruß Tommy
#include<stdio.h> #include<stdlib.h> Hab jetzt folgendes Programm geschrieben: #include<avr/pgmspace.h> #include<avr/interrupt.h> #include<avr/iom162.h> //#include<avr/signal.h> #include"uart.h" #define F_CPU 4000000UL #define UART_BAUD_RATE 9600 int main() { int a=5; char b[10]; uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); sei(); itoa(a,b,10); Hier springt er ins Unterprogramm siehe Abb. 1 while(1) { uart_puts("test"); } } Abb. 1 /*********************************************************************** ***** Function: uart1_puts_p() Purpose: transmit string from program memory to UART1 Input: program memory string to be transmitted Returns: none ************************************************************************ ****/ void uart1_puts_p(const char *progmem_s ) { register char c; while( (c = pgm_read_byte(progmem_s++)) ) er springt eigentlich direkt in die while Zeile! Ich weiß einfach nicht wieso er das macht! uart1_putc(c); }/* uart1_puts_p */ Gruß Tommy
Es soll auch schon vorgekommen sein, dass man irrtümlich das falsche HEX-File auf den µC gebrannt hat. Wenn ich mir deine Fehlerbeschreibungen so ansehe, dann sieht das für mich genau danach aus: Im µC läuft ein ganz anderes Programm, als das welches du im Debugger betrachtest.
Hab ich auch schon gedacht! Aber daran liegt es auch nicht. Tausche den String in der while Schleife damit ich diesen Fehler ausschließen kann. Gruß Tommy
Der Debugger macht genau das was du von ihm verlangst. Wenn es der GNU Compiler ist, dann wirft er die Zeile: itoa(a,b,10); Hier springt er ins Unterprogramm siehe Abb. 1 raus. Auch wenn alle Optimierung des Compilers deaktiviert ist. Das ist blöd aber der GNU-C arbeitet so. Ziehe: char b[10]; aus der main() raus, schreibe es als globale Variable so: char volatile b[10];
Habe jetzt mal die Funktion wo er hinspringt auskommentiert! Wenn ich das mache, springt er einfach in die Funktion darüber. Gruß Tommy
Versuch doch mal zu verstehen was andere Leute schreiben.
> MERKE: DAS PROBLEM SITZT IMMER VOR DER TASTATUR
Das ist mir schon klar, dass es an mir liegt! Ist ja leider kein anderer im Raum. Nur leider löst es sich nicht mit so einer Aussage!!
Löse Dich von dem Gedanken, der AVR oder der Debugger würden C können. Der AVR kann nur Maschinencode, nur durch Assembler 1 zu 1 notierbar. Dem Debugger wird es nicht besser gehen, der wird auch nicht wirklich C können. Wenn Du wirklich wissen willst was los ist, dann schau Dir den vom Compiler erzeugten Assemblercode an, denn nur der zählt. ...
Okay schreibe erstmal ein ganz einfaches Probgramm und schaue mir dann den assembler Code an Danke
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.