Hallo!
Ich habe vor kurzem AVR GCC 4.1.1 installiert. seit dem wird meine
Option
-minit-stack=0x800400
Ignoriert.
der Aufruf des Compilers der main.c in welcher sich die main funktion
befindet ist:
avr-gcc -c -fmessage-length=0 -Wall -Wstrict-prototypes
-Wa,-adhlns=../main.lst -mmcu=atmega128 -minit-stack=0x800400 -Os
-fshort-enums -fpack-struct -funsigned-char -funsigned-bitfields
-std=gnu99 -save-temps -dB -DUART_RX_BUFFER_SIZE=512
-DUART_TX_BUFFER_SIZE=64 -o"main.o" "../main.c" && \
echo -n 'main.d' ./ > 'main.d' && \
Ich nutze Eclipse unter WinXP mit dem AVR Plugin aus dem Thread
Beitrag "Eclipse und WinAVR"
habe mir mal die Assamblerdatei main.s angeschaut. bei GCC version 3.4.6
steht da
.global main
.type main, @function
main:
/* prologue: frame size=5 */
ldi r28,lo8(0x800400 - 5)
ldi r29,hi8(0x800400 - 5)
out _SP_H_,r29
out _SP_L_,r28
/* prologue end (size=4) */
GCC 4.1.1 macht daraus
.global main
.type main, @function
main:
/* prologue: frame size=5 */
push r16
push r17
push r28
push r29
in r28,__SP_L__
in r29,__SP_H__
sbiw r28,5
in _tmp_reg_,__SREG__
cli
out _SP_H_,r29
out _SREG_,__tmp_reg__
out _SP_L_,r28
/* prologue end (size=12) */
alles beim gleichen aufruf des compilers
als erstes würde ich sagen, das der Prolog für die main funktion zu
aufgeblasen ist, scheit als würde der compiler denken, er könne aus ihr
zurückspringen.
weiterhin habe ich festgestellt, das bei GCC 3.4.6 der Stack 2 mal
initialiesiert wurde. einmal auf 0x10FF und dann in der main funktion
auf 0x0400 wie gewünscht.
habt ihr Eine idee wie ich GCC 4.1.1 dazu bringen kann, das er den Stack
wert übernimmt??
Vielen Dank im Vorraus
Stefan
Stefan wrote:
> -minit-stack=0x800400> Ignoriert.
Aus dem Bauch raus würde ich sagen, diese Option hat mittlerweile
keinen Sinn mehr.
> als erstes würde ich sagen, das der Prolog für die main funktion zu> aufgeblasen ist, scheit als würde der compiler denken, er könne aus> ihr zurückspringen.
Ja, main() ist eine normale Funktion geworden.
Deklariere sie als
int __attribute__((noreturn))
main(void)
{
...
}
Eigentlich sollte es wohl besser noch ein __attribute__((c_task)) oder
sowas geben, das wie noreturn wirkt, aber trotzdem noch einen
return-Wert gestattet. Der Unterschied hat aber nahezu nur
akademischen Wert.
> weiterhin habe ich festgestellt, das bei GCC 3.4.6 der Stack 2 mal> initialiesiert wurde. einmal auf 0x10FF und dann in der main> funktion auf 0x0400 wie gewünscht.
Richtig. Die zweite Initialisierung (das ist die, die man mit
-minit-stack beeinflussen konnte) ist aber schon lange Kokolorus
gewesen. Der Stack muss deutlich vor main() initialisiert werden, da
sonst insbesondere die C++-Konstruktoren keinen Stack haben.
Unabhängig davon, ob man nun main() wirklich als normale Funktion
behandelt werden sollte oder nicht (das hat uns in der jetzigen Form
ein wenig kommentarlos der ATmega256x-Patch mitgebracht), die
Geschichte mit der Stack-Initialisierung in main() (und damit auch die
-minit-stack Option) gehört auf den Müllhaufen der AVR-GCC-Geschichte
entsorgt.
> habt ihr Eine idee wie ich GCC 4.1.1 dazu bringen kann, das er den> Stack wert übernimmt??
Ja, so wie auch schon die früheren Compiler, vermutlich mehrere Jahre
lang bereits:
-Wl,--defsym=__stack=0x800400
Hallo Jörg!
Vielen Dank für die Promte Antwort!
Funktioniert!
Habe auch das mit dem
int __attribute__((noreturn))
main(void)
{
...
}
Versucht, ändert aber nicht viel an dem Prolog der main funktion. auser
das 2 push weniger sind. wenn mir mal die paar bytes fehelen, kann ich
mich ja daran nochmalmachen.
Danke Stefan
Stefan wrote:
> Habe auch das mit dem>> int __attribute__((noreturn))> main(void)> {> ...> }>> Versucht, ändert aber nicht viel an dem Prolog der main funktion. auser> das 2 push weniger sind.
Sorry, ja, das muss auch
1
int__attribute__((noreturn,naked))main(void)...
sein.
Ich weiß, der GCC klagt dann darüber dass eine noreturn-Funktion
einen return-Wert hätte bzw. bei Deklaration mit void umgekehrt,
dass main() nicht vom Typ int ist. Damit muss man bis zu einer
,,richtigen'' Reparatur wohl erstmal leben.
Hallo Jörg!
wenn ich das naked dazu nehme, dann wirds ganz wild, und der Compiler
jammert:
../main.c:31: internal compiler error: in start_function, at
c-decl.c:6014
Please submit a full bug report,
with preprocessed source if appropriate.
wers bei no return belassen, vielleicht klappts bei der nächsten GCC
version. ich werds mir merken.
Gruß Stefan
Stefan wrote:
> ../main.c:31: internal compiler error: in start_function, at> c-decl.c:6014> Please submit a full bug report,> with preprocessed source if appropriate.
Dann bitte tu genau das. Streich dein Programm so weit zusammen, dass
der ICE (internal compiler error) reproduzierbar ist, und reiche einen
Bugreport bei gcc.gnu.org ein.
> vielleicht klappts bei der nächsten GCC version.
Wenn es keiner als Bug berichtet, warum sollte sich was ändern?
Hmm, als WinAVR-Bugreport kommt er nicht zu den GCC-Entwicklern.
Anyway, ich kann das für meinen Compiler nicht reproduzieren. Wenn du
einen Sourcecode hast, mit dem es reproduzierbar ist, dann würde ich
mich weiter drum kümmern wollen. Bitte häng' das einfach an den
WinAVR-Bugreport dran.
Tja, ich habe das mittlerweile auch schon mit Eric Weddington
diskutiert, irgendwas scheint beim WinAVR-Compiler anders zu sein
als bei meinem. Ist auch ein GCC 4.1.1, aber ich bekomme diesen
Bug nicht getriggert, egal womit. Es gibt zwar minimale Differenzen
in den Patches zwischen WinAVR und FreeBSD, aber ich habe die
Patches seinerzeit verglichen und hätte nicht gedacht, dass bei
WinAVR einer dabei ist, der zu solchen Effekten führen könnte...
Wir haben auch nochmal die formale Syntaxbeschreibung der
Attribute im GCC-Handbuch nachgelesen, ich bin mittlerweile der
Meinung, dass aus GCC-Sicht folgendes technisch exakter wäre:
1
__attribute__((noreturn,naked))intmain(void){
2
...
3
}
also die Attribute vor der Funktion. Kannst du mal probieren, ob
das ein Unterschied ist für dich?
Ansonsten, was offenbar auf jeden Fall funktioniert ist, dass man
die Attribute nur in eine Prototypdeklaration steckt:
1
intmain(void)__attribute__((noreturn,naked));
2
int
3
main(void){
4
...
5
}
Idealerweise sollte man auch schreiben können
1
int
2
main(void)__attribute__((noreturn,naked))
3
{
4
...
5
}
aber dafür sagt das GCC-Handbuch ausdrücklich ``not yet implemented''.
> ergibt den selben Fehler wie oben.
OK.
> ..., ist aber auch nur 2 bytes kleiner als ein normales int> main().
Naja, mehr scheint's dann nicht zu sparen zu geben. Ich habe
damit jedenfalls (wie gewünscht) keinen Prolog mehr in main().
naked allein genügt eigentlich auch.
>>../Main.c:3: error: expected ',' or ';' before '{' token
Ja, ``currently not supported'' eben.
Ich kann den Crash von WinAVR gcc 4.1.1 bestätigen, ich bekomme das auch
wenn ich
1
__attribute__((noreturn,naked))intmain(void)
2
{
3
}
verwende.
Alternativ auch bei meiner Hauptschleife (Unterfunktion von main), die
habe ich wahlweise auch so dekoriert.
Wenn ich hingegen nur den Prototypen dekoriere, also
1
__attribute__((noreturn,naked))intmain(void);
2
intmain(void)
3
{
4
}
dann klappts. Spart bei bei main() nur 2 Bytes, hingegen bei der
Hauptschleife 18 Bytes! Anscheinend hat er bei main() schon was erkannt.
Ich habe noch nicht ins Disassembly geguckt.
Hallo!
Mit dem Prototype
int main(void) __attribute__((noreturn, naked));
und dann:
int main(void) {
}
funktioniert es bei mir, und der Prolog wird auf 0 Byte
zusammengestrichen, jedoch wie schon befürchtet mit der Warnung:
../main.c: In function 'main':
../main.c:102: warning: function declared 'noreturn' has a 'return'
statement
Finished building: ../main.c
ansonnsten hast du ja deine Informationen die du brauchst, oder Jörg.
Gruß Stefan
ich hab die haessliche warning: `noreturn' function does return so
wegbekommen, allerdings in einer beliebigen Fkt, nicht unbedingt main.
Der Compiler meckert sonst, wenn er nicht eine Funktion erkennt, von der
er weiss, dass sie nie zurueckkommt (wie zB exit)
#if !defined(_lint_)
#define _NORETURN_ for (;;) continue
#else
#define _NORETURN_
#endif