Arduino Due - a bonckés alatt

A korábban elméleti síkon már elemzett Arduino-zászlóshajónak kikiáltott Arduino Due kerül ma a gyakorlatban is a bonckés alá... (Tipp: http://www.tavir.hu/cikk-arduino-due )
Előzmények: az ATMega-x8 processzoros Arduino áramkörök kapcsán felmerült, hogy sok feladatra már lassúak, és kicsi a memóriájuk. Ezen problémán két módon lehet segíteni:

  1. Optimalizált programozás, célirányos fejlesztés,
  2. Központi chip bővítésével vagyis cseréjével.

Az első megoldás nem volt járható út, mivel a teljes rendszert az alapjaitól kellene újraírni - elveszítve a hordozhatóságot, a függvénykönyvtárakkal való egyszerű bővíthetőséget.
Maradt a processzorcsere. Ennek első állomása a központi chip ATMega1280 majd később ATMega2560-ra való cseréje volt: így született meg az Arduino Mega családvonal. Az átállás a mai napig kompromisszumokkal jár: a Mega panelek lábkiosztása nem teljesen csereszabatos a klasszikus Arduino vonallal.


Arduino Mega pinout (Katt a képre!)  

Azonban, ha ezehet a programtervezésnél figyelembe vesszük illetve a felhasznált függvénykönyvtátak elfedik előlünk, akkor sínen vagyunk. Egy 128/256 kbyte programmemóriát tartalmazó, soklábú áramkör az eredmény:

ATMega2560

De vigyázni kell rá: míg az ATMega x8 család egyszerűen cserélhető a DIP toknak köszönhetően, az Arduino Mega központi chipek esetén biztos kéz, jó szem és speciális szerszámok szükségesek...
A memóriakérdés ezzel a változtatással-bővítéssel megoldódott 2009-ben. A sebességi probléma azonban fennmaradt továbbra is.
Erre 2011. szeptemberéig kellett várni. Ekkor került bejelentésre az Arduino Due lapka.

Itt a központi chip már nem az Atmel AVR családja, hanem az Atmel ARM családból a Cortex-M3 magú ATSAM3X8E. Ennek sebessége immár 84 MHz. De a sebességhajkurászás az nem MHz-kben mérhető! Sokkal szembetűnőbb a MIPS mérőszám (Million Instruction Per Secundum - másodpercenkénti utasítások száma).

Chip Sebesség MIPS MIPS/MHz
ATMega (AVR8) max. 20 MHz 20 MIPS 1 MIPS/MHz
xMega (AVR8/16) max. 32 MHz 32 MIPS 1 MIPS/MHz
SAM3X (Cortex-M3) max. 84 MHz 100 MIPS 1.19 MIPS/MHz
80486SX max. 33 MHz 27 MIPS 0.81 MIPS/MHz

Mi az oka, hogy nem lineárisak a sebesség - MIPS értékek?
- A processzor maga.

A chipek adatszervezése lehet 8, 16 vagy 32 bites. Ezáltal az egyszerre, egy lépésben megmozgatható önállóan leírható számok egyre nagyobbak. De a chip belső felépítése, utasításszervezése is nagyon sokat számít! Persze a nyers teljestmény csak a végtelenségig optimalizált szintetikus teszteket tartalmazó programmal mutat jól. A való életben a realitás talaján rontjuk el a programjainkat...

Negatívumok...

Az ARM chipes rendszer nagy nyers számolási teljesítménnyel bír - amit pillanatok alatt le tudunk amortizálni. Ezek az Arduino programnyelv pazarló, egymásba ágyazott függvénykönyvtáraira vezethetők vissza. Ez nem változott eddig a fejlődés során.

Tört számok

A processzorok nagy rákfenéje a tört számok. Ezek ábrázolása ún. lebegőpontosan történik és a processzoroknak ebből kell - egész számok képességével - számolniuk. Olyan ez mintha általános iskola elején / óvoda végén a gyermekednek a 30 tized almát ossz el 45 részre című kérdést teszed fel. Ha rutinos, akkor megoldás gyanánt vagy almapürét gyárt és azt ossza el, vagy almáspitét süt és az darabolja :) .

Itt is ez a helyzet. Ezért ahol lehet, egész számokkal dolgozunk...

És mi az ami a feltételezés? És műszakilag az elmélet sosem megoldás. Mindig gyakorlatban akarjuk látni a megoldást. Így itt is ez a feladat:
Egy egyszerű alkalmazásban számoljuk ki az 1.00001 százezredik hatványát.

Erre mit tehetünk? Két egyszerű megoldást tesztelünk:

  • (4/3)^10 és ezt 1000x ismételjük
  • (4^10)/(3^10) és ezt 1000x ismételjük

A mintaprogram az első esetben:

unsigned long time22;

void setup(){
  Serial.begin(9600);
}
void loop(){
  long i,j;
  double k;
  double f=1.3333333333333333333333333333333333;

  Serial.print("Time: ");
  time22 = micros();
  //prints time since program started
  //10.000 x run
  for (i=0; i<1000; i++){
    k=f;
    for (j=0; j<10; j++){   
      k = k * f;
    }
   }
  Serial.print(micros()-time22);
  Serial.print(' ');
  Serial.println(k);
  delay(1000);
}

A második esetben:

unsigned long time22;

void setup(){
  Serial.begin(9600);
}
void loop(){
  long i,j;
  long k;
  long f;
 
  Serial.print("Time: ");
  time22 = micros();
  //prints time since program started
  //10.000 x run
  for (i=0; i<1000; i++){
    k=4;
    f=3;
    for (j=0; j<10; j++){    
      k = k * 4;
      f= f * 3;
    }
   }
  Serial.print(micros()-time22);
  Serial.print(' ');
  Serial.println(k/f);
  delay(1000);
}

És a lényeg:

Alappanel Chip Program Futásidő
Arduino Diecimila/328 ATMega328@16MHz Lebegőpontos, 10000 futás 20.084 usec
Arduino Due SAM3x8E@84 MHz Lebegőpontos, 10000 futás 1027 usec
Arduino Diecimlia/328 ATMega328@16 MHz Egészszámos, 10000 futás 999.620 usec
Arduino Due SAM3x8E@84 MHz Egészszámos, 10000 futás 164.475 usec

Az ARM mag nyert. Viszont csak a nyers számítási sebesség látszik, azaz a számítási különbség a MIPS és az órajel függvényében. Ha az eggyel újabb/következő lépcsős processzort használták volna a Due létrehozásához, akkor az abban levő matematikai cél-processzorra hárítható lett volna a feladat.

Programkód

Az egymásba ágyazott, többszörösen meghívott függvények sem tesznek jót a sebességnek. A fordítóprogram nem tudja ezeket kioptimalizálni.
Sőt, ha belenézünk a kódba, akkor nem nagyon találunk ARM-specifikus kódrészleteket. Ilyen lenne a többszintű megszakítás, a blokkos memóriaátvitel (DMA) használata. Ezek teljesítménycentrikus doppingszerként tudnak viselkedni - ha használják őket. Talán, ahogy a fordító fejlődik belekerül.

Bemenetkezelés

Az ARM alapú rendszerek rendszerfeszültsége 3.3V. A beépített Atmel SAM3x8E processzor ki/bemenetei is 3.3V-osak - de nem 5V toleránsak. Ennek végzetes következményei vannak!
Az Arduino fedpanel-lapkák (shieldek) az 5V-os alaprendszerekhez készültek. Ez a ki-/bemenetekre is vonatkozik. Ha egy ilyen fedpanel kimenetén megjelenő 5V-ot az Arduino Due bemenetére kapcsolunk: chiphalál lesz a vége :(. Semmiféle védelem nem került beépítésre a DUE oldaláról!
Néhány shield be-/kimeneti jelszintillesztéssel rendelkezik már, vagy az azon levő áramkör a jelszintekre nem érzékeny. Ilyen az Ethernetshield, melyen levő 3.3V-os Wiznet W5100 chip bemenetei 5V toleránsak és az itt levő SD kártya illesztéséről a 74HCT125 jelszintillesztést végző chip gondoskodik.
Fontos! Arduino DUE esetén a csatlakoztatandó shield-et ilyen szemmel (is) mindig nézzük át!

Funkciolábak

Az Arduino mega esetén kezdődött a funkciolábak részleges elvándorlása.

Kialakítás

Az Arduino Due két USB csatlakozóval szerelt. Egyik a soros-USB átjárást biztosító Uno-nál debütát ATMega16U2 chiphez kapcsolódó felület, a másik a központi chip natív USB portját célozza meg. A csatlakozó felületszerelt mikro-USB. Így végre nincs véletlen rövidzár az USB csatlakozó és a shieldpanel közt.
Az USB csatlakozók sorában a "B" csatlakozó található meg az Arduino családban: a normál, mini és mikro. A gyári (official) a normált, míg a Due a mikro-t tartalmazza. Néhány esetben a továbbfejlesztett alappanelek a mini csatlakozást tartalmazzák a normál helyett (ilyen a teljes AVR-Duino család (Diecimila R3 , Duemilanove R3, Uno R3)).

A csatlakozások

Az Arduino az első megjelenésétől kezdve külső tápcsatlakozóval, illetve a shieldpanelek csatlakoztatására szolgáló hüvelysorral rendelkezik. Az Arduino a sikerét annak köszönheti, hogy a csatlakozás/bővítés "házon belüli" szabvánnyá vált. Ez két módon változott - a kompatibilitást lehetőleg megtartva:

  • Arduino Mega megjelenésével: újabb hüvelysorok megjelenésével és dedikált funkcionalitással,
  • R3 fejlesztés: amint az Arduino Due 3.3V-os rendszermagja és az új chipek megjelenése hozott.

Újdonságok az Arduio Due mentén

A rendszer teljesen megújult chipet tartalmaz, ahol nem csak perifériabővülés történt, hanem a teljes architektúra átalakult. Lehet, hogy néhány év múlva úgy tekintünk erre, hogy a kontroller-világ vége. De ez még nagyon-nagyon messze van.
Az Arduino Due magja az Atmel SAM3x chipcsaládból került ki. Valódi 32-bites, Cortex-M3 magot tartalmazó ARM processzor.

Mit nyertünk?

  • A processzor sebessége 16 MHz helyett 84 MHz. Az utasításvégrehajtási sebessége is legalább ennyivel nő.

De nézzünk néhány "szintetikus" tesztet:

  • egész/long,
  • lebegőpontos,
  • i/o vezérlés.
  • belső memória sokkal nagyobb,

A processzor speciális funkcióiról sem szabad elfeledkezni:

  • beépített CAN-busz,
  • több hardware alapú I2C/TWI (wire) port,
  • két digital-analog átalakító...

Vesztes oldal

Mert sosincsen olyan, hogy csak nyerünk valamin:

  • 3.3V-os rendszer, az ennek megfelelő illesztési követelményekkel (bár mostanában egyre több a tisztán 3.3V-os rendszer)
  • a Mega rendszerekkel összemérhető ár, ám jóval alacsonyabb függvénykönyvtár-támogatás,
  • az utánépítés-standalone felhasználás esélytelen a 0.5 mm SMD lábkiosztás miatt.

De mi van a RaspberryPi-vel?

Az ár oldalon sűrűn emlegetik a RaspberryPi (RasPi) rendszereket. Míg az Arduino hardwareközeli, kontroller alapot képvisel, addig a RasPi inkább a komplett, beágyazott PC világot. Amolyan alma-körte összehasonlítás (vagy inkább még távolabb: az egyik málna, a másik meg tökféle).

Szóval mindkettő helye ott van, de a feladat dönti el, hogy mire használjuk...

 

Felhasznált források:

TavIR-Facebook