Forum: Mikrocontroller und Digitale Elektronik Warum springt der Debugger hier hin?


von Tommy (Gast)


Lesenswert?

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;
    }
  }
}

von Henry (Gast)


Lesenswert?

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.

von Tommy (Gast)


Lesenswert?

Werd ich ausprobieren!
Vielen Dank

von Tommy (Gast)


Lesenswert?

Funktioniert auch nicht! So ein M...
Wofür ist denn dann das JTAG ICE MK2 überhaupt gut?
gruß tommy

von Roland Praml (Gast)


Lesenswert?

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

von Tommy (Gast)


Lesenswert?

Vielen Dank werd ich gleich machen

von Roland Praml (Gast)


Lesenswert?

Wichtig ist noch, das KOMPLETTE Projekt dann neu zu compilieren...

von Tommy (Gast)


Lesenswert?

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

von Tommy (Gast)


Lesenswert?

Ne das ist es wohl auch nicht! Selbst nach dem Compilieren springt er in 
die Routine

von Tommy (Gast)


Lesenswert?

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

von pcb (Gast)


Lesenswert?

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.

von Roland Praml (Gast)


Lesenswert?

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

von Tommy (Gast)


Lesenswert?

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

von Tommy (Gast)


Lesenswert?

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

von Tommy (Gast)


Lesenswert?

Habs verstanden,:) du meintest mit default den Namen, den ich der Datei 
gegeben habe!
Hab sie gefunden!

von Tommy (Gast)


Lesenswert?

In Zeile 118 hab ich das hier gefunden:
 118:  0e 94 17 04   call  0x82e  ; 0x82e <itoa>

von Roland Praml (Gast)


Lesenswert?

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

von Tommy (Gast)


Lesenswert?

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

von Tommy (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

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

von Tommy (Gast)


Lesenswert?

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

von Mutti (Gast)


Lesenswert?

MERKE: DAS PROBLEM SITZT IMMER VOR DER TASTATUR

von Tommy (Gast)


Lesenswert?

Na dann hab ich ja glück, dass ich dahinter sitze! ;-)
Gruß Tommy

von Tommy (Gast)


Lesenswert?

#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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Tommy (Gast)


Lesenswert?

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

von Henry (Gast)


Lesenswert?

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];

von Tommy (Gast)


Lesenswert?

Habe jetzt mal die Funktion wo er hinspringt auskommentiert! Wenn ich 
das mache, springt er einfach in die Funktion darüber.
Gruß Tommy

von Henry (Gast)


Lesenswert?

Versuch doch mal zu verstehen was andere Leute schreiben.

> MERKE: DAS PROBLEM SITZT IMMER VOR DER TASTATUR

von Tommy (Gast)


Lesenswert?

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!!

von Hannes Lux (Gast)


Lesenswert?

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.

...

von Tommy (Gast)


Lesenswert?

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