Hallo, ich hab ein...naja schon fast peinliches Problem mit C und dem AVR Studio: Ich bin dabei ein Programm zu schreiben, ich hatte schon ziemlich viel geschrieben, doch irgendwann trat dieser Fehler auf und hab nach und nach alles wieder entfernt bis nur noch diese mini Testprogramm da war ....und der Fehler wo ich net kapier war ebenfalls noch da... Wenn ich bei dem Programm "Build an Run" mach, also simulieren will, dann passiert nicht viel...der Programcounter (das ist doch der gelbe Pfeil am linken Rand??) bleibt einfach bei der 1. geschweiften Klammer nach "main" hängen (siehe Anhang). Ich kann so oft auf "Step Into" oder "Step Over" drückn wie ich möchte, er bleibt immer da. Das ist ein Szenario. Wenn ich noch ins "main" den rießigen Befehl "PORTD |= 0x01" zB. rein schreib passiert folgendes: nach "Build" ist der Programmcounter wieder auf der geschweiften Klammer, aber verschwindet wenn ich auf "Step Into" oder so klick. Irgendwas wird simuliert aber kommt nix dabei raus. Wenn ich auf "Pause" drück ist der CycleCounter bei einigen 100.000.. Irgendwas scheint da an den Einstellungen nicht zu stimmen... Hab das AVRStudio 4.18 Ich hab es mit SP2 und ohne SP2 probiert, ich hab es mit der neuesten WINAVR und mit einer etwas älteren probiert, nix haut hin. PS: ich hab ausversehen zwei bilder angehängt #include <avr/io.h> #include "stdlib.h" #include "stdio.h" #include <avr/interrupt.h> int ausgabe(); void main() { int test; test = 2; // PORTD = 0x01; if(test == 1) { ausgabe(); }; for(;;); }; int ausgabe() { int i = 3; return i; };
Besser wäre der kpl. Bildschirm. Es scheint was zu fehlen. Der Aufruf ohne Rückgabewert: ausgabe(); Funktion mit Rückgabe: int ausgabe() { return i; }; Sollte eine Fehlermeldung bringen. Auserdem würde er nur einmal durchlaufen und dann hier hängen bleiben: for(;;); avr
>Der Aufruf ohne Rückgabewert: > ausgabe(); Aber das "int ausgabe();" ist doch nur ein Prototyp (heist das so?) damit ist eine Warnung weniger Das Programm müsste dann dohc wenigstens in der Endlosschleife hengen bleiben meiner Meinung nach Edit: Ohne "int ausgabe();" gehts auch nicht :-(
Stefan A. schrieb: > Das Programm müsste dann dohc wenigstens in der Endlosschleife hengen > bleiben meiner Meinung nach for (;;); ist aber keine Endlosschleife, es handelt sich um eine virtuelle Prozedur, die so nicht richtig ist.
>for (;;); ist aber keine Endlosschleife, es handelt sich um eine >virtuelle Prozedur, die so nicht richtig ist. while(1){}; geht ebensowenig, ich hab das Gefühl, dass es das nicht ist, weil das Programmcounter gar nicht bis dahin kommt
Ich ändere das Programm mal (also, das ist jetzt VHIT (vom Hirn ins terminal, also ohne Compilerlauf) #include <avr/io.h> #include "stdlib.h" #include "stdio.h" #include <avr/interrupt.h> void main() { int test; test = 2; if(test == 1) { fprintf( "%s Test ist jetzt, \t ", test); }; for(;;); }; Die fprintanweisung stimmt vermutlich nicht, ich habe das momentan nicht genau im Kopf. Das Programm sollte den Wert von test ausgeben. Führe in das programm Ausgabeanweisungen ein, die einen Wert ausgeben, und checke die Richtigkeit dieses Wertes. Gruss Robert
>fprintf( "%s Test ist jetzt, \t ", test); >Die fprintanweisung stimmt vermutlich nicht, ich habe das momentan nicht >genau im Kopf. ich möcht ein Programm für nen ATmega8 schreiben, ich kenn die fprintf Anweisung noch aus dem 2. Semester da haben wir aber für Windows programmiert. Da ging dann glaub ich ein DOS Fenster auf aber selbst wenn ich das einfüge kommen zwar nur 3 Warnings, aber der gelbe Pfeil hängt trotzden auch noch nach 1000 mal "Step Into" drücken noch immer an der 1. geschweiften Klammer. Ich hab überhaupt keine Ahnung was das sein könnte
Die Bedingung if(test == 1) wird nie wahr sein, und auch sonst macht das Programm nichts sinvolles (aus der Sicht des Optimizers) also optimiert der Compiler ganz einfach alles überflüssige (quasi das ganze Programm) weg! Desswegen bleibt der Debuger auch am Programmanfang stehen, es sit alles erledigt und gibt nichts mehr zu tun das irgend einen Einfluss hat...
ich weiß nicht was dein programm machen sollte deshalb habe ich es so umgeschriebn, dass du zumindesten beim simulieren etwas sehen solltes am portd. bei deinem programm, waren einige klammern falsch gesetzt, wenn du "int main" schreibst musst du einen rückgabewert schreiben "return 0" zuviele strichpunkte wenn du ausgänge setzten willst musst du im directionport auch den port als ausgang setzen.
1 | int main(void){ |
2 | int test; |
3 | test = 2; |
4 | DDRD=0xFF; |
5 | |
6 | |
7 | if(test == 1){ |
8 | ausgabe(); |
9 | }
|
10 | |
11 | while (1){ |
12 | PORTD = 0x01; |
13 | }
|
14 | |
15 | return 0; |
16 | }
|
hmm ich hab jetzt das Programm etwas umgestalltet, nun macht der Simulator wieder ganz komische sachen: "Build" , dann Simulation startetn, dann ist der gelbe Pfeil bei der 1. geschweiften Klammer klick auf "Step Into" gelber Pfeil ist auf der } vom main-Programm (!) noch ein klick auf "Step Into" gelber Pfeil ist auf der } vom ausgabe-Programm (!!) noch ein klick auf "Step Into" Pfeil weg, endlosschleife #include <avr/io.h> #include "stdlib.h" #include "stdio.h" #include <avr/interrupt.h> int main(void) { int test; test = ausgabe(4); PORTD |= test; return (0); while(1); }; int ausgabe(int bin) { int i; i = 2 + bin; return i; };
Auf 'nem AVR ist's recht unsinnig, main zu verlassen, deshalb wäre die Endlosschleife vor dem "return 0" besser aufgehoben.
1 | #include <avr/io.h> |
2 | #include "stdlib.h" |
3 | #include "stdio.h" |
4 | #include <avr/interrupt.h> |
5 | |
6 | |
7 | int main(void) |
8 | {
|
9 | int test; |
10 | |
11 | test = ausgabe(4); |
12 | PORTD |= test; |
13 | |
14 | while(1); |
15 | |
16 | return (0); |
17 | };
|
18 | |
19 | |
20 | int ausgabe(int bin) |
21 | {
|
22 | int i; |
23 | i = 2 + bin; |
24 | return i; |
25 | };
|
Tip! Wenn Du was simulieren willst, schalte vorher die Optimierung aus.
Schniefnase schrieb: > for (;;); ist aber keine Endlosschleife, Schwachsinn. Was ist denn eine Schleife ohne Abbruchbedingung? Eine Endlosschleife. In diesem Fall zusätzlich noch mit leerem Body. > es handelt sich um eine > virtuelle Prozedur, die so nicht richtig ist. Was soll denn eine "virtuelle Prozedur" sein? Auch C++ kennt "virtuell" nur im Zusammenhang mit Methoden. Bloss weil es auf den ersten Blick ein wenig wie ein Funktionsaufruf aussehen mag, ist es noch lange keiner. Andreas
weißgradnich schrieb: > Auf 'nem AVR ist's recht unsinnig, main zu verlassen, deshalb wäre die > Endlosschleife vor dem "return 0" besser aufgehoben. Und das "return 0" kann man auch gleich noch weglassen. Selbst ohne die Endlosschleife, denn main() gibt implizit immer 0 zurück, wenn nichts anderes zurückgegeben wird. Letzteres gilt allerdings nur für main(), jede andere Funktion, die nicht "void" zurückgibt, braucht ein explizites return. Andreas
Der Reihe nach: Autor: avr (Gast) Datum: 03.04.2010 20:20 > Der Aufruf ohne Rückgabewert: [...] > Sollte eine Fehlermeldung bringen. Nein, der Rückgabewert wird implizit verworfen, ist vollkommen in Ordnung so. Autor: Schniefnase (Gast) Datum: 03.04.2010 20:31 > for (;;); ist aber keine Endlosschleife, es handelt sich um eine > virtuelle Prozedur, die so nicht richtig ist. for (;;); ist eine Endlosschleife und syntaktisch und semantisch vollkommen korrekt. Virtuelle Prozeduren gibt es in C nicht, du verwechselst da irgendwas. Autor: R. Freitag (rfr) Datum: 03.04.2010 20:37 > fprintf( "%s Test ist jetzt, \t ", test); > Die fprintanweisung stimmt vermutlich nicht [...] Stimmt, auch unter Windows verlangt fprintf() als erstes Argument nach einem Stream, in den geschrieben werden soll. Sinnvoll wäre auf dem AVR sprintf() in einen statischen Puffer, der dann per UART ausgegeben wird. Einschlägige Beispiele stehen im Wiki und in der Dokumentation zur AVR-LIBC. Nach ISO-C99 darf in main() die return-Anweisung entfallen, was dann denselben Effekt wie exit(0) haben muss. Ansonsten ist des Pudels Kern sicher die Optimierung; ein optimiertes C-Programm zu debuggen, ist meistens zwecklos. Wenn alle Stricke reißen, schau mal ins Assembly (beim gcc zu erzeugen mit 'gcc -S').
Meine Überlegung ging dahin, durch das Einfügen von Ausgabeanweisungen Klarheit über den aktuellen Status des Programmes zu erhalten. Der OP wird (oder sollte eigentlich) selbst merken, daß die IF-Konstruktion niemals erfüllt wird. Die Optimierung schlägt übrigens nicht zu, weil die fprintanweisung ausführbar ist und daher nicht wegoptimiert werden kann. Gruss Robert
Hier:
1 | void main() |
2 | {
|
3 | int test; |
4 | test = 2; |
5 | |
6 | if(test == 1) |
7 | {
|
8 | fprintf( "%s Test ist jetzt, \t ", test); |
9 | };
|
10 | |
11 | for(;;); |
12 | |
13 | };
|
Schlägt die Optimierung mit absoluter Sicherheit zu, da der Text im Körper der if-Anweisung niemals erreicht werden kann. Mit meinem AVR-GCC ergibt das folgendes Assembly:
1 | main: |
2 | /* prologue: frame size=0 */ |
3 | ldi r28,lo8(__stack - 0) |
4 | ldi r29,hi8(__stack - 0) |
5 | out __SP_H__,r29 |
6 | out __SP_L__,r28 |
7 | /* prologue end (size=4) */ |
8 | .L2: |
9 | rjmp .L2 |
Kann mir einer erklären warum stehen hinter den "}" immer ";" stehen?
Schlägt die Optimierung mit absoluter Sicherheit zu, da der Text im Körper der if-Anweisung niemals erreicht werden kann. Gans recht. Und der OP wird dann eine Phase des Nachdenkens einlegen, deren Ergebnis sein wird, zu erklären, warum die fprintanweisung nicht ausgeführt wird. Ich hoffe, das bringt den OP auf vernünftige Ideen. Gruss Robert
Noname schrieb: > Kann mir einer erklären warum stehen hinter den "}" immer ";" stehen? Ich glaub mich zu erinnern, dass wir das in der Info-Vorlesung so gelernt hatten. zu meinem Hauptproblem: gestern Nacht bin ich doch tatsächlich noch duch verzweifeltes umherklicken im AVRStudio in ein Menü gekommen wo man den Optimierungsgrad einstellen kann. Da ich erst gestern das erste mal mit C nen AVR programmieren wollte und mich nicht auskenn hab ich einfach mal die Optimierung auf Stufe0 gesetzt. :-) Das wars! Meine Programme sind zwar jetzt 3 mal so groß aber ich kann nahezu alles Simulieren! Dann hab ich noch kurz versucht die Disassambly mit eingeschalteter Optimierung nachzuvollziehen....naja das hab ich dann schnell wieder aufgegeben, das ist ja voll krank^^ Vielen Dank für die Hilfe an alle!
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.