Arduino a alokace mista pro promenne

Miroslav Mraz mrazik na volny.cz
Čtvrtek Říjen 24 18:56:36 CEST 2019


Ono to není jen o lineárním nebo nějak rozsekaném adresním prostoru. 
Někdy je to jen lenost programátora, který moc nepřemýšlí nad tím jak 
ten kód píše a co s tím pak překladač může dělat. Mě osobně docela dost 
poučil přístup jazyka rust - vše je implicitně konstantní, pokud do toho 
chceme někdy později zapsat, musíme to explicitně vyjádřit už v 
deklaraci. V C/C++ je to naprosto opačně. Jenže pro konstantní objekty 
umí obvykle překladač dělat dost efektivní optimalizace. A je opravdu 
dost málo objektů (proměnných) se kterými je potřeba později nějak hýbat 
i když se to zpočátku nezdá.
Pokud z lenosti napíšeme např.
char * s = "string";
pak gcc vyhradí pro ten "string" jednak místo ve flash (protože někde 
musí být pevně uložen), pak ho zkopíruje do sekce .data, kde pro něj 
také musí být místo. Sice gcc při tomhle obvykle nadává, ale moc na to 
nespoléhejte. O něco lepší je napsat
const char * s = "string";
tady už je "string" uložen v sekci .rodata, ale v sekci .data se vytvoří 
ukazatel s, to není konstantní objekt, můžete klidně udělat const char c 
= s++. A když napíšete
const char * const s = "string";
pak už sice můžete z řetězce číst jen pomocí indexu, ale ten může být 
lokální, tedy v registrech, takže do sekce .data se neukládá nic.
Překladač gcc takhle funguje na všech platformách, takže pokud je sekce 
.rodata nadefinována tak, že se ukládá do flash (což je možné a velmi 
časté), pak to takto funguje i na AVR. To je ale otázka linker skriptu, 
ale protože se s AVR už dost dlouho nezabývám, může to tam být uděláno 
jinak.
Nicméně používat modifikátor const všude tam, kde je to jen trochu možné 
je celkem dobrá praktika, kterou ale využijete spíš v C++, protože tam 
se deklarovat a inicializovat proměnná dá vlastně kdekoli. V dnešním C 
už by to mělo jít ale bez problémů také.

Mrazík

Dne 24. 10. 19 v 14:42 Jan Waclawek napsal(a):
> To je skor prejav toho, ze C (a tym aj C++) nie je pripraveny na koncept
> roznych pamatovych priestorov. Existuje uz asi 15 rokov navrh rozsireni,
> tzv. named address spaces, ale nejako sa neujal. Pre AVR je zhodou
> okolnosti tiez uz asi 10 rokov implementovany
> https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html , ale aj
> "vdaka" arduinu sa zakonzervovalo prave skor pouzitie toho nestandardneho
> atributu __progmem.
> 
> Ono to ma este vselijake relativne zlozite suvislosti najma pre vacsie
> AVRka (nad 64kB FLASH) a aj s kompromisom medzi efektivnym (co sa tyka
> velkosti binaru aj rychlosti vykonavania a ciastocne aj spotreby RAM) a
> "unifikovanym" (t.j. kde netreba rozmyslat) kodom.
> 
> K tomu textu z manualu avr-libc este doporucujem ako doplnkove citanie
> tento tutorial (v podstate len prvy post z celeho vlakna)
> https://www.avrfreaks.net/forum/tut-c-gcc-and-progmem-attribute?name=PNphpBB2&file=viewtopic&t=38003
> 
> 
> wek
> 


Další informace o konferenci Hw-list