Kérdés:
Miért foglalnak el a vázlatok ennyi helyet és memóriát?
hichris123
2014-02-22 03:29:25 UTC
view on stackexchange narkive permalink

Amikor összeállítom ezt a vázlatot a Yún számára:

  int led = 7; void setup () {pinMode (led, OUTPUT); } void loop () {digitalWrite (led, HIGH);}  

Kapom:

A Sketch 5098 bájtot (17%) használ a program tárhelyén .

Legfeljebb 28 672 bájt. A globális változók 153 bájt (5%) dinamikus memóriát használnak, így 2407 bájt marad a helyi változók számára. A maximum 2560 bájt.

Még akkor is, ha a BareMinimum vázlatot lefordítom:

  void setup () {// setup} void loop () {// loop}  

Értem:

A Sketch 4548 bájtot (15%) használ a program tárhelyéből.

Legfeljebb 28 672 bájt . A globális változók 151 bájtot (5%) használnak a dinamikus memóriából, így 2409 bájt marad a helyi változók számára. A maximum 2560 bájt.

Miért veszi el a minimális vázlat a kiosztott program 15% -át? És miért egy nagyon egyszerű vázlat foglalja el a program tárhelyének 17% -át? az Arduino webhelye szerint:

Az egészet egyszerűen fel lehet használni, ha rengeteg karakterlánc van a programban. Például egy olyan deklaráció: char message [] = "Támogatom a Cape Wind projektet."; 33 bájtot tesz az SRAM-ba (mindegyik karakter bájtot vesz igénybe, plusz a '\ 0' terminátor).

Azonban ezekben a vázlatokban nincsenek deklarálva karaktersorozatok.

Úgy tűnik, mintha más könyvtárakat / osztályokat importálnának vagy használnának, amelyeket nem adok ' t adja meg. Esetleg egy rendszer alapértelmezett könyvtárát importálja? Vagy valami másról van szó?

Négy válaszokat:
jippie
2014-02-22 03:36:27 UTC
view on stackexchange narkive permalink

Az Arduino sok szabványos könyvtárban fordít, megszakít, stb. Például a pinMode és a digitalWrite függvények egy keresőtábla segítségével futtatás közben kitalálják, melyik GPIO regisztrációhoz kell adatokat írni. Egy másik példa az, hogy az Arduino nyomon követi az időt, alapértelmezés szerint meghatároz néhány megszakítást, és mindez a funkció némi helyet igényel. Észre fogja venni, hogy ha kibővíti a programot, akkor a lábnyom csak kismértékben változik.

Én személy szerint szeretem a vezérlőket minimális mértékben, "puffadás" nélkül programozni, de gyorsan belép a Az EE.SE és a SO, mert több könnyen használható funkció már nem működik a dobozból. Vannak olyan alternatív könyvtárak a pinMode és a digitalWrite számára, amelyek kisebb méretben fordulnak össze, de más hátrányokkal is járnak, például a statikusan lefordított csapok (ahol a led nem lehet változó, de állandó).

Tehát alapvetően mindenféle szabványos könyvtárban áll össze anélkül, hogy kérdezné? Tiszta.
Igen, általában "puffadásnak" nevezem, de ez valóban használható dolog. Az Arduino egy alacsony belépési szintű környezet, amely túl sok gondolkodás nélkül működik. Ha többre van szüksége, az Arduino lehetővé teszi alternatív könyvtárak használatát, vagy fordíthat a csupasz fémek ellen is. Az utolsó valószínűleg nem tartozik az Arduino.SE hatálya alá
Lásd az @mpflaga válaszomat. Nincs annyi puffadás. Vagy legalább a törzskönyvtárban a minimális funkcionalitás érdekében. Valójában nincs sok szabványos könyvtár, hacsak nem nevezzük vázlatnak. A 15% inkább a 32u4 USB támogatásának köszönhető.
mpflaga
2014-02-22 11:58:43 UTC
view on stackexchange narkive permalink

A YUN egy kombináció. Arduino és OpenWRT rész (Linux). Kérdése az Arduinóra vonatkozik. Ahol ez valójában egy Leonardo-hoz hasonló ATmega32u4, és nem UNO (ATmega328p). A 32u4 (Leo) virtuális soros portokon keresztül kommunikál az USB-n keresztül (rövid válasz: ezt támogatni kell) , ahol az UNO valódi soros porttal (más néven UART) rendelkezik. Az alábbiakban összeállítjuk az AVR processzorok különböző táblatípusainak statisztikáit.

Megjegyzés az UNO-ban van egy külső chip, amely az USB-t átalakítja a soros port DTR tűjévé, amely az ATmega328 visszaállító gombját váltja, amikor csatlakozik, és újraindítást okoz a rendszerbetöltőhöz. Ezzel szemben a Leo / Yun USB to Serial USB-jét a 32u4 firmware-jében hajtják végre. Ezért a Leo vagy a YUN 32u4 chipjének távoli újraindításához a betöltött firmware-nek mindig támogatnia kell az USB kliens oldali illesztőprogramot. Ami hozzávetőlegesen 4K-t fogyaszt.

Ha NEM volt szükség az USB-re, és nem hívtak meg más könyvtári erőforrásokat, mint például a BareMinimum.ino esetében egy UNO-n, csak körülbelül 466 bájtra van szükség az alapvető Arduino könyvtárhoz.

állítsa össze a BareMinimum.ino statisztikáit egy UNO-n (ATmega328p)

  A Sketch 466 byte (1%) programterületet használ. A maximum 32 256 bájt. A globális változók 9 bájt (0%) dinamikus memóriát használnak, 2039 bájtot hagyva a helyi változók számára. A maximum 2048 bájt.  

a BareMinimum.ino statisztikáinak összeállítása egy Leonardo (ATmega32u4) fájlon

  Sketch 4554 bájt (15%) programterületet használ . A maximum 28 672 bájt. A globális változók 151 bájt (5%) dinamikus memóriát használnak, így 2409 bájt marad a helyi változók számára. A maximum 2560 bájt.  

a BareMinimum.ino statisztikáinak összeállítása Yun-on (ATmega32u4)

  Sketch 4548 bájt (15%) programterületet használ . A maximum 28 672 bájt. A globális változók 151 bájt (5%) dinamikus memóriát használnak, így 2409 bájt marad a helyi változók számára. A maximum 2560 bájt.  
Edgar Bonet
2015-07-07 13:12:17 UTC
view on stackexchange narkive permalink

Már van néhány nagyon jó válasz. Csak ezt teszem közzé, hogy megosszam néhány statisztikát, amelyeket egy napon meg is tettem, és ugyanolyan kérdéseket tettem fel magamnak: Mi foglal annyi helyet egy minimális vázlaton? Mi szükséges minimum ugyanazon funkcionalitás eléréséhez?

Az alábbiakban egy minimálisan villogó program három változata látható, amely másodpercenként a 13-as tűre kapcsolja az LED-et. Mindhárom verziót összeállítottuk az anUno számára (nincs USB csatlakozás) az avr-gcc 4.8.2, avr-libc 1.8.0 ésarduino-core 1.0.5 használatával (nem használom az Arduino IDE-t).

Először is, a szokásos Arduino mód:

  const uint8_t ledPin = 13; void setup () {pinMode (ledPin, OUTPUT);} void loop () {digitalWrite (ledPin, HIGH); késés (1000); digitalWrite (ledPin, LOW); delay (1000);}  

Ez 1018 bájtra áll össze. Az avr-nm és a szétszerelés segítségével ezt a méretet külön funkciókra bontottam. A legnagyobbtól a legkisebbig:

  148 A ISR (TIMER0_OVF_vect) 118 A init 114 A pinMode 108 A digitalWrite 104 C vector table 82 A turnOffPWM 76 A delay 70 A micros 40 U loop 26 A main 20 A digital_pin_to_timer_PGM 20 A digital_pin_to_port_PGM 20 A digital_pin_to_bit_mask_PGM 16 C __do_clear_bss 12 C __init 10 A port_to_output_PGM 10 A port_to_mode_PGM 8 U setup 8 C .initb__cit - Cinter 4 ------------------------ 1018 ÖSSZESEN  

A fenti listában az első oszlop a bájtban megadott méret , és a második oszlop megmondja, hogy a kód az Arduino magkönyvtárból származik (A, 822 bájt összesen), a C futási időből (C, 148 bájt) vagy a felhasználótól (U, 48 bájt).

Amint lehet Ebben a listában látható, hogy a legnagyobb funkció az időzítő 0 túlcsordulás megszakításának karbantartása. Ez a rutin az idő követéséért felelős, és a millis () , micros () és a delay () szükséges. A második legnagyobb függvény init () , amely beállítja a hardver időzítőket a PWM esetében engedélyezi a TIMER0_OVF megszakítást és leválasztja az USART-ot (amelyet a rendszerbetöltő használt). Ezt és az előző függvényt is meghatározták a <Arduino könyvtárban> / hardware / arduino / cores / arduino / wiring.c .

A következő a C + avr-libc verzió: >

  #include <avr / io.h> # include <util / delay.h>int main (void) {DDRB | = _BV (PB5); / * állítsa kimenetként a PB5 csapot * / a (;;) {PINB = _BV (PB5) számára; / * kapcsoló PB5 * / _delay_ms (1000); }}  

Az egyes méretek bontása:

  104 C vektortábla 26 U main 12 C __init 8 C .init9 (call main, jmp exit) 4 C __bad_interrupt 4 C _exit ---------------------------------- 158 ÖSSZESEN  

Ez 132 bájt a C futásidejéhez és 26 bájt felhasználói kód, beleértve a beillesztett _delay_ms().funkciót.

Megjegyezhetjük, hogy mivel ez A program nem használ megszakításokat, a megszakításvektortáblára nincs szükség, és a rendszeres felhasználói kodeket lehet a helyére tenni. A következő szerelési verzió pontosan ezt teszi:

  #include <avr / io.h> # define io (reg) _SFR_IO_ADDR (reg) sbi io (DDRB), 5; állítsa a PB5-t kimeneti nyílásként: sbi io (PINB), 5; kapcsoló PB5 ldi r26, 49; késleltetés 49 * 2 ^ 16 * 5 ciklus késleltetés: sbiw r24, 1 sbci r26, 0 brne késleltetés rjmp hurok  

Ez össze van állítva ( >) csak 14 bájtba, amelyek többségét a váltások késleltetésére használják, hogy a villogás ne legyen látható. Ha eltávolítja ezt a késleltetési hurkot, akkor egy 6 bájtos programot kap, amely túl gyorsan villog ahhoz, hogy látható legyen (2 MHz-en):

  sbi io (DDRB), 5; állítsa a PB5-t kimeneti nyílásként: sbi io (PINB), 5; váltani a PB5 rjmp ciklust  
Nick Gammon
2015-07-07 07:17:10 UTC
view on stackexchange narkive permalink

Írtam egy bejegyzést Miért kell 1000 bájt villogni egy LED-en?.

A rövid válasz: "Nem kell 2000 bájt villogni két LED! "

A hosszabb válasz az, hogy a standard Arduino könyvtárak (amelyeket nem kell használni, ha nem akarod) néhány szép funkcióval rendelkeznek, hogy egyszerűsítsék a élet. Például futás közben megcímezheti a tűket szám szerint, ahol a könyvtár a 8. tűt a megfelelő portra és helyes bitszámra alakítja. Ha hard-code hozzáférést biztosít a porthoz, akkor elmentheti ezt a rezsit.

Még akkor is, ha nem használja őket, a standard könyvtárak kódot tartalmaznak a "kullancsok" számlálásához, így megtudhatja az aktuális "időt" ( a millis () ) meghívásával. Ehhez hozzá kell adnia néhány megszakítási szolgáltatási rutin általános költségeit.

Ha leegyszerűsíti (az Arduino Uno-n) ezt a vázlatot, akkor a program memóriájának használatát 178 bájtra csökkenti (az IDE 1.0-n. 6):

  int main () {DDRB = bit (5); míg (true) PINB = bit (5); }  

OK, a 178 bájt nem olyan sok, és ebből az első 104 bájt a hardver megszakítási vektor (mindegyik 4 bájt, 26 vektor esetében).

Tehát vitathatatlanul csak 74 bájt szükséges a LED villogásához. Ebből a 74 bájtból a legtöbb valóban a fordító által generált kód a globális memória inicializálásához. Ha annyi kódot ad hozzá, hogy két LED villogjon:

  int main () {DDRB = bit (5); // pin 13 DDRB | = bit (4); // pin 12 while (true) {PINB = bit (5); // pin 13 PINB = bit (4); // pin 12}}  

Ezután a kód mérete 186 bájtra nő. Tehát azt állíthatja, hogy csak egy LED villogásához 186 - 178 = 8 bájt kell.

Tehát 8 bájt egy LED villogásához. Elég hatékonyan hangzik számomra.


Abban az esetben, ha kísértésbe esne ezt kipróbálni otthon, meg kell említenem, hogy bár a fenti közzétett kód két LED-et villog, valóban nagyon gyorsan. Valójában 2 MHz-en villognak - lásd a képernyőképet. Az 1. csatorna (sárga) a 12. érintkező, a 2. csatorna (cián) a 13. tű.

Rapid blinking of pins 12 and 13

Mint látható, a kimeneti csapok négyzet alakú hullámúak, 2 MHz frekvenciával. A 13. tű megváltoztatja a 62.5 ns (egy órás ciklus) állapotot a 12. tű előtt, a kódban lévő csapok váltogatásának sorrendje miatt.

Tehát hacsak nincs sokkal jobb szeme, mint az enyémnek, akkor nem valójában lát minden villogó hatást.


Szórakoztató extraként két csapot át lehet váltani a ugyanannyi programterületen, mint a váltás egy tű.

  int main () {DDRB = bit (4) | bit (5); // állítsa a 12. és 13. csapokat kimenetre, míg (true) PINB = bit (4) | bit (5); // váltani a 12. és 13. csapokat} // a main vége  

Ez 178 bájtba áll össze.

Ez magasabb frekvenciát eredményez:

Very rapid blinking of pins 12 and 13

Most 2,66 MHz-en vagyunk.

Ennek rengeteg értelme van. Tehát a szabványos könyvtárak csak a fejlécek kerülnek beépítésre automatikusan? És hogyan tudta * nem * befogadni őket?
A linkelő agresszíven eltávolítja a nem használt kódot. Ha nem hívtuk meg az `init ()` parancsot (ahogy a szokásos` main ()`), akkor a wiring.c fájlt (amelyben benne van az `init ') nem kapcsolták össze. Ennek eredményeként a megszakításkezelők feldolgozása ( a `millis ()` esetében a `micros ()` stb.) kihagyásra került. Valószínűleg nem különösebben praktikus kihagyni, hacsak soha nem kell időzíteni a dolgokat, de az a helyzet, hogy a vázlat mérete nő attól függően, hogy mit tesz bele. Például, ha Serialt használ, mind a programmemória, mind a RAM eltalál.


Ezt a kérdést és választ automatikusan lefordították angol nyelvről.Az eredeti tartalom elérhető a stackexchange oldalon, amelyet köszönünk az cc by-sa 3.0 licencért, amely alatt terjesztik.
Loading...