räknas lokala variabler med i minnesåtgången?
Re: räknas lokala variabler med i minnesåtgången?
Man skulle kunna kombinera unions med något variant av lås för att göra det lite svårare att klanta till det
Re: räknas lokala variabler med i minnesåtgången?
Jag tycker inte bara optimeringen av minnesanvändning är imponerande, även optimeringen av kod är imponerande.jesse skrev:Försöker analysera minnesåtgången, och jag får säga att jag är imponerad av GCC's optimering!
Men just när det gäller minnet så är ju AVR enligt beskrivningen designad med många register just för att C-kod ska kunna optimeras bra.
Re: räknas lokala variabler med i minnesåtgången?
Main behandlas som en vanlig funktion, och därför reserveras plats på stacken för lokala variabler i main och även retur adressen.jesse skrev:EDIT: när jag kör lite större funktioner (som i sin tur anropar en massa andra och så kör interrupten dessutom under tiden) så har jag kommit upp i 32 byte som mest. Men jag irriterar mig lite på att stackpekaren ligger på 10EB när main() startar --- vad är det för skit den lagrar i stacken innan? Det kommer väl aldrig att användas då jag aldrig gör retur från main(). SKulle man kunna justera stacken i början och sätta den till 1100 där den borde börja? (Ja AVR är konstig; SRAM börjar på 0x100 och slutar på 0x1100 om jag har 4096 bytes)
Man kan tydligen komma runt det genom att tala om för gcc att det är en "OS_task" eller "OS_main", så slipper man spara undan vissa register och retur adressen.
Kod: Markera allt
int main(void) __attribute__((OS_task)) {
...
};

Re: räknas lokala variabler med i minnesåtgången?
Den där koden gick ju inte bara att klistra in...
Fast jag får ju erkänna att jag inte har en susning om vad jag sysslar med.
Låter lite oroväckande att den inte skulle reservera utrymmen för lokala variabler i main på stacken. Var ska de då lagras nånstans?
Verkar som om OS_main hade fungerat lika bra... men jag är osäker: Add 'OS_main' and 'OS_task' attributes in avr-gcc 4.2.1
Förstår inte riktigt texten. Det finns väl inte så många situationer där interrupt kan ske precis när funktionen main() anropas? Skulle vara om man först aktiverade interrupt (sei), och sedan gjorde "goto 0x0000"?
EDIT2:
kollade disassemby... nu (med OS-task) gör den ändå ett call till main och sparar därmed returadressen på stacken. Om det skulle vara så att main gjorde "ret" någonstans kommer den tillbaks och då avslutas programmet med en JUMP till följande avslutande kod:
Stänger av interrupt + stanna i en oändligt loop.
EDIT: Det här gick bättre:Error 3 expected ',' or ';' before '{' token
Kod: Markera allt
__attribute__((OS_task))
int main(void){
...
};
Låter lite oroväckande att den inte skulle reservera utrymmen för lokala variabler i main på stacken. Var ska de då lagras nånstans?
Verkar som om OS_main hade fungerat lika bra... men jag är osäker: Add 'OS_main' and 'OS_task' attributes in avr-gcc 4.2.1
Förstår inte riktigt texten. Det finns väl inte så många situationer där interrupt kan ske precis när funktionen main() anropas? Skulle vara om man först aktiverade interrupt (sei), och sedan gjorde "goto 0x0000"?
Kanske "naked" är ännu bättre. Varför ha en "ret" i slutet av main när en ändå aldrig ska komma dit?+@item OS_main/OS_task
+@cindex @code{OS_main} AVR function attribute
+@cindex @code{OS_task} AVR function attribute
+On AVR, functions with the @code{OS_main} or @code{OS_task} attribute
+do not save/restore any call-saved register in their prologue/epilogue.
+
+The @code{OS_main} attribute can be used when there @emph{is
+guarantee} that interrupts are disabled at the time when the function
+is entered. This will save resources when the stack pointer has to be
+changed to set up a frame for local variables.
+
+The @code{OS_task} attribute can be used when there is @emph{no
+guarantee} that interrupts are disabled at that time when the function
+is entered like for, e@.g@. task functions in a multi-threading operating
+system. In that case, changing the stack pointer register will be
+guarded by save/clear/restore of the global interrupt enable flag.
+
+The differences to the @code{naked} function attrubute are:
+@itemize @bullet
+@item @code{naked} functions do not have a return instruction whereas
+@code{OS_main} and @code{OS_task} functions will have a @code{RET} or
+@code{RETI} return instruction.
+@item @code{naked} functions do not set up a frame for local variables
+or a frame pointer whereas @code{OS_main} and @code{OS_task} do this
+as needed.
+@end itemize
+
EDIT2:
kollade disassemby... nu (med OS-task) gör den ändå ett call till main och sparar därmed returadressen på stacken. Om det skulle vara så att main gjorde "ret" någonstans kommer den tillbaks och då avslutas programmet med en JUMP till följande avslutande kod:
Kod: Markera allt
00003AF8 CLI Global Interrupt Disable
00003AF9 RJMP PC-0x0000 Relative jump
Re: räknas lokala variabler med i minnesåtgången?
Då main() är den abs. första funktion att anropas och då den aldrig ska lämnas lär interrupt inte hända innan den har startat, det är i den som interrupt aktiveras osv.
Och ja, jag vet att vissa program börjar med en snabb rutin som nollar arbetsminnet, kopierar saker från ROM till RAM men de startar knappast speciellt många interrupt...
Och ja, jag vet att vissa program börjar med en snabb rutin som nollar arbetsminnet, kopierar saker från ROM till RAM men de startar knappast speciellt många interrupt...
Re: räknas lokala variabler med i minnesåtgången?
ehm...
jag har faktiskt ett ställe i koden där det står
Men i och med att jag har cli(); före goto så borde det vara säkert.

Kod: Markera allt
cli();
goto 0x0000;