Warum springt der Debugger hier hin?

Gast #1222340
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;
    }
  }
}
Gast #1222406
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
Gast #1222518
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
Gast #1222698
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
Gast #1222728
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
Gast #1222767
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
Gast #1223058
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
Gast #1223474
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
Gast #1223690
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
Gast #1223712
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];
Gast #1223760
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.

...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren