arduino - data v PROGMEM

Jaroslav Buchta jaroslav.buchta na hascomp.cz
Pondělí Listopad 3 22:41:03 CET 2014


Krasny roman, hned jsem chytrejsi ;-)
Kazdopadne prave  na ARM architekture se mi libi prave to, ze od pidi 
MCU za 30Kc CM0 az po ctyrjadrove mrchy na 2GHz je vse podobne - jediny 
4GB pametovy prostor obsahujici prakticky vsechno co se da adresovat, 
vsechny registry 32b... I kdyz jsou ruzne MCU dost odlisne celkove, v 
ARM jadru ma clovek jistotu ;-)
Na AVR me vzdycky stvaly ty oddelene adr. prostory, o 8051 a PICech 16 
nemluve, tam to bylo az perverzni :-P

Dne 3. 11. 2014 22:13, Jan Waclawek napsal(a):
> Cele je to o tom, ze programovacie azyky nie su nikdy dokonale presnym
> predpisom, co ma pocitac robit, a je otazne nakolko ma prekladac "uhadnut"
> zamer programatora. Aby som bol konkretny, jazyk C ako taky viacmenej
> predpoklada jednoliaty kus pamate, do ktorej sa da volne po bytoch
> zapisovat a citat. No ale u AVR (a inych 8-bitoch) to tak celkom nie je -
> obvykle maju niekolko roznych druhov pamati, do ktorych sa da a treba
> zapisovat a citat roznym sposobom - inak sa pristupuje k relativne malemu
> "operacnemu" kusku RAM, inak k vacsiemu kusu (typicky nepriamo cez pomocne
> registre), inak sa pristupuje k FLASH a inak k EEPROM. To "inak" znamena
> uplne iny druh instrukcii v asembleri. Niektore prekladace dovolia
> programatorovi predpisat, kam sa ma premenna zapisat a na zaklade toho
> predpisu dokazu "uhadnut", ako k premennej pristupovat. No ale gcc je
> mamut, ktory je orientovany na "normalne" pocitace a nie na nejake
> pidi8-bity, takze tam taky mechanizmus nie je (resp. donedavna nebol, ale
> o tom neskor). Preto implementatori suity okolo avr-gcc si museli pomoct.
> A najjednoduchsie je pomoct si tak, ze sa necaha do kompilatora (gcc), ale
> do tej suity okolo, lebo ta je jednoduchsia. To zahrna asembler, linker a
> jeho "konfiguracny" subor (linker script), a zakladnu kniznicu (avr-libc).
> Najjednoduchsie je cahat do toho posledneho, lebo to je dokonale nezavisle
> od vsetkych ostatnych "targetov" (cielovych architektur, pre ktore sa
> preklada) a sluzi len a len pre AVR.
>
> Ta finta bola nasledovna: GCC ma rozsirenie (tzv. atributy,
> https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes
> ), ktorymi sa da predpisat umiestnenie premennej do tzv. sekcie (section)
> - chapte to ako skupina premennych, ktore sa umiestnuju od nejakej danej
> adresy. Tento predpis kompilator jednoducho odovzda asembleru (prilepi ho
> k asemblerovskej definicii premennej) a ten to znova len odovzda linkeru
> (prilepi to v tabulke symbolov v object subore (.o) k symbolu patriacemu k
> premennej) - ak sa ziadne nepredpise, premenna sa podla toho, ci je
> inicializovana alebo nie, umiestnuje do sekcie .data alebo sekcie .bss ,
> ktore su nasledne umiestnene linkerom v RAM a inicializacne hodnoty pre
> sekciu .data su umiestnene v pripade AVR za samotny program do FLASH, a k
> programu linker "prilepi" inicializacny kod, ktory pri spusteni programu
> (po resete) nakopiruje tieto udaje do .data v RAM a vynuluje celu oblast
> .bss v RAM (lebo C predpisuje mat explicitne neinicializovane globalne a
> static-lokalne premenne implicitne inicializovane na 0).
>
> Vytvoril sa teda specializovany atribut (__attribute__((progmem))
> https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#index-g_t_0040code_007bprogmem_007d-AVR-variable-attribute-3132
> ), a bol upraveny linker, aby takto oznacenu premennu umiestnil do FLASH
> pamate (do sekcie .progmem) spolu s jej inicializacnou hodnotou. Do
> avr-libc bol vytvoreny hlavickovy subor <avr/pgmspace.h>, v ktorom bolo
> definovane makro PROGMEM, co nie je nic ine iba ten atribut.
>
> Lenze do avr-gcc nebolo dorobene nic, co by umoznilo kompilatoru "uhadnut",
> ze ak takto oznacenu premennu niekto pouzije v programe, tak sa musi citat
> pomocou inych instrukcii, takych, ktore citaju z FLASH (instrukcie LPM a u
> "velkych" AVR este aj ELPM). Preto, ak by ste takuto premennu pouzili
> "obycajnym" sposobom, kompilator nijako neprotestuje, ale vygeneruje
> instrukcie, ktore citaju z rovnakej adresy ale v RAM, t.j. nerobia to, co
> chcete. Toto bolo obidene tym, ze do <avr/pgmspace.h> boli doplnene makra
> (typu pgm_read_byte() apod.), ktore su implementovane pomocou inline
> assembleru (ktory je mimochodom v gcc neobvykle siroko parametrizovatelny
> a daju sa do neho prenasat symboly z C, inak by sa to implementovat
> nedalo). Cenou za tento postup je, ze do tychto makier vstupuje *adresa*
> premennej, nie premenna ako symbol, t.j. treba pred nu pisat to &.
>
> Neskor boli vytvorene este aj pomocne "hacky" na pracu s retazcami, lebo
> tie su najcastejsia pricina problemu "prisiel som o celu RAM a neviem
> preco" - lebo retazcove konstanty, ktore clovek bezmyslienkovite pouzije
> napr. v strcpy(blah, "BlahBlah"), su (pre programatora anonymne)
> inicializovane polia znakov umiestnene do RAM - to je logicke, kedze
> nativne gcc pozna len premenne v RAM, aj strcpy ocakava premenne v RAM,
> nikde inde. Takze do kniznice boli doplnene funkcie (a do <string.h>
> prototypy), ktore maju podobne nazvy aj syntax ako standardne funkcie zo
> <string.h>, len maju "priponu" _P, ocakavaju pointer do FLASH a pouzivaju
> instrukcie na citanie z FLASH; a do pgmspace.h bolo doplnene makro PSTR(),
> pomocou ktoreho sa daju definovat retazcove konstanty do FLASH
> (http://www.efton.sk/tmp/C_ch50.pdf a linky tam uvedene).
>
> Neskor boli doplnene do pgmspace.h aj prostriedky na pristup ku >64kB FLASH
> (bo tie horeuvedene na to nestacia); ak ma niekto zaujem o tuto
> specializovanu oblast, tak mozeme aj o tom pokecat.
>
> ----
> gcc pre C++ (oznacovane aj spustane ako g++), ktore pouziva (dost zbytocne)
> Arduino, malo s atributmi rozne problemy, takze najdete pre verzie avr-g++
> pred tusim 4.6 staznosti ktore odkazuju na nepozitelnost PSTR() a podobne.
>
> ----
>
> Medzicasom standardizacna komisia C vytvorila draft, ktory okrem ineho
> obsahuje aj rozsirenia pre pristup k viacerym druhom pamate (tzv. named
> address spaces), a toto bolo do gcc niekedy okolo verzie 4.6
> implementovane vo vseobecnej (navonok nepouzitelnej, len ako predpriprava)
> podobe, pricom od verzie 4.7.2 existuje avr-specificka implementacia,
> ktorej autorom je Georg-Johann Lay (na avrfreaks.net nick SprinterSB),
> https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html#Named-Address-Spaces
> . O tom mozeme tiez pokecat, ale kedze named address spaces v g++ nie su a
> nikdy ani nebudu (bo C++ standardizacna komisia sa tomu brani a gcc sa
> snazi drzat standardu), pre Arduino je to nerelevantne.
>
> Snad to trocha ozrejmilo problematiku.
>
> wek
>
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list


---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com



Další informace o konferenci Hw-list