Jak umístit proměnnou na absolutní adresu v AVR+GCC ?

No ved presne o tomto (aspon myslim :slight_smile: ) cely cas hovorime.

Ja osobne skladam aplikaciu tak zo siestich az dvadsiatich samostatnych C suborov z ktorych sa kazdy stara o nieco ine. AD prevod, zobrazenie na display, sprava tlacitok a pohyb v menu, komunikacia - kazda pre ine protokoly, sprava IO atd. Podla potreby si zoberiem prislusne C-cka a aplikaciu si jednoducho vyskladam ako potrebujem. Potrebujem navonok (komunikacia, display) prezentovat vysledky ich cinnosti, respektive potrebujem aby spracovavali vysledky nejakych inych casti programu. Aby neboli jednotlive casti medzi sebou pevne zviazane a nevolali si navzajom funkcie ktore sa staraju o zapuzdrenie premennych, mam jednu aplikaciu - hlavnu, ktora okrem casovania a spustania jednotlivych “aplikacii” spravuje velke pole vseobecnych premennych (256-1024B, skratka podla potreby). Jednotlive aplikacie si z tohto pola beru hodnoty (riadenie od teploty si zoberie nameranu hodnotu teploty z definovaneho indexu pola) alebo vysledky svojej cinnosti do tohto pola vkladaju (napriklad stav rele pre riadenie teploty a ina aplikacia zabezpeci nastavenie rele na zaklade hodonty premennej v poli).

Aby som sa nestratil v tom, ktora aplikacia vyuziva aky index, Tieto indexy spravujem cez jeden jediny subor s nazvom global_adr.h. Ak chcem nieco zmenit, alebo pridat, kuknem don a hned je mi jasno ktore indexy su este volne, respektive ktore by bolo vhodnejsie inak preskupit, aby sa pri komunikacii dalo efektivnejsie nacitat viac i navzajom nesurodych hodnot.

Subor global_all.h obsahuje udaje napriklad

#define ADR_AD_PREVOD 8 // index 8  a dalsie styri obsahuju surovy vysledok AD prevodu pred kalibraciou

#define ADR_AD_KALIB_PRUD 12 // hodnota meranej veliciny, napr. napatie alebo prud po zakladnej kalibkracii
#define ADR_AD_FYZIKALNA_VELICINA 16 // hodnota napr. tlaku, teploty v stupnoch

#define ADR_PARAM_RIADENIA 20 // premenne urcene pre modifikaciu riadenia


//...

Pricom prevod medzi prudom a fyzikalnou velicinou sa moze starat funkcia, ktora so samotnym AD prevodom nema absolutne nic spolocne.

Vediem si samostatne pole pre premenne v EEPROM a samostatne pole pre premenne v RAM. Pri komunikacii viem aky index ma zaujima (poznam obsah suboru global_adr.h) a preto si vyziadam napriklad 12 wordov od indexu (subadresy) 8 a mam v ramci jednej komunikacie nacitane surove data, kaliborvany udaj napriklad vstupneho prudu (zariadenie viem skontrolovat pomocou prudoveho kalibratora) a nakoniec to co ma zaujima najviac, hodnotu fyzikalnej veliciny. Viem si tak skontrolovat cinnost programu na vsetkych stupnoch AD merania. Ak sa za touto adresou nachadzaju dalsie suvisiace hodnoty, kludne mozem nacitat bajtov aj sto. Usporiadane ich mam tak ako potrebujem. Kedze uplne vo vsetkych programoch sa odvolavam na textove hodnoty za #define, aj po ich poprehadzovani a znovuprelozeni si vsetky casti navzajom rozumeju a to vratane komunikacie v PC. Vyhoda tohto riesenia je v tom, ze jednotlive casti mozem testovat a ozivovat bez toho aby boli pevne zviazane s castami programu ktore este neexistuju, je vyrieseny problem atomickeho nacitavania udajov z logicky roznych casti programu (AD prevod, pocitanie impulzov, stavy binarnych vystupov mozu byt ulozene tesne za sebou) ak si ich indexy vhodne usporiadam, jednotlive casti sa lahko i na dialku prepnu do simulacneho modu, ked na nejake indexy cez sw prepinac bud vkladam napr. skutocne hodnoty z AD, alebo hodnoty simulovane, ktore zapisujem do zatial nevyuzitych casti pola.

Takze myslim si ze presne o tomto cely cas hovorime :slight_smile:

Tato myšlenka se mi líbí a také jsem z ní vycházel při psaní bootloderu. Není jednoduché vše splnit, protože každý typ AVR je jiný. Má jiný počet přerušovacích vektorů, takže program de facto začíná od jiné adresy, rovněž tak RAM začíná u některých od 0x0060 a u jiných od 0x0100. Skok na bootloader je taktéž pokaždé jinde. Uživatel si může určit velikost bootloaderu. To vše mě přesvědčilo o tom, že se nemohu upínat na žádné pevné adresy, no snad jen svyjímkou EEPROM.
Dospěl jsem k názoru, že bootloader musí být pro každý typ AVRka jiný, nebo alespoň nějak modifikovaný, protože musí obsahovat konstanty, resp. pointery na informace o nahraném firmware. Krom toho musí obsahovat informace sám o sobě a o tomto zařízení. Jiný, neznamená jíné ovládání přes sběrnici či jiný protokol.
Tabulka informací musí být na stejných adresách ve všech verzích firmware a jediné rozumné místo pro ni je hned za přerušovacími vektory. Jedině zde nedochází k posunu po adresách při změně firmware.

Ahoj, toto téma už je asi mrtvé téma, ale mám řešení neboť mě absolutní adresace příjde jako velmi vhodná, také jí velmi často a rád používám.

Řešení je takové, že si nadefinuju nějaké pole o velikosti mé “virtuální RAM”. Pak nedefinuju proměné jako pointery na tuto virtuální oblast.


#define  word_1         *(uint16_t*)(pamet + 0x00)
#define  word_2         *(uint16_t*)(pamet + 0x02) 
#define  znak_1         *(uint8_t*)(pamet + 0x04) 
#define  znak_2         *(uint8_t*)(pamet + 0x05)  

volatile static uint8_t pole[6];

Promene pak plnim a ctu stejne jako jakekoliv tohoto typu. Jedine omezeni, ktere jsem zatim nasel je, ze nelze použít např: znak_2++, ale musí se použít znak_2 += 1;

Sice proměné nejsou absolutně adresované v paměti ram, ale v definovaném poli…nicméně si myslím, že to řeší částečně tento problém.

BTW: zapomněl jsem napsat, že je toto dokonce efektivnější z hlediska flash paměti než používat klasické globální proměnné…samozřejmě pouze u typu integer. U typu char se to neprojeví.

Zajímavé téma a řek bych hodně kontraverzní. Něco takového jsme řešili a celkem zdárně vyřešili pro jednu řídící aplikaci a pojmenovali jsme to “DataPool” Principielně jde o to že “objekty zájmu” se zaregistrují do struktury datapoolu a tuto lze publikovat přes komunikační rozhraní a dále podle ní přistupovat k jednotlivým členům této struktury (různá práva, R, R/W , atd).
Ještě k původnímu nápadu - úplně bych to neodsuzoval ale používá se to podle mě zřídka. Tenhle požadavek měla ESA na softvare v mikroakcelerometru (přistupovat za běhu kamkoli a u některých proměných pevně dané umístění)

U PIC to jde velice snadno.

unsigned char promenna @ 0x20 ;

A je to, na adrese 0x20 v RAM najdete tuto proměnnou.:slight_smile: