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
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
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
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.
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
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.
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
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.
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).
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
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.
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
>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?
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 :-)
>>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.
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
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
intmain(void)
5
{
6
intms;
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
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!