geh hier völlig kaputt...
also sollte eig. echt gehen
compileroptionen :
-Wall -g2 -gstabs -O3 -funsigned-char -funsigned-bitfields
-mmcu=atmega2561 -DF_CPU=14745600UL
-avr-gcc version:
4.1.1 (WinAVR 20070122)
ist doch alles da :
- F_CPU -define (stimmt mit MCU-quarz überein) >> quarz-clk auch
nachgemessen
- divide clk by 7 fuse-bit ist nicht gesetzt
- optimierung sit an
code
1
#include ...
2
#include<util/delay.h>
3
intmain()
4
{
5
//....
6
7
8
while(D_TRUE)
9
{
10
// AH_HandleAction(8);
11
PORTE^=(0x80);
12
_delay_ms((double)1.0);
13
VolDummy++;
14
15
}
16
return(0);
17
}
wieso macht der delays > 100ms an dem togglenden-ausgangspin ???
in der libc-docu steht noch was:
"and applications that otherwise do not use floating-point calculations
will experience severe code bloat by the floating-point library routines
linked into the application."
das sagt doch nur das der code sehr viel größer werden kann ...
ich kann mir nicht mehr helfen
wenn ich übrigensm Opuimierung ausschalte dann haut es hin mit der
delay-zeit.
es ist doch nun egal was ich schreibe .. mit der "1" gehts auch nicht
.. andere hätten wieder gemeckert weil der Cast (double) fehlt .
es geht nicht !
>> Compilefähiger Code? << ??
weil die zeit sich so beeilt wrote:
> es ist doch nun egal was ich schreibe ..
(double)1.0 ist doppelt gemoppelt. Die Konstante 1.0 ist bereits
vom Typ double.
> mit der "1" gehts auch nicht
Hatte ich auch nicht erwartet. Die Bemerkung bezog sich nur
darauf, dass der C-Standard dir die Konvertierung der Konstante
1 (vom Typ `int') in den Typ `double' als Automatismus garantiert.
> .. andere hätten wieder gemeckert weil der Cast (double) fehlt .
Es gibt keinen plausiblen Grund für den Typecast. Der einzige dieser
Tage noch plausible Grund wäre die Benutzung einer Integer-Konstanten
als double-Argument innerhalb einer variablen Argumentliste, also
bspw.:
1
printf("%f\n",(double)3);
Allerdings braucht bereits diese Form keinen Typecast mehr:
1
printf("%f\n",3.0);
>>> Compilefähiger Code? << ??
Ja, was sollen wir mit deiner Aussage ,,Es geht nicht!'', ohne dass
wir compilierfähigen Code von dir sehen würden, mit dem man das
nachvollziehen kann?
Da diese Makros ganz offensichtlich für den Rest der Welt (im Rahmen
ihrer dokumentierten Bereiche) funktionieren, muss der Fehler ja
irgendwo in deinem Code und/oder deinen Compileroptionen liegen,
daher muss man sich das halt angucken können.
ah stop ..
vor der schleife standen inits .. kA an was es liegt aber irgendwas
machen die mit der delayzeit .
Interrupts / ..
hier verhaut sich alle gegenseitig .. kein bock mehr .
andere Frage ..
die sache mit den Volatile-def. und das ganze zeug wo der Optimizer
einfluss haben kann - ist das "im" c-Standart festgelegt ?
ich mein irgendjemand muss ja sagen was optimiert werden kann und was
nicht
in so einem C-code .
oder wie ist das?
hab kein informatik studiert ... hatte nur mal ein semester
C-programmierung während Kommunikationstechn.Studium
da war nie die rede von volatile und optimierung(s-verhinderung) .
weil die zeit sich so beeilt wrote:
> Interrupts / ..
Die müsstest du sperren, wenn die Delays genau werden sollen.
Aber dann verzichtest du besser auf die Delays und organisierst
das Timing gleich mit Timern und Interrupts.
> andere Frage ..
Warum keinen anderen Thread?
> die sache mit den Volatile-def. und das ganze zeug wo der Optimizer> einfluss haben kann - ist das "im" c-Standart festgelegt ?
Der C-Standard ist ein "as if"-Standard: eine Implementierung muss
sich im Ergebnis so verhalten, als hätte sie den Quellcode so
compiliert, wie er aufgeschrieben worden ist. Diese Regelung gibt
dem Compiler weitgehende Freiheit, was er dabei alles optimieren
kann.
Die Definition für volatile beschreibt dabei, dass die Daten eines
als volatile gekennzeichneten Objekts jeweils an den sogenannten
sequence points den Daten entsprechen müssen, die sich beim formalen
Abarbeiten der dem Standard zu Grunde liegenden abstrakten Maschine
ergeben würden. Das bedeutet letztlich, dass über diese sequence
points hinweg der Compiler keine Daten eines volatile-Objekts
zwischenspeichern darf.
> hab kein informatik studiert ...
Ich auch nicht.
> da war nie die rede von volatile und optimierung(s-verhinderung) .
Ein ernsthaftes Manko.
Jörg Wunsch wrote:
> Die Definition für volatile beschreibt dabei, dass die Daten eines> als volatile gekennzeichneten Objekts jeweils an den sogenannten> sequence points den Daten entsprechen müssen, die sich beim formalen...
Was ist denn ein "sequence point"?
> ...Abarbeiten der dem Standard zu Grunde liegenden abstrakten Maschine> ergeben würden. Das bedeutet letztlich, dass über diese sequence> points hinweg der Compiler keine Daten eines volatile-Objekts> zwischenspeichern darf.
IMHO trifft das nicht genau, was volatile macht/machen soll, etwa wenn
das Lesen eines SFRs einen Effekt auf die Maschine hat. Hier wird nichts
zwischengespeichert:
1
SFR;
Der Wert in SFR muss gelesen werden, objwohl er nicht verwendet wird.
"volatile" bedeutet also, daß jedesmal, wenn der Compiler im Fluß an
einen so gekennzeichneten Zugriff kommt, er diesen auscodieren muss.
Oder ist das gleichbedeutend mit deiner Formulierung?
brauch da mehr infos zu ... (volatile und das ganze zeug was man braucht
um an hardware rumzuschreiben/lesen)
ich hoffe ich find da was geeignetes zu im netz ...
jo danke ..
ich arbeitet an einem zusammengeschuhsterten Projekt ... hab viel
quelltext so bekommen und nur angepasst ...
nach und nach ging einiges auf dem Board : UARTS, ETH, .. und dann
hab ich mal fürn Performance test (Ethernet) mal die optimierung
angeschaltet .. und ab ging die post - aber nur bei dem einfachen test
halt . alles andere verabschiedete sich ...
so jetzt versuch ich hier das wieder zum laufen zu bekommen - aber
zurzeit seh ich nur noch schwarz .. durch die Opt. kommt es mir vor
gerät alles durcheinander.
-- nice weekend !
weil die zeit sich so beeilt wrote:
> so jetzt versuch ich hier das wieder zum laufen zu bekommen - aber> zurzeit seh ich nur noch schwarz .. durch die Opt. kommt es mir vor> gerät alles durcheinander.
Nö, die Optimierung bringt nichts durcheinander.
Sondern der Quelltext ist durcheinander bzw. Knaup. Bedank dich bei
demjenigen, der's verbockt hat...
Immer dieses Gemecker über die Compileroptimierung :-(
Optimiert der Compiler nicht, heißt es:
Wääääääh, der Code ist so lang, wääääh, mein Flash ist voll, wääääh, das
läuft so langsam, wäääääh, sieht der Compiler das denn nicht?
Optimiert der Compiler, heißt es
Wäääääh, der macht mein Programm kaputt, wääääh, warum geht das nicht,
wääääh, ich kann nicht debuggen, wääääh, warum macht der Compiler das
nicht so?
Als Compilerbauer hätte ich aus Frust schon längst alle User
totgeprügelt.
Als Kompensation gibt's die Momente in denen Leute erst laut "Compiler
baut Mist" brüllen um dann kurz drauf peinlich berührt den Schwanz
einzuziehen. Die Prügeln sich sozusagen selber, das spart Arbeit ;-).
ja 'schuldigung
ich mein - bin wie gesagt relativ neu in der szene C und hardware.
und wenn man nie was von optimierung durch den Compi. gehört hat
geschweige denn von Volatile - Variablen ( hab übrigens am WE mal in
einige ebooks gesehn zu dem thema - entweder steht garnix drin oder wenn
ein viertelseitiger abschnitt ohne wirkliche informationen >> liegt
wohl daran das diese bücher eher für den reine PC -programmierung ohne
direkten hardwarezugriff gemacht worden sind ) .
und dann fängt man so an in der erwartung: "C" geht schon sein gang !
und das macht es auch bis zum tag wo jmd zu dir kommt und sagt :"
schalt doch mal optimizer an!" ... und du beginnst theoretisch von vorn
...
also so kommt mir es vor ..
ohne sich das Compiler_manual durchzulesen (Kapital Optim.) kann man ja
nicht wissen wie man programmieren muss damit trotz Opt. der zweck
erfüllt wird. und wenn man sich dort die einzelnen Optionen ansieht
die die jeweilige Opt.Stufe einschaltet - da brauch man schon ne weile
um das in den kopf zu bekommen was man so beachten muss beim prog´n.
>> wär vielleicht auch nochmal was das in dem AVR-Tutorial VERSTÄRKT zu erwähnen
ist: Optimierung: WAS?(wird verändert)-WANN?/Optim.-Stufe
oder halt verweis aufs GCC manual - dass man sich dazu vorher mal einen
kopf macht ...
ich hab noch bis 31.1. zeit - dann is projektabgabe - ich hoffe das wird
noch was bis dahin
Falsche herum gedacht. Du solltest berücksichtigen, was der Compiler per
Sprachdefinition nicht optimieren darf und davon ausgehen, dass er
alles andere optimieren darf. Sonst rennst du bei jedem Compiler und
jeder Version erneut gegen die Wand.
hmm .. ja ..
eine while(1) - schleife (ziehmlich ohne inhalt) optimiert er doch
weg/um oder ?
die ist doch aber laut sprachdef. nicht unzulässig ...
ich kenn e mich mit der sprachdefinition nicht 100%ig aus ..
aber auch z.B. das 2mal - hintereinander lesen derselben adresse (nicht
volatile) (vielleicht allgem. formuliert) ... ist das in der sprache
definiert, dass man da volatile benutzen muss ??
>eine while(1) - schleife (ziehmlich ohne inhalt) optimiert er doch>weg/um oder ?
Eine while(1)-Endlosschleife optimiert der Compiler nicht weg. Eine
leere for(int i=0;i<100;i++);-Schleife dagegen kann wegoptimiert werden.
>aber auch z.B. das 2mal - hintereinander lesen derselben adresse (nicht>volatile) (vielleicht allgem. formuliert) ... ist das in der sprache>definiert, dass man da volatile benutzen muss ??
Eher umgekehrt: C kennt keine Variablen bzw. Speicherstellen mit
"Nebenwirkungen". Zweimal hintereinander lesen der selben Adresse ergibt
nach Sprachdefinition zweimal den selben Wert, also kann der Compiler
das auf einmal Lesen reduzieren - oder auch auf gar nicht lesen, weil
der Wert z.B. noch in einem Register steht. Ebenso ist per
Sprachdefinition die Reihenfolge von Lesezugriffen nicht festgelegt.
Auch die darf der Compiler verändern.
Daraus folgt ganz einfach: Wenn eine Adresse im Speicher Nebenwirkungen
hat (Hardwareregister, ,die sich "von selbst" ändern, Steuerregister,
denen es nicht egal ist, in welcher Reihenfolge oder ob sie einmal oder
zweimal geschrieben werden, usw.), mußt du das dem Compiler das
mitteilen. Ebenso bei Codeabschnitten, die einfach nur Zeit verbrauchen
sollen.
Oliver
weil die zeit sich so beeilt wrote:
> eine while(1) - schleife (ziehmlich ohne inhalt) optimiert er doch> weg/um oder ?
Probiere es aus. Die Endlos-Schleife wird nicht wegoptimiert. Wäre ja
noch schöner!
Wenn sowas kommt, ist das ein dankbares Opfer für eine Wegoptimierung...
{
int i = 10;
while(i)
i--;
}
Da gibt es eine lokale (!) Variable i, die nur runtergezählt wird und
nach dem Block verschwunden ist/nicht mehr gültig ist/nicht mehr benutzt
wird. DAS kann der Compiler in der Optimierung ganz rausschmeissen.
Der Unterschied zu while(1);?
Ein einem Fall geht es nach dem while weiter und im anderen Fall nicht.
Wo es nicht weitergeht, muss der Compiler das auch beachten!
Und im gemischten Fall?
{
int i = 10;
while(1)
i--;
}
Tja. Nach der Optimierung kann das so aussehen:
{
while(1);
}
Anders, wenn die Variable i in anderen Funktionen / Statements benutzt
wird also global ist oder eine lokale Variable ist die nach dem
while-Block verwendet wird hier z.B. als Returnwert.
int foo(void)
{
int i = 10;
while(i)
i--;
return i;
}
Dann muss tatsächlich runtergezählt werden. Optimierbar ist dann wie das
gemacht wird.
Der Compiler könnte so optimieren, dass nicht 10x -1 gerechnet wird,
sondern nur einmal -10. Im Prinzip könnte der Compiler dann die
while-schleife in Einzelstatements aufrollen und die Einzelstatements
zusammenfassen.
Oder Compiler kann als Speed-Optimierung i aus dem langsamen Speicher
lesen, in einem schnellen Register halten/runterzählen und erst am Ende
der Schleife an eine Stelle im langsamen Speicher zurückschreiben.
{
volatile int i = 10;
while(i)
i--;
}
Noch anders, wenn die Variable i als volatile gekennzeichnet ist. DANN
muss der Compiler immer damit rechnen, dass die Variable anderswo eine
Rolle spielt also gelesen/geschrieben wird. Die Variable wird bei jedem
Zugriff (Prüfung auf 0, Substraktion) aus dem Speicher gelesen und
geschrieben.
weil die zeit sich so beeilt wrote:
> und wenn man nie was von optimierung durch den Compi. gehört hat> geschweige denn von Volatile - Variablen ( hab übrigens am WE mal in
Eine Rechenaufgabe:
1
a = 1
2
b = a+a;
Frage: Wie groß ist b?
2?
Nö, der Wert ist 14, denn ich hab a nach der Zuweisung heimlich
verändert. Ätsch.
Genau so geht's deinem C/C++-Program, wenn ein Interrupt eine Variable
verändert und diese nicht volatile ist.
Wenn der Compiler denkt (bzw. denken darf) b sei 2, dann wird er meine
Änderung nie mitbekommen.
weil die zeit sich so beeilt wrote:
> und das macht es auch bis zum tag wo jmd zu dir kommt und sagt :"> schalt doch mal optimizer an!" ... und du beginnst theoretisch von vorn> ...
Aus diesem Grunde sollte man die Optimierung ja einfach von vornherein
einschalten, auch wenn dies das Debuggen manchmal etwas erschwert.
Sonst, in der Tat: du debuggst zweimal.
weil die zeit sich so beeilt wrote:
> und das macht es auch bis zum tag wo jmd zu dir kommt und sagt :"> schalt doch mal optimizer an!" ... und du beginnst theoretisch von vorn> ...
Das wird in der Regel kommen, weil ohne Optimierung grottenschlechter
Code erzeugt wird.
Mal grob geschätzt, entspricht das Ausschalten der Optimierung einer
Reduzierung der Quarzfrequent von 20MHz auf 1MHz.
Es ist auch grundfalsch, dann sämtliche Variablen als volatile zu
definieren.
Es betrifft eigentlich nur die Variablen für den Datenaustausch mit
Interrupts.
Und dabei gibt es noch Atomicity zu beachten, sonst gibts race
conditions.
Durch race conditions sind schon Leute gestorben:
http://courses.cs.vt.edu/~cs3604/lib/Therac_25/Therac_1.html
Peter