Forum: Compiler & IDEs Frequenzmessung und Optimierung -Os


von Timer (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe mir für meine Codesammlung mal eine Frequenzmessung 
programmiert um später evtl. auch ein LC-Meter zu bauen.
Ich programmiere grundsätzlich immer mit der Optimierung -O0. Das 
Programm funktioniert damit auch schon sehr gut. Nun habe ich mal die 
Optimierung auf -Os umgestellt, da ich ja die delay.h verwende und in 
der Hilfe zu der lib steht, dass man unbedingt die Codeoptimierung 
einschalten soll. Nun hab ich aber das Problem, dass mein Programm nicht 
mehr funktioniert, also wird irgend etwas wegoptimiert, was ich 
eigentlich bräuchte. Da denk ich mir, stellen wir die Optimierung eben 
wieder auf -O0, aber das Programm läuft immer noch nicht!?!?!
Kann mir das einer erklären?
Ich bin froh, dass ich zufällig noch ein BackUp auf dem Stick hatte.

von Timer (Gast)


Lesenswert?

Ach so, ich bin leider nicht zu Hause - kann also nicht genau sagen 
welche Version ich von AVR Studio (irgend eine 4.x Version) bzw von 
WinAVR (irgend was von 2007) nutze.
Das Programm läuft auf einem ATMega32 mit 16Mhz Quarz.

von Johannes M. (johnny-m)


Lesenswert?

Was funktioniert nicht? Läuft gar nichts?

BTW: Bist Du sicher, dass die Zahlen hier
1
zeitdiff=(65535-zeit1)+65635*(ueberlauf-1)+zeit2;
stimmen? Zumindest die zweite Zahl würde ich instinktiv anzweifeln...

von Timer (Gast)


Lesenswert?

Ich bekomme nach der Optimierung einfach keine Anzeige auf dem Display.
In
1
zeitdiff=(65535-zeit1)+65635*(ueberlauf-1)+zeit2;
ist natürlich die 2. Zahl falsch (Tippfeler^^, muss 65535 sein). Erklärt 
aber immer noch nicht das Problem mit der Optimierung, da der 
Schreibfehler ja nur eine konstante Abweichung der Frequnz hervorrufen 
sollte.
Mein "Gedankengang" zu der Codezeile steht als Kommentar auch darüber, 
falls du es nachvollziehen möchtest.
Trotzdem schon mal dickes DANKE für die Entdeckung des Tippfehlers ;)
Würde mich freuen wenn noch mehr Vorschläge zur Verbesserung meines 
Codes kommen. Man lernt ja nie aus und gerade bei Frequenzmessung kommt 
es auf sauberen Code an um genaue Messungen durchführen zu können.

von Johannes M. (johnny-m)


Lesenswert?

Nun, da ich die lcd.h (und die vermutlich dazugehörige lcd.c) nicht 
kenne, kann ich dazu nix sagen...

von Michael Wilhelm (Gast)


Lesenswert?

>zeitdiff=(65535-zeit1)+65635*(ueberlauf-1)+zeit2;

Und wenn du eine der Variablen nach unsigned long castest, damit die 
ganze Rechnung in long ausgeführt wird? So rechnet der µC ja nur in 
unsigned int. Kann es da zu Überläufen kommen?

MW

von Johannes M. (johnny-m)


Lesenswert?

Michael Wilhelm wrote:
> du eine der Variablen nach unsigned long castest, damit die
> ganze Rechnung in long ausgeführt wird? So rechnet der µC ja nur in
> unsigned int. Kann es da zu Überläufen kommen?
Das würde aber auch ohne Optimierung passieren...

von Timer (Gast)


Angehängte Dateien:

Lesenswert?

Die LCD Routinen sind von Peter Fleury aus der HD44780U LCD library.

von Rolf Magnus (Gast)


Lesenswert?

>>zeitdiff=(65535-zeit1)+65635*(ueberlauf-1)+zeit2;
>
> Und wenn du eine der Variablen nach unsigned long castest, damit die
> ganze Rechnung in long ausgeführt wird? So rechnet der µC ja nur in
> unsigned int.

Nein. So wie es oben steht, wird das in long gerechnet.

von Rolf Magnus (Gast)


Lesenswert?

Ach ja, was ich vergaß:
1
zeitdiff=(65535-zeit1)+65535*(ueberlauf-1)+zeit2;
2
//umgestellt--> zeitdiff=65635*ueberlauf+zeit2-zeit1;

Wieso schreibst du die einfachere Formel in den Kommentar statt direkt 
in den Code?

von Timer (Gast)


Lesenswert?

OK, wenn ich Glück habe, liegt es nur an der LCD libery. Kann ja sein, 
dass da delay Pausen drin sind welche für mein Display zu kurz sind 
(ohne Optimierung sind die delays ja zu groß und könnten so gerade 
passen).
Ich probier das heute Abend mal mit einer simplen LCD Ausgabe aus und 
sag dann morgen bescheid.

Die einfache Formel steht im Kommentar, weil ich das erst nachträglich 
geändert habe und noch nicht getestet ist. Quasi als Gedankenstutze, das 
ich das noch machen muss. Ich baue neuen Code immer erst nach dem Test 
ein - never change a running system.

Ist der Code der Frequenzmessung ansonsten so OK, oder kann der noch 
verbessert werden (geht bestimmt^^).

von Timer (Gast)


Lesenswert?

Ich hab mir beim Mittag noch mal gedanken darüber gemacht. An der LCD 
Libery kanns ja eigentlich auch nicht liegen, da das Programm beim 
zurückzetzen de Optimierung auf -O0 auch nicht mehr funktioniert.
Irgend einer ne Idee? Evtl. spinnt ja nur AVR Studio.

von Johannes M. (johnny-m)


Lesenswert?

Timer wrote:
> Ich hab mir beim Mittag noch mal gedanken darüber gemacht. An der LCD
> Libery kanns ja eigentlich auch nicht liegen, da das Programm beim
> zurückzetzen de Optimierung auf -O0 auch nicht mehr funktioniert.
Wie jetzt? Dann ist die Optimierung also doch nicht Schuld?

> Irgend einer ne Idee? Evtl. spinnt ja nur AVR Studio.
AVRStudio hat damit nichts zu tun. AVRStudio kann kein C und hat mit dem 
Compilieren an sich nichts am Hut.

von Timer (Gast)


Lesenswert?

Ich hab im Ersten Beitrag geschrieben, dass ich -Os eingestellt habe und 
das Programm nicht mehr lief. Nach dem zurückstellen auf -O0 gings aber 
auch nicht mehr, obwohl der Code der gleiche geblieben ist. Nachdem ich 
das BackUp von meinem Stick gezogen hatte war alles wieder i.O. Bei 
jedem Versuch das gleiche Verhalten - keine Anzeige mehr auf dem 
Display.
Will aber eigentlich schon die Optimierung reinnehmen, da es schon einen 
Unterschied macht ob das Programm 6500kB oder 1200kB verbraucht. Soll 
evtl. mal auf nen ATMega8 oder 2321.

von Johannes M. (johnny-m)


Lesenswert?

Timer wrote:
> Ich hab im Ersten Beitrag geschrieben, dass ich -Os eingestellt habe und
> das Programm nicht mehr lief. Nach dem zurückstellen auf -O0 gings aber
> auch nicht mehr, obwohl der Code der gleiche geblieben ist.
EBEN. Das ist nämlich eigentlich so gut wie unmöglich.

von Timer (Gast)


Lesenswert?

Genau deswegen denk ich ja, dass es evtl. an AVR STudio (da stell ich ja 
die Optimierung ein) oder WinAVR liegt
Ich kanns mir halt auch nicht erklären, deswegen frag ich ja ;)

von Karl H. (kbuchegg)


Lesenswert?

Irgend etwas muss dir beim Einschalten der Optimierung
noch passiert sein. Im Code sehe ich nichts was das
von dir beschriebene Verhalten erklären könnte (*). Auch wenn
ich manches anders machen würde, sehe ich eigentlich
nicht, warum da keine Ausgabe aufs LCD mehr erfolgen
sollte.
(*) Stimmt nicht ganz. Ich würde nicht auf flanke_anz == 13
abfragen, sondern auf größer. Wenn dein Programm aus irgend
einem Grund die 13.te Flanke verpasst dann kannst du das
mit einem > immer noch abfangen. Wenn die Variable aber
exakt 13 sein muss, dann kannst du ev. ein Problem haben.

Was ich an deiner Stelle jetzt tun würde:
Den Behandlungscode in main() mal kürzen, so dass die
Interrupts kürzer gesperrt sind.
1
while(1)
2
{  
3
  if (flanke_anz > 12) 
4
  { 
5
    cli();
6
7
    if (ueberlauf==0) 
8
    {
9
        zeitdiff=zeit2-zeit1;      //wenn kein �berlauf dann nur zeit zwischen timestamp's
10
    }
11
    else
12
    {
13
    //bsp f�r 2 �berlaufe:    
14
    //      t1  �1      �2  t2
15
    //    ...|-----|-----------|---|...
16
    //      65535-zeit1     zeit2
17
    //      65635*(ueberlauf-1)
18
        zeitdiff = (65535-zeit1) + 65535 * (ueberlauf-1) + zeit2;
19
    //umgestellt--> zeitdiff=65635*ueberlauf+zeit2-zeit1;
20
    //wenn �berlauf, dann zeit von 1.timestamp zu 1.�berlauf +zeit f�r alle �berl�ufe +zeit von letztem �berlauf bis 2.timestamp
21
    }
22
23
    ueberlauf=0;        //�berl�ufe f�r n�chste Messung r�cksetzen
24
    flanke_anz=0;        //R�cksetzen f�r n�chste Messung
25
    sei();
26
27
    ltoa( zeitdiff, s, 10 ); 
28
    lcd_clrscr();
29
    lcd_puts( zeitdiff );
30
31
    //lcd_puts("/n");
32
    //frequenz=cpu_takt/zeitdiff;
33
    //lcd_puts(dtostrf(frequenz,6,3,s));
34
  }
35
}

von Timer (Gast)


Lesenswert?

von Karl heinz Buchegger:
"Was ich an deiner Stelle jetzt tun würde:
Den Behandlungscode in main() mal kürzen, so dass die
Interrupts kürzer gesperrt sind."

Ist es denn schlimm wenn die Interrupts längere Zeit gesperrt sind?
Gut, ich erhalte keine Messdaten, aber sobald ich die Interrupts wieder 
einschalte sollte doch alles wieder von vorne laufen.

von Rolf Magnus (Gast)


Lesenswert?

> Ist es denn schlimm wenn die Interrupts längere Zeit gesperrt sind?

Naja, ist eben so eine Grundregel, die Interrupts nie länger als absolut 
nötig zu sperren.

> Gut, ich erhalte keine Messdaten, aber sobald ich die Interrupts wieder
> einschalte sollte doch alles wieder von vorne laufen.

Es werden zumindest mit guter Wahrscheinlichkeit die Interrupt-Flags 
deiner beiden Interrupts gesetzt sein, so daß sofort nach dem sei() 
erstmal irgendwelche alten Interrupts von "früher" deine beiden ISRs 
auslösen werden.

von Timer (Gast)


Lesenswert?

"Es werden zumindest mit guter Wahrscheinlichkeit die Interrupt-Flags
deiner beiden Interrupts gesetzt sein, so daß sofort nach dem sei()
erstmal irgendwelche alten Interrupts von "früher" deine beiden ISRs
auslösen werden."

genau deswegen verwerfe ich auch die erstn 2 Flanken und fange erst mit 
der 3. an über 10T zu messen

Kann man die Interruppt-Flags denn nicht löschen bzw. kommen die 
überhaupt wenn Interrupts deaktiviert sind?
Das wäre ja sonst ein grundsätzliches Problem. Ich mache meine Interrupt 
Routinen immer extra klein, da der nächste Interrupt mir ja im Nacken 
hängt. Den Hauptteil von Berechnungen und Co. mache ich deswegen immer 
in der main und stelle vorher die Interruts ab, damit ich Zeit zur 
Rechnung habe.
Ist das jetzt doch nicht so günstig?

von Johannes M. (johnny-m)


Lesenswert?

Timer wrote:
> Kann man die Interruppt-Flags denn nicht löschen bzw. kommen die
> überhaupt wenn Interrupts deaktiviert sind?
Natürlich "kommen" die auch, wenn die Interrupts nicht freigegeben sind. 
Sonst könnte man kein Polling machen. Und natürlich kann man die auch 
von Hand löschen (von wenigen Ausnahmen abgesehen).

von Timer (Gast)


Lesenswert?

OK, ich hab mir mal eine einfache Display Routine geschrieben und Os 
eingestellt, hat funktioniert

Dann hab ich mal ein Blinklicht gemacht mit O0 funktionierts mit Os geht 
das Display nicht, aber die LED's blinken. Wenn ich wieder auf O0 
zurückgehe geht das display auch nicht mehr aber die LED's blinken, 
klingt komisch, ist aber so

Dann hab ich mal mit dem Interrupt rumprobiert. hab einfach den int0 
genommen.
Mit O0 funktionierts mit Os nicht und wenn ich wieder auf O0 zurückgehe 
gehts auch nicht mehr. Diesmal hab ich aber die hex dateien 
zwischengespeichert und siehe da, beim ersten mal mit O0 sind einige hex 
werte geändert als beim 2. mal O0 nach Os???????

Irgend was läuft das schief. Ach so, meist wird die LCD init und das clr 
noch gemacht, zumindest zeigt das Display keine "schwarzen Quadrate"

von Rolf Magnus (Gast)


Lesenswert?

Hast du nach den Änderungen immer wirklich alles neu übersetzt? Wenn 
du im Makefile die Optimierungseinstellungen änderst, wird nicht 
automatisch alles neu gebaut.

von Oliver (Gast)


Lesenswert?

Wie und wo stellst du denn die Optimierungsstufen ein? In den 
AVRStudio-Projektoptionen, oder woanders?

Oliver

von Oliver (Gast)


Lesenswert?

Nachtrag: Vergleiche doch auch mal den Konsolenoutput von Compiler und 
Linker, ob da bei den Läufen mit -O0 irgendetwas unterschiedlich ist. Am 
besten in externe Textfiles kopieren, und mit Winmerge o.ä. ansehen.

Oliver

von Timer (Gast)


Angehängte Dateien:

Lesenswert?

Die Optimierungsstufen stell ich direkt bei AVR Studio ein. Ich hab kein 
extra makefile, sondern stell unter Projekt Options (oder so ähnlich) 
meinen ATMEga32, die 16MHz und halt die Optimierung ein. Dann bekomm ich 
mein *.hex file und "brenne" dann mit PonyProg mein ATMega32.

Habe jetzt kein AVR Studio zur Hand, aber zum Übersetzen nehme ich immer 
den linken der beiden Compilebuttons. Sollte auch so stimmen, denn von 
der Einstellung -O0 nach -Os wird ja auch alles neu Übersetzt, da sollte 
es umgekehrt ja genauso sein.

Konsolenoutput werd ich heut Abend mal anschauen.

von Werner (Gast)


Lesenswert?

Achte doch einfach mal darauf, welche Uhrzeit deine Hex hat. nicht das 
du die ganze zeit eine "andere" hex lädst...

von Timer (Gast)


Lesenswert?

>Mit O0 funktionierts mit Os nicht und wenn ich wieder auf O0 zurückgehe
>gehts auch nicht mehr. Diesmal hab ich aber die hex dateien
>zwischengespeichert und siehe da, beim ersten mal mit O0 sind einige hex
>werte geändert als beim 2. mal O0 nach Os???????

@Werner, also 3 verschienene *.hex Dateien. Die erste mit O0 geht die 
zweite mit Os nicht und die dritte wieder auf O0 eben komischer weise 
auch nicht

von Timer (Gast)


Angehängte Dateien:

Lesenswert?

hier mal die Konsolenmitschnitte von AVR Studio

von Michael U. (amiga)


Lesenswert?

Hallo,

nur mal wegen des Effekts, daß das Display auch mit -O0 dann nicht mehr 
geht: Spannung mal ganz aus und wieder ein?

Das Display wird abgestürzt sein, das bekommt ja keinerlei Reset und 
verbleibt vermutlich in einem undefinierten Zustand nach dem Zugriff mit 
den falschen Timings bei -Os.

Gruß aus Berlin
Michael

von Timer (Gast)


Lesenswert?

Die Sache mit der Spannung war mein erster Gedanke. Hat aber nicht 
geklappt.

von Oliver (Gast)


Lesenswert?

very strange, das alles.

Wenn die hex-Dateien der beiden -O0-"Versionen" unterschiedlich sind, 
gibt es auch Unterschiede in den .lss, .map, oder anderen Dateien?

Und wenn ja, welche?

Welche WinAVR-Version, welche Studio-Version (da der Consolenoutput 
keine size anzeigt, muß das alles ja schon was älter sein)

Schon mal mit frisch installierten, und/oder aktuelleren Versionen 
probiert?

Oliver

von Timer (Gast)


Lesenswert?

Ich hatte erst alles mir den neuen Versionen probiert, hab dann gedacht, 
dass es daran liegt und meine alten Versionen (AVR Studio 4.12, WinAVR 
von 01.2007) wieder installiert, aber war genauso. Zu der Zeit hab ich 
dann auch die Konsolenoutputs gemacht.

von KB (Gast)


Lesenswert?

Hallo
ich arbeite auch mit dem AVR Studio und nutze winavr über das GCC 
Plugin.
Was sein kann das du nach dem zurückstellen ur -O0 nur ein Teil der 
Objekt Files neu Compiliert wurden und somit avr-gcc da einfach nurks 
macht.

hilft eigentlich dann meistens wenn du dann über Build -> ein mal Clean 
sagst und dann klick ich immer Rebuild All an. Sollte eventuell helfen.
Hat mich zumindest auch hinundwieder nerfen gekostet.

MfG Kai

von Timer (Gast)


Lesenswert?

Ich werd mal probieren.

von Fred S. (Gast)


Lesenswert?

Hallo Kai,

> hilft eigentlich dann meistens wenn du dann über Build -> ein mal Clean
> sagst und dann klick ich immer Rebuild All an. Sollte eventuell helfen.

danke für diesen wertvollen Tipp -- nach einigem Haareraufen mit einem 
ähnlichen Problem wie von "Timer" oben beschrieben hat er mich gerettet!

Gruß

Fred

von OliverSo (Gast)


Lesenswert?

> hilft eigentlich dann meistens wenn du dann über Build -> ein mal Clean
> sagst und dann klick ich immer Rebuild All an. Sollte eventuell helfen.

Wobei das Studio eigentlich sehr zuverlässig in der Bestimmung der 
dependencies ist. Wenn das Projekt mit allen benötigten Sourcen richtig 
angelegt ist, dürfte da nichts schiefgehen.

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.