Forum: Compiler & IDEs C-Code mit AVR-Studio-Simulator debuggen möglich?


von Beninho (Gast)


Lesenswert?

Hallo,

Betreff sagt eigentlich schon alles. Kann es sein, dass man mit dem 
AVR-Studio-Simulator (4.13 mit SP1, build 557) ein Debuggen von 
GCC-C-Code (Winavr 20070525) nicht möglich ist? Ich meine, ich habe das 
mal irgendwo gelesen, weiß aber nicht mehr wo.
Wenn ich z.B. eine leere Endloschleife benutze (siehe Code), bleibt der 
CycleCounter im Simulator hängen, steht dort etwas, läuft der 
Cycle-Counter. Außerdem überspringt der Simulator die 
USART-Sendebefehle.
Oder habe ich einfach Fehler in meinem Code?

Gruß,
Ben

von Beninho (Gast)


Angehängte Dateien:

Lesenswert?

+Anhang

von Jörg X. (Gast)


Lesenswert?

Stel die Optimierung mal auf '1' oder '2', bei 's' kommt der Debugger 
gerne mal aus dem Tritt.
Und dass dein Programm nicht besonders sinnvoll ist, ist dir hoffentlich 
auch schon aufgefallen ;)

hth. Jörg

von Beninho (Gast)


Lesenswert?

Hallo Jörg,

danke für den Tip. Eine leere Endlosschleife mag der Debugger zwar auch 
mit Optimierung 1 und 2 nicht, aber die USART-Sendebefehle werden jetzt 
wenigstens nicht mehr übersprungen.
Und das mit dem nicht-sinnvollen Code hab ich einfach mal überhört ;-)

Grüße aus München,
Ben

von Karl H. (kbuchegg)


Lesenswert?

Wie schreibst du die leere Endlosschleife?

  while(1);

Schreib das mal um

  while(1)
    ;

Manche Debugger arbeiten zu sehr Zeilenorientiert. Die streiken
dann, wenn sie für Schleifenkopf und Schleifenrumpf (der leer ist)
keine eigene Zeilen haben.

Wie das beim gdb ist, hab ich nie ausprobiert. Ich schreibe
grundsätzlich die Dinge immer in eigene Zeilen. (Mit Microsoft
Debuggern) gebranntes Kind scheut das Feuer.

von Beninho (Gast)


Lesenswert?

Hallo Karl Heinz,

meine Endlosschleife sieht folgendermaßen aus:

Funktioniert nicht:
for(;;)
  {
  }

Funktioniert:
for(;;)
  {
  DDRE = 0xFF;
  }

Dasselbe mit while(1) probiert, sogar einen Strickpunkt hinter der 
geschlossenen geschweiften Klammer hab ich ausprobiert (nach Deinem Tip 
auch in einer eigenen Zeile), jedoch bleibt der Cycle-Counter trotzdem 
hängen.

Viele Grüße,
Ben

von Karl H. (kbuchegg)


Lesenswert?

Beninho wrote:
> Hallo Karl Heinz,
>
> meine Endlosschleife sieht folgendermaßen aus:
>
> Funktioniert nicht:
> for(;;)
>   {
>   }
>
> Funktioniert:
> for(;;)
>   {
>   DDRE = 0xFF;
>   }
>
> Dasselbe mit while(1) probiert, sogar einen Strickpunkt hinter der
> geschlossenen geschweiften Klammer hab ich ausprobiert (nach Deinem Tip
> auch in einer eigenen Zeile), jedoch bleibt der Cycle-Counter trotzdem
> hängen.

Das ist eigenartig. Sowas hab ich im AVR-Studio Emulator noch
nie beobachtet.

von Beninho (Gast)


Lesenswert?

>Das ist eigenartig. Sowas hab ich im AVR-Studio Emulator noch nie beobachtet.

Hm. Interessant. Dann liegts wohl doch an mir...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Naja, die Endlosschleife wird ja wohl nur aus einem rjmp .-2
bestehen.  Das ist ziemlich schwierig, sowas zeilenweise
abzuarbeiten -- selbst im Assembler ist es ja nur eine Zeile. ;-)

Schreib da mal was ,,richtiges'' rein, und es sollte sich besser
debuggen lassen.  Wenn du gerade nichts besseres weißt, dann
taugt allemal sowas wie
1
PORTB = 42;

als ,,richtiger'' Code.

von Karl H. (kbuchegg)


Lesenswert?

Jörg Wunsch wrote:
> Naja, die Endlosschleife wird ja wohl nur aus einem rjmp .-2
> bestehen.  Das ist ziemlich schwierig, sowas zeilenweise
> abzuarbeiten -- selbst im Assembler ist es ja nur eine Zeile. ;-)

Schon.
Aber eigentlich sollte der Debugger schon bei einem Druck auf F10
den rjpm einmal ausführen und dann wieder stehen bleiben. Mit
Erhöhung des cycle counter natürlich.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Keine Ahnung, ich nehme kein AVR Studio...  Ich weiß auch gerade nicht,
wie sich GDB da verhält.  Ich habe eher selten komplett leere
Schleifen (und wenn, dann setze ich mir den Brechpunkt lieber in eine
ISR oder sowas).

von Raphael (Gast)


Lesenswert?

Hallo

ich hab das gleiche problem das der simulator mir einfach die for 
schleifen überspringt ohne den cycle counter zu erhöhen.

so sieht die aus sollte also alles stimmen spuckt auch kein compiler 
fehler

for(q=0;q<=880;q++)
      {

        r++;

      }

hab da extra noch das r++; in die schleife geschrieben geht aber immer 
noch nicht. die optimierung hatte ich auch schon auf 1 und 2 
umgeschalten.
geht auch nicht. was kann das dann noch sein?
bin froh um jede hilfe?

gruss

raphael

von Karl H. (kbuchegg)


Lesenswert?

Raphael wrote:
>
> for(q=0;q<=880;q++)
>       {
>
>         r++;
>
>       }
>
> hab da extra noch das r++; in die schleife geschrieben geht aber immer
> noch nicht. die optimierung hatte ich auch schon auf 1 und 2
> umgeschalten.
> geht auch nicht. was kann das dann noch sein?
> bin froh um jede hilfe?

Zeig mal das komplette Programm.

Machst du was mit dem r nach der Schleife?
So dämlich ist der COmpiler auch wieder nicht, dass er sich so einfach
austricksen lässt. Wenn du mit einer Variablen nichts machst, dann
kann die Variable auch wegfallen. Damit steht aber wieder nichts
in der Schleife, was eine Schleife erfordern würde.

Somit ist ...

> for(q=0;q<=880;q++)
> {
> }
>

... wieder gleichbedeutend mit ...

  q = 880;

nur das Letzteres um einiges weniger Zeit beansprucht und daher
vom Optimizer favourisiert werden wird.

Genaueres kann man aber nur sagen, wenn man das komplette Programm
sieht.

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger wrote:

> Das ist eigenartig. Sowas hab ich im AVR-Studio Emulator noch
> nie beobachtet.

Hmm.
Nachdem ich mir vor einiger Zeit eine neuere Version geholt
habe, sieht es jetzt bei mir ebenfalls so aus:
1
#include <avr/io.h>
2
3
main()
4
{
5
  DDRA = 0xFF;
6
  PORTA =0xFF;
7
8
  while( 1 )
9
    ;
10
}

Compiliert mit -Os. Der Debugger kommt ausser Tritt. Single
Step geht noch bis zur Port Zuweisung, danach ist Schluss.

Mach ich den Single Step jedoch im Disassembler Window läuft
der Debugger brav auf den
    rjmp   PC-0x0000
auf, stept auch weiter und erhöht auch brav den Cycle Counter

von Kai G. (runtimeterror)


Lesenswert?

>Mach ich den Single Step jedoch im Disassembler Window läuft
>der Debugger brav auf den
>    rjmp   PC-0x0000
>auf, stept auch weiter und erhöht auch brav den Cycle Counter

Wollt ich gerade fragen... hätte sonst vermutet, dass das als SLEEP 
übersetzt wird.

Funktioniert das Zählen im nicht-single-step-Modus? Also einfach mal 
laufen lassen und dann wieder anhalten?

von Karl H. (kbuchegg)


Lesenswert?

Kai Giebeler wrote:
>>Mach ich den Single Step jedoch im Disassembler Window läuft
>>der Debugger brav auf den
>>    rjmp   PC-0x0000
>>auf, stept auch weiter und erhöht auch brav den Cycle Counter
>
> Wollt ich gerade fragen... hätte sonst vermutet, dass das als SLEEP
> übersetzt wird.
>
> Funktioniert das Zählen im nicht-single-step-Modus? Also einfach mal
> laufen lassen und dann wieder anhalten?

Habs gerade probiert.
Disassembler Window zu.
Debugger auf  - "Run"
Nach einiger Zeit auf "Break"

Der Debugger braucht interessanterweise 1 bis 2 Sekunden
bis er sich wieder meldet. Danach steht der Cycle Count
auf 650390 (ist aber jedesmal eine andere Zahl in der
Größenordnung).

So ganz koscher dürfte dasGanze also nicht sein :-)

von Kai G. (runtimeterror)


Lesenswert?

>So ganz koscher dürfte dasGanze also nicht sein :-)
ACK - Plädiere auf Bug im Debugger ;)

von Toni (Gast)


Lesenswert?

>>Compiliert mit -Os. Der Debugger kommt ausser Tritt. Single
>>Step geht noch bis zur Port Zuweisung, danach ist Schluss.


>>Habs gerade probiert.
>>Disassembler Window zu.
>>Debugger auf  - "Run"
>>Nach einiger Zeit auf "Break"

>>Der Debugger braucht interessanterweise 1 bis 2 Sekunden
>>bis er sich wieder meldet. Danach steht der Cycle Count
>>auf 650390 (ist aber jedesmal eine andere Zahl in der
>>Größenordnung).

>>So ganz koscher dürfte dasGanze also nicht sein :-)


Kann ich nicht bestätigen. Bei mir läuft der Simulator ohne Probleme.

von Kai G. (runtimeterror)


Lesenswert?

>Kann ich nicht bestätigen. Bei mir läuft der Simulator ohne Probleme.

Evtl. andere Version?

von Toni (Gast)


Lesenswert?

>Evtl. andere Version?

AVR-Studio-Simulator (4.13 mit SP1, build 557), jedoch hab ich noch ne 
ältere  WinAVR Version drauf. WinAVR 20060421.

von Raphael (Gast)


Lesenswert?

Hallo

ich habe da das Programm auf das wesentliche gekürtzt und ein eigenes 
Projekt dafür auf gemacht. der Code sieht wie folgt aus:

#include <avr/io.h>

  int a=400,b,c;

int main(void)
{

  DDRC = 0xFF;
  DDRA = 0xFF;
  PORTA = 0xFF;



  for(b=0;b<a;b++)
  {

    for(c=0;c<=1000;c++);


  }

  PORTA = 0x00;

  while(1);

}

es sollte ein kurzes aufblinken der Led's an PORTA bewirken verz ca 
1000ms.
der counter zählt jetzt zwar hoch wird dabei aber nur die erste schlaufe 
beachtet das heisst egal was ich in die nachfolgende schlaufe für eine 
zahl zum hochzählen hinein schreibe der counter gibt mir immer die selbe 
zeit aus. wird denn das einfach vom Compiler übersehen weil das eine 
lehre schlaufe ist? übrigens wenn ich das auf mein atmega32 schmeisse 
ändert sich die zeit auch nicht. das heisst ja das es am Compiler liegen 
sollte.

mfg Raphael

von Karl H. (kbuchegg)


Lesenswert?

Raphael wrote:
> lehre schlaufe ist? übrigens wenn ich das auf mein atmega32 schmeisse
> ändert sich die zeit auch nicht. das heisst ja das es am Compiler liegen
> sollte.

Grundsätzlich musst du zwischen Simulator und realer Hardware
unterscheiden. Der Simulator hat auch so seine Fehler.

Wenn der reale Prozessor auch nicht wartet, dann hast du
aller Wahrscheinlichkeit nach den Optimizer eingeschaltet
und ja, der optimiert die Schleifen weg.
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
int main(void)
5
{
6
  int ms;
7
8
  DDRC = 0xFF;
9
  DDRA = 0xFF;
10
11
  PORTA = 0xFF;
12
13
  for( ms = 0; ms < 100; ms++ )
14
    _delay_ms( 10 );   // 100 mal 10 Millisekunden ergeben eine Sekunde
15
16
  PORTA = 0x00;
17
18
  while(1);
19
}

von Raphael (Gast)


Lesenswert?

hallo

ok danke schön alles klar. hab das jetzt mit delay.h gelöst.

mfg

raphael

von Beeblebrox (Gast)


Lesenswert?

Hallo Ihr,

ich brauch mal eure Hilfe. Ich habe da wohl ein ähnliches Problem mit 
WinAvr. Ich möchte im Hauptprogramm an einer Stelle warten solange die 
Variable t (Zeit) kleiner als 1500 ms ist. Die Zeit t wird in einer 
Interrupt-Routine aktualisiert. Offensichtlich schmeißt der Compiler 
auch bei mir die while-Schleife raus oder übersetzt Blödsinn und wartet 
endlos. Vermutlich bemerkt er nicht, dass die Schleife tatsächlich 
sinnvoll ist. Gibt es vielleicht eine andere elegante Möglichkeit an 
einer Stelle im Programm zu warten, bis t den Wert (hier) 1500 erreicht 
hat? Bzw. kann man den Compiler zwingen die Zeile trotzdem zu 
übersetzen?

main()
{

       // Befehle vorher

       // while-Schleife funktioniert nicht:
       while (t < 1500) {}     // warte bis t > 1500 ...

       // Befehle

       // while-Schleife funktioniert:
  while (t < 1500)
  {
     lcd_setcursor(0,0); fprintf(fLCD, "%i", t);
  }

        // Befehle nachher

}

ISR(SIG_OUTPUT_COMPARE1A)
{
  sreg=SREG;
  if (t < T) t+= 10; else t = 0;
  SREG=sreg;
}

Nebenbei: Ist es notwendig das Statusregister explizit in der 
Interrupt-Routine zu sichern? Bzw. fügt der Compiler den notwendigen 
Code selbst ein?

Dankeschön!

von Oliver (Gast)


Lesenswert?

volatile t

SREG sichern nicht nötig.

Oliver

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.