Küsimus:
Miks visandid võtavad nii palju ruumi ja mälu?
hichris123
2014-02-22 03:29:25 UTC
view on stackexchange narkive permalink

Kui koostan selle skeemi Yúni jaoks:

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

Saan:

Sketch kasutab 5098 baiti (17%) programmi salvestusruumist .

Maksimaalselt on 28 672 baiti. Globaalsed muutujad kasutavad 153 baiti (5%) dünaamilist mälu, jättes kohalike muutujate jaoks 2407 baiti. Maksimaalselt on 2560 baiti.

Isegi kui ma koostan BareMinimum visandi:

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

Saan:

Sketch kasutab 4548 baiti (15%) programmi salvestusruumist.

Maksimaalselt on 28 672 baiti . Globaalsed muutujad kasutavad 151 baiti (5%) dünaamilist mälu, jättes kohalike muutujate jaoks 2409 baiti. Maksimaalselt on 2560 baiti.

Miks võtab minimaalne visand 15% eraldatud programmi salvestusruumist? Ja miks võtab väga lihtne visand 17% programmi salvestusruumist? Arduino veebisaidi andmetel:

Seda kõike on lihtne kasutada, kui teie programmis on palju stringe. Näiteks selline deklaratsioon nagu: char message [] = "Toetan Cape Windi projekti."; paneb SRAM-i 33 baiti (iga märk võtab baidi, millele lisandub terminator '\ 0').

Kummaski visandis pole deklareeritud ühtegi stringi.

Näib, et nad võivad importida või kasutada muid teeke / klasse, mida ma ei kasuta ' t täpsustage. Võib-olla impordib see süsteemi vaikekogu? Või on see midagi muud?

Neli vastused:
#1
+7
jippie
2014-02-22 03:36:27 UTC
view on stackexchange narkive permalink

Arduino kompileerib paljudes tavapärastes teekides, katkestab jne ... Näiteks funktsioonid pinMode ja digitalWrite kasutavad otsingu tabelit, et tööajal välja selgitada, millisesse GPIO-i registreerub andmete kirjutamiseks. Teine näide on see, et Arduino jälgib aega, määratleb vaikimisi mõned katkestused ja kogu see funktsionaalsus nõuab veidi ruumi. Märkate, et kui programmi pikendate, muutub jalajälg ainult veidi.

Mulle isiklikult meeldib programmeerida kontrollereid miinimumiga, ilma "paisuta", kuid sisenete kiiresti EE.SE ja SO, sest mitmed hõlpsasti kasutatavad funktsioonid ei tööta enam kastist väljas. PinMode'i ja digitalWrite'i jaoks on mõned alternatiivsed teegid, mis kompileeruvad väiksema jalajäljega, kuid millel on muid puudusi, näiteks staatilised kompileeritud tihvtid (kus led ei saa olla muutuja, kuid on konstant).

Nii et see kompileerib põhimõtteliselt kõikvõimalikes standardraamatukogudes, ilma et te seda küsiksite? Korralik.
Jah, ma nimetan seda tavaliselt "paisuks", kuid see on tegelikult kasutatavus. Arduino on madal algtaseme keskkond, mis töötab lihtsalt ilma liigse mõtlemiseta. Kui vajate rohkem, lubab Arduino kasutada alternatiivseid teeke või saate kompileerida palja metalli vastu. Viimane on arvatavasti Arduino.SE reguleerimisalast väljas
Vaadake minu @mpflaga vastust. Punnimist pole nii palju. Või vähemalt põhiteeki minimaalse funktsionaalsuse tagamiseks. Seal pole tegelikult ühtegi standardset teeki, välja arvatud juhul, kui seda nimetatakse visandiks. Pigem on 15% tingitud 32u4 USB-toest.
#2
+6
mpflaga
2014-02-22 11:58:43 UTC
view on stackexchange narkive permalink

YUN on kombo. Osa Arduino ja osa OpenWRT (Linux). Teie küsimus on seotud Arduinoga. Kus see on tegelikult Leonardo sarnane ATmega32u4, mitte UNO (ATmega328p). 32u4 (Leo) suhtleb virtuaalsete jadaportide kaudu USB-liidese kaudu (lühike vastus: seda tuleb toetada) , kus UNO-l on tõeline jadaport (aka UART). Allpool on toodud AVR-protsessorite erinevate tahvlitüüpide statistika.

UNO-s on märkus, et seal on väline kiip, mis teisendab USB-i jadapordi DTR-piniks, mis lülitab ATmega328 lähtestusnupu ühenduse loomisel ja põhjustab taaskäivitamise alglaadurile. Seevastu Leo / Yuni USB to Serial on rakendatud 32u4 püsivara. Seega peab Leo või YUNi 32u4 kiibi kaugelt taaskäivitamiseks laaditud püsivara alati toetama USB-kliendi draiverit. Mis kulutab umbes 4K.

Kui USB-d EI OLE vaja ja muid raamatukogu ressursse ei kutsutud nagu UNO-s BareMinimum.ino puhul, on Arduino tuuma teegi jaoks vaja ainult umbes 466 baiti.

koosta BareMinimum.ino statistika UNO-l (ATmega328p)

  Sketch kasutab 466 baiti (1%) programmi salvestusruumist. Maksimaalselt on 32 256 baiti. Üldised muutujad kasutavad 9 baiti (0%) dünaamilist mälu, jättes kohalike muutujate jaoks 2039 baiti. Maksimaalselt on 2048 baiti.  

kompileerige BareMinimum.ino statistika Leonardo (ATmega32u4) kohta

  Sketch kasutab 4554 baiti (15%) programmi salvestusruumist . Maksimaalselt on 28 672 baiti. Üldised muutujad kasutavad 151 baiti (5%) dünaamilist mälu, jättes kohalike muutujate jaoks 2409 baiti. Maksimaalselt on 2560 baiti.  

kompileerige Yare'i (ATmega32u4) BareMinimum.ino statistika

  Sketch kasutab 4548 baiti (15%) programmi salvestusruumist . Maksimaalselt on 28 672 baiti. Üldised muutujad kasutavad 151 baiti (5%) dünaamilist mälu, jättes kohalike muutujate jaoks 2409 baiti. Maksimaalselt on 2560 baiti.  
#3
+4
Edgar Bonet
2015-07-07 13:12:17 UTC
view on stackexchange narkive permalink

Teil on juba täiesti häid vastuseid. Postitan selle ainult selleks, et jagada mõnda statistikat, mille ühel päeval tegin, küsisin endalt samasuguseid küsimusi: mis võtab minimaalse sketši jaoks nii palju ruumi? Mida on sama funktsionaalsuse saavutamiseks vaja?

Allpool on kolm versiooni minimaalsest vilkuvast programmist, mis lülitab LED iga sekundiga tihvti 13 külge. Kõik kolm versiooni on koostatud anUno jaoks (USB-d pole kaasatud), kasutades avr-gcc 4.8.2, avr-libc 1.8.0 jaarduino-core 1.0.5 (ma ei kasuta Arduino IDE-d).

Esiteks tavaline Arduino viis:

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

See kompileeritakse 1018 baiti. Nii avr-nm kui ka lahtivõtmise abil jagasin selle suuruse üksikuteks funktsioonideks. Suurimast väikseimani:

  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 häälestus 8 C .init__interjöör 4 Cinter - 4 ------------------------ 1018 KOKKU  

Ülaltoodud loendis on esimese veeru suurus baitides ja teises veerus on teada, kas kood pärineb Arduino tuumikukogust (kokku 822 baiti), C käituse ajast (C, 148 baiti) või kasutajalt (U, 48 baiti).

Nagu võib olla Selles loendis on suurim funktsioon taimer 0 ülevoolu katkestuse teenindamine. See rutiin vastutab jälitusaja eest ja seda vajavad millis () , micros () ja delay () . Suuruselt teine ​​funktsioon on init () , mis määrab riistvaralised taimerid PWM-i jaoks võimaldab TIMER0_OVF-i katkestamist ja ühendab lahti USART-i (seda kasutas alglaadur). Nii see kui ka eelmine funktsioon on määratletud <Arduino kataloogis > / hardware / arduino / cores / arduino / wiring.c .

Järgmine on versioon C + avr-libc:

  #include <avr / io.h> # include <util / delay.h>int main (void) {DDRB | = _BV (PB5); / * määrake väljundiks tihvt PB5 * / jaoks (;;) {PINB = _BV (PB5); / * lüliti PB5 * / _delay_ms (1000); }}  

Üksikute suuruste jaotus:

  104 C vektoritabel 26 U main 12 C __init 8 C .init9 (call main, jmp exit) 4 C __bad_interrupt 4 C _exit ---------------------------------- 158 KOKKU  

See on 132 baiti C käituse jaoks ja 26 baiti kasutajakoodi, sealhulgas sisestatud funktsioon _delay_ms().

Võib märkida, et kuna see programm katkestusi ei kasuta, katkestusvektoritabelit pole vaja ja selle asemele võiks panna tavakasutaja koodeki. Järgmine assamblee versioon teeb täpselt nii:

  #include <avr / io.h> # define io (reg) _SFR_IO_ADDR (reg) sbi io (DDRB), 5; määrake väljundiks PB5: sbi io (PINB), 5; lüliti PB5 ldi r26, 49; viivitus 49 * 2 ^ 16 * 5 tsüklit viivitus: sbiw r24, 1 sbci r26, 0 brne delay rjmp silmus  

See on kokku pandud (koos avr-gcc -nostdlib ) ainult 14 baiti, millest enamikku kasutatakse lülituste viivitamiseks, nii et vilkumine on nähtamatu. Kui eemaldate selle viivitussilmu, saate 6-baidise programmi, mis vilgub liiga kiiresti, et seda nähtaks (2 MHz juures):

  sbi io (DDRB), 5; määrake väljundiks PB5: sbi io (PINB), 5; ümberlülitamine PB5 rjmp silmus  
#4
+3
Nick Gammon
2015-07-07 07:17:10 UTC
view on stackexchange narkive permalink

Kirjutasin postituse teemal Miks ühe LED-i vilkumiseks kulub 1000 baiti?.

Lühike vastus on: "Vilgutamiseks pole vaja 2000 baiti kaks valgusdioodi! "

Pikem vastus on, et Arduino tavalistel teekidel (mida te ei pea kasutama, kui te seda ei soovi) on teie funktsiooni lihtsustamiseks mõnus funktsioon elu. Näiteks võite tihvtid adresseerida käitamise ajal numbri järgi, kus teek teisendab (ütleme) tihvti 8 õigeks pordiks ja korrektseks bitinumbriks. Kui pääsete porti kõvakoodiga, saate selle üldkulu salvestada.

Isegi kui te neid ei kasuta, sisaldavad standardsed teegid koodi, et loendada "puuke", et saaksite teada praeguse "aja" ( helistades millis () ). Selleks peab see lisama mõne katkestusteenuse rutiini lisakulud.

Kui lihtsustate selle visandi jaoks (Arduino Unos), saate programmi mälumahu alla 178 baiti (IDE 1.0-l. 6):

  int main () {DDRB = bit (5); samas (tõene) PINB = bit (5); }  

OK, 178 baiti pole nii palju ja sellest esimesed 104 baiti on riistvarakatkestuse vektorid (igaüks 4 baiti 26 vektori jaoks).

Nii et vaieldamatult on LED-i vilkumiseks vaja ainult 74 baiti. Ja neist 74 baiti on enamik kompilaatori loodud koodi globaalse mälu initsialiseerimiseks. Kui lisate kahe LED-i vilkumiseks piisavalt koodi:

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

Siis suureneb koodi suurus 186 baidini. Seega võiksite väita, et LED-i vilkumiseks kulub ainult 186 - 178 = 8 baiti.

Nii et LED-i vilkumiseks on vaja 8 baiti. Kõlab minu jaoks üsna tõhusalt.


Kui teil on kiusatus seda kodus proovida, peaksin märkima, et kuigi ülaltoodud postitatud kood vilgutab kahte LED-i, teeb see seda tõesti väga kiiresti. Tegelikult vilguvad need sagedusel 2 MHz - vt ekraanipilti. Kanal 1 (kollane) on tihvt 12, kanal 2 (tsüaan) on tihvt 13.

Rapid blinking of pins 12 and 13

Nagu näete, on väljundtappidel ruutlaine sagedusega 2 MHz. Tihv 13 muudab koodis olevate tihvtide vahetamise järjekorra tõttu olekut 62,5 ns (üks taktsükkel) enne tihvti 12.

Nii et kui teil pole palju paremaid silmi kui minul, siis te seda ei tee tegelikult näevad mingeid vilkuvaid efekte.


Lõbusa lisana saate programmi ruumi samas mahus ümber lülitada kaks nööpi. üks tihvt.

  int main () {DDRB = bit (4) | bitti (5); // seadistage tihvtid 12 ja 13 väljundiks, kui (true) PINB = bit (4) | bitti (5); // vahetavad tihvte 12 ja 13} // peaosa lõpp  

See kompileeritakse 178 baidiks.

See annab teile suurema sageduse:

Very rapid blinking of pins 12 and 13

Nüüd oleme sagedusega 2,66 MHz.

See on väga mõistlik. Nii et kas standardraamatukogud lisatakse ehitamise ajal automaatselt ainult päistele? Ja kuidas suutsite neid * mitte * kaasata?
Linker eemaldab agressiivselt koodi, mida ei kasutata. Kui te ei kutsunud funktsiooni "init ()" (nagu seda teeb tavaline "main ()", ei olnud faili wiring.c (milles on "init") lingitud. Selle tulemusena katkestuskäitlejate töötlemine ( "millise ()" jaoks jäeti välja "mikros ()" jne. Selle väljajätmine pole ilmselt eriti otstarbekas, välja arvatud juhul, kui teil pole kunagi vaja asju ajastada, kuid fakt on see, et visandi suurus suureneb sõltuvalt sellest, mida te selle panete. Näiteks kui kasutate Seriali, saavad löögi nii programmi mälu kui ka RAM.


See küsimus ja vastus tõlgiti automaatselt inglise keelest.Algne sisu on saadaval stackexchange-is, mida täname cc by-sa 3.0-litsentsi eest, mille all seda levitatakse.
Loading...