[megoldva] AVR architektura, feltetelben

Azt hogyan tudom ellenorizni egy AVR assembly forraskodban, `avr-as` segitsegevel forditvan hogy milyen architekturara is forditjuk? Peldaul: `avr-as -mmcu=avr31 -o xyz.o xyz.s` es akkor a *.s-ben meg ilyesmik lennenek, mint:

.if (avr3 | avr31 | avr5)
.set SOMETHING, 8
.else
.set SOMETHING, 4
.endif

Es akkor ezen fenti parancsnal a SOMETHING erteke 8 legyen merthogy AVR31-es az architektura. Szoval mit is irjak az elso `.if ...` sor helyere ha epp a fenti architekturakra gondol a kolto... Konkretan ezalapjan probalkoztam, meg az itt elpottyintett avr-as understands the same -mmcu= options as avr-gcc mondat alapjan biztam benne hogy egy `.if (AVR_ARCH == 31)` pl jo lehet, de sajnos nem :/

Koszi, A.

Hozzászólások

A megoldást nem tudom, de szerintem legrosszabb esetben futásidőben meg tudod csinálni, ami kétségkívül egy ronda workaround.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Van még egy ötletem.

#include "avrarch.h"

Majd a fordító scriptbe:

echo "#define AVR_ARCH $avr_arch" >avrarch.h

Értelemszerűen avr_arch tartalmazza az architektúrát, s ezt akár az gcc avr-as paramétereként is fel lehet használni.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

lehet alapból van avr arch, csak nem úgy hívják, hanem így, ha jól gondolom
__AVR_ARCH__

#ifndef __SFR_OFFSET
/* Define as 0 before including this file for compatibility with old asm
sources that don't subtract __SFR_OFFSET from symbolic I/O addresses.  */
#  if __AVR_ARCH__ >= 100
#    define __SFR_OFFSET 0x00
#  else
#    define __SFR_OFFSET 0x20
#  endif
#endif

https://stackoverflow.com/questions/14464713/arduino-assembler-programm…
Ha az stimmel, akkor itt írnak még több hasonlót
https://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html
__AVR_Device__ például

Koszi, igen, ezt is neztem, de az assembly-ben ugy latom ez sincs definialva... :/

Most egy ilyen workaroundot probaltam meg: `avr-as -mmcu=avr31 --defsym arch=31 -o xyz.o xyz.s`, es akkor ez ltt a feltetel:

.if     (arch==31)
.set    ...
.else
.set    ...
.endif

Es akkor ez hellyel-kozel azert egy makefile-ban is kezelheto relative kulturaltan... persze a defsym/symbol csak numerikus lehet, szoval ilyet nem csinalhatok hogy -mmcu=$(ARCH) --defsym arch=$(ARCH), de azert talan igy mar vallalhato... 

De azert meg nezegetem majd rendes megoldasok kapcsan, hatha. Az mondjuk latszik, hogy a .set illetve a --defsym altal definialt szimbolumok mind-mind bekerulnek a *.o-ba (az avr-nm kilistazza). Azaz nem kizart(?) hogy csak olyanokra lehet tesztelni mar forditasi idoben is ami meg is jelenik igy az object symbol table-kben... jo kerdes. Vegulis assembler, lehet hogy annyi elvarasunk nem lehet mint C-ben egy #define/#ifdef/#endif eseteben.

Jaja, igen, egyelore ez teljesen jo. Itt most ennel a konkret problemanal csak a build folyamatot akarnam egyszerusiteni egy kicsit, aztan nagy segitseg lett volna ha a fordito (megha assembler is) at tudna passzolni azt az infot a forraskodnak hogy vegulis milyen architekturara fordit... de ne akarjunk sokat :) Ugy neztem kozben itt menetkozben hogy az assembler semmilyen pre-defined symbolt nem ad at a forrasnak. Lehet hogy ez tenyleg szandekos itten(?)

biztosan jól akarod használni?

https://android.googlesource.com/toolchain/avr-libc/+/edcf5bc1c8da8cc4c…

Itt van ebben is __AVR_ARCH__ használat. Vagy te mindenképp futásidőben gondolod kiértékelni? Ez fordítási időben megy így.
Más annak az assemblernek a szintaktikája, hogy .if -es példáut mutatsz, amikor #if -es a preprocesszoros avr-as -szel?

https://tenbaht.github.io/posts/migrating-from-avra-to-avr-as/
ebben van példa mindkét fajtára Pre-defined variables.
Nem avr-gcc -vel kell buildelni és majd ő hívja az avr-as-t? És persze a # fajtát használni.

Részben kérdem, nem állítom, mert ezer éve nem assemliztem :)

Hm... ez erdekes. Itten keveri a C-szeru #if... #else... #endif jellegu dolgokat az assemblyvel, de nalam valamiert ez nem megy. Mintha minden #... egy komment lenne, meg egy standalone #error ...-ral sem tudom leallitani.

Vagy te mindenképp futásidőben gondolod kiértékelni? Ez fordítási időben megy így.

Nemnem. Vagyis forditasi idoben lenne szuksegem valami feltetel formajaban az architekturara ;) Ez a pelda amit linkeltel ez teljesen jo lenne, de valamiert nem megy nalam. Mintha az avr-as uses the C-preprocessor, so it only detects (and removes) C-comments at this point nem lenne igaz... nem ertem... 

Ah, ugy nez ki megoldva:

  • avr-gcc-vel kell forditani (es nem `avr-as`-sel)
  • a kiterjesztes nem *.s hanem *.S kell hogy legyen...

Es akkor igy mar van #if, #ifdef, ... ilyesmi is es ezek felismerik a __AVR_ARCH__ meg hasonlo definiciokat. Eh... Csak az egyik (*.s helyett *.S) vagy csak a masik (avr-gcc avr-as helyett) az keves, mindketto kell :/

futásidőben meg tudod csinálni

Itt egyebkent mire gondolsz? Marmint pl Cortex-Mx-nel el tudom kepzelni hogy sorban adsz ki egyre magasabb architekturahoz tartozo utasitasokat, es az lesz a felso korlatja az architekturanak amikor mar belefut egy hardfault exception-be. De AVR-nel ugyanez...? 

Valami olyasmire gondoltam, hogy mivel van az architektúrák között különbség, vélhetően írható olyan kód, amelyik megmondja, ez milyen architektúra.

A másik - bár, ha fordítási időben tudjuk, akkor okafogyott az egész -, hogy fordítási időben letesszük a permanens memóriába, amit futásidőben kiolvasunk.

Azt a hozzászólást egyébként eléggé érzésből írtam, nem gondoltam alaposan végig. Nekem egyszer volt olyan tervezési hibám, hogy két azonos CPU volt a nyákon, de az azonosíthatósága lemaradt a kapcsolási rajzról. Aztán gondoltam egyet, ha ott ez a két CPU, azért van ott, mert más a dolguk, valahogyan csak meg lehet állapítani, melyik a CPU1, s melyik a CPU2. Addig néztem a kapcsolási rajzot, amíg kitaláltam, hogyan lehet identifikálni a CPU-kat. :) Ott nyilván az volt a cél, hogy azonos kód legyen nekik letöltve, de szerepük szerint mégis mást csináljon az egyik, mint a másik.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Megnéztem, és ha jól láttam, az AVR-nek nincs runtime kiolvasható vendor id, revision id és part number. (Mint a PIC-nél.) Egyes példányok kivételével csak a programozó interfészen elérhető vagy belefordíthatod a programba. Ha kiolvasod, akkor még a wafer x-y koordináta is ott van!

Ha tévedtem, akkor ezt a fícsört jól elrejtették az adatlapon. :-D

Ezek a procik elég egyformák, a kiolvasott információ meg kellhet pl. a perifériák darabszámának megállapításához. Pedig itt a csiphiányos időkben az ember rákényszerülhet több mcu-n futó program írására.

Ah, igen. AVR-nel akkor lehetne ilyesmit hogyha valamelyik I/O portjaba (vagy akar memoriateruletre) bele lenne irva valami hasonlo. Mondjuk igen, fizikai AVR-nel olyat lehet hogy a programozas soran az eeprom-jaba beleirunk valamit, ami egyedi... de igen, dedikalt architekturara vonatkozo informaciot nem lehet belole kiolvasni. Ez van :)

Azt nem lehet megcsinálni, hogy az egyikben van mondjuk egy UART, a másikban nincs, beírsz valamit a regiszterébe, visszaolvasod, ha jól jön vissza az érték, van mögötte regiszter, ha nem, akkor nincs? Ilyesmire gondoltam. Ha nem tudsz különbséget tenni két eszköz között, akkor szerintem nincs köztük különbség.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Nem tudom, ezen CPU-k között mi a különbség. Arra lehet kódot írni, amiben van. Vagy arról lenne szó, hogy teljesen más a gépi kódja az egyiknek, mint a másiknak? Mert úgy tényleg nehéz, de arra is van ötletem. Be kell fordítani a kódba olyan kódrészt, ami binárisan mássá fordul az eltérő architektúrán, majd futásidőben meg kell nézni, mik ezek a bináris értékek, s máris tudjuk, milyen architektúráról van szó.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Sőt, még a kötsög vindóz se fut rajta! ;)

Pedig éppen most pont azon dolgozok, hogy ugyanazt a programot több "családtag" vagy kissé eltérő felépítés mellett is ugyanarra lehessen használni. Az egyikben több ram van, de van dma, viszont nincs eeprom, stb. Esetleg az Alkotó ötletszerűen felcserélt két sfr régiót, ami miatt bankolni kell, holott eddig nem kellett. Az egyik jelzi, hogy stabilizálódott a pll, a másiknál időt kell mérni. Az eltérések miatt pont nem szoftverről van szó, mert az bármelyiken fut. A boltban meg éppen azt lehet kapni, amit árulnak. Így aztán sorozatgyártásnál az kerül a gyártmányba, amit sikerült megvenni.

Tudod, említettem: csiphiány, meg az árak sem ugyanazok, mint a Kádár-korszakban. :-D

Pedig éppen most pont azon dolgozok, hogy ugyanazt a programot több "családtag" vagy kissé eltérő felépítés mellett is ugyanarra lehessen használni.

Mgen, ez sajnos egy ismeros dolog... de azert az nagy segitseg hogy forditasi idoben tudja a program hogy mire kell dolgozni ;)

... forditasi idoben tudja a program hogy mire kell dolgozni ;)

Persze, nem árt. ;) Csakhogy ebben már szintet ugrottam. :-D

Eleinte minden a "kályhától" készült. Tehát ugyanahhoz a változathoz külön fordítottam akkor is, ha csak a flash méret tért el. Mivel a két bináris megegyezik, ezért a headerek is megegyeznek. Egyesítettem őket. Ettől kezdve csa a programozónak kell megmondani az éppen beszerzett típust.

A kicsit eltérő arch módosítása csak ifdef-es kiegészítés lett, fordítható a korábbira is. A kód "tevékenysége" nem változott, könnyedén vissza lehet térni, ha a régi mcu is visszatér. ;)

Extrem esetben olyan is van (pl. Atmega8, Atmega328P), hogy a 28 labu DIP tokon 6 ADC van kivezetve, a 32 labu SMD tokazasokon (merettol fuggetlenul) pedig 8. A belseje azonos. (ezert van az Arduino shieldeken 6 ADC kivezetve, mert regen a DIP tokos volt rajtuk)

Csereben viszont a programozo le tudja kerni az eszkoztol az azonositojat, es az egeto script ez alapjan ra tudja tolteni a neki megfelelo binarist (a tokozast szerintem o sem tudja). Szoval azert annyira nem rossz a helyzet. Annyi flash meg nincs bennuk, hogy minden program tobbszor elferjen benne architekturankent, mint pl. a MAC-eknel.

A strange game. The only winning move is not to play. How about a nice game of chess?