Programovanie Arduino (a derivátov) bez Arduino IDE #2

30.03 | 17:18 | Richard | Richard

V dnešnej časti seriálu si povieme, ako funguje arduino-cli, program, ktorý umožňuje kompiláciu, nahrávanie, správu knižníc… to všetko pre svet Arduina a jeho kamarátov.

Obsah minulej časti + čo s tým originálnym IDE?

V minulej časti sme si stručne povedali, čo sa deje, ak si v Arduino IDE doinštalujeme vývojové dosky. A tiež, ako to môžeme spraviť ručne. A tiež, že to nie je síce kozmická veda, ale ručne je to možno zbytočne iritujúce.
Keďže chceme programovať Arduiná a podobné vývojové dosky z iného prostredia, musíme sa zmieriť s tým, že alebo to spravíme ručne, dopomôžeme si arduino(m)-cli, alebo si necháme na disku i Arduino IDE a strpíme zaprataných cca 0,5 GB priestoru.


Alebo si originálne IDE nejako zoštíhlime, zmažeme to, čo vôbec nepotrebujeme k inštalácii dosiek a knižníc (tie si navyše môžeme inštalovať i pomocou arduino-cli). Dá sa okliešiť na cca 100 MB a to tak, že:


A už je to veselšie. Aj pri súčasnych veľkých diskoch ma vždy poteší, ak môžem nejaký priestor ušetriť. Mám z toho dobrý pocit, aj keď ten priestor reálne nepotrebujem 😉. Možno sa jedná o nejaký odklon od normálnosti, alebo nevyliečená bolesť z minulosti. Erudovaná osoba by vedela zhodnotiť ☺.


Prinajhoršom, vždy si môžeme Arduino IDE stiahnúť, takže zásadné škody nehrozia.

 

Ako funguje arduino-cli

Skôr než sa pozrieme na praktické príklady použitia arduino-cli, v rýchlosti si povieme, ako a čo spomínaný program robí.

 

Súbor arduino-cli.yam

V ~/.arduino15 by sme takýto súbor mali mať. Ak chýba, dá sa vytvoriť pomocou arduino-cli config init.
V ňom sú dôležité tieto riadky:

directories:
  data: /home/richard/.arduino15
  downloads: /home/richard/.arduino15/staging
  user: /home/richard/.prog/arduino-1.5.7/Moje

V náhľade z môjho súboru vidíme, že je tam definované, kde sa nachádza samotný ~/.arduino15 (a teda dôležité podadresáre v ňom), kde sa dočasne sťahujú nové knižnice a kde máme uložené naše programy. Ja mám historicky adresár ešte z čias v 1.5.7. ☺

Adresáre hardware

Len pripomeniem, že základom sú adresáre
~/.arduino15/packages/<vývojová doska>/hardware/<architektúra>/<verzia>
Konkrétne napr.: ~/.arduino15/packages/industrialshields/hardware/avr/1.1.43.


Každá architektúra obsahuje tri dôležité súbory: boards.txt, platform.txt a programmers.txt.

A z týcho súborov "čerpá" arduino-cli parametre pri zostavovaní príkazov pre kompiláciu a nahrávanie.


Súbor boards.txt obsahuje definície vývojových dosiek, napríklad množstvo pamäte, "fuses", rýchlosť procesora…
Súbor platform.txt obsahuje parametre pre avr-gcc, preprocesor i avrdude. Pohľadom na množstvo údajov nás poteší, že toto nemusíme ručne zadávať, ale že to niekto spravil za nás.
Súbor programmers.txt obsahuje definície externých programátorov, na napálenie bootloader-a a pod.

 

Proces kompilácie

V platform.txt vidíme nielen parametre pre preklad, linkovanie,… , ale aj postup, ako sa to vykonáva. Deje sa to v tejto postupnosti:


Tieto vytvorené súbory sa potom nachádzajú v /tmp/arduino/sketches/ a sú pripravené na nahratie.

 

Čo je to FQBN?

Je to skratka z Fully Qualified Board Name ("plne kvalifikovaný názov dosky"). Ide o jedinečný identifikátor konkrétnej dosky, ktorý zvyčajne obsahuje typ dosky, model mikrokontroléra, taktovaciu frekvenciu a ďalšie dôležité informácie.
Je to jedným z nevyhnutných parametrov zadávaných pre arduino-cli, ktorý sa skladá z nasledovného:
<výrobca>:<architektúra>:<označenie dosky>[=<ďalšie možnosti, napr. typ procesora>]


Napríklad pre:

DoskaFQBN
Arduino Unoarduino:avr:uno
Arduino Leonardoarduino:avr:leonardo
Arduino Uno WiFiarduino:avr:unowifi
Industrial Shields Ardbox Analog HF+industrialshields:avr:ardbox:cpu=ardboxanaloghfplus232
Industrial Shields M-Duino 58+industrialshields:avr:mduino:cpu=mduino58plus
Raspberry Pi Picorp2040:rp2040:rpipico:flash=2097152_0,freq=133,opt=Small,rtti=Disabled,
 stackprotect=Disabled,exceptions=Disabled,dbgport=Disabled,dbglvl=None,
 usbstack=picosdk,ipstack=ipv4only

Tak OK, to Pico je trochu moc ☺.


Ako zistiť tieto FQBN?

Príkazom arduino-cli board listall zistíme FQBN pre všetky inštalované dosky.
Pre dosky, kde sa nevyžaduje špecifikácia ďalších parametrov (napr. cpu), to postačuje. Teda všetky základné dosky Arduino, ale aj iné, napr. Adafruit.


Ako sme si povedali, dosky sú uvedené v súbore boards.txt.
Konkrétne pre IndustrialShields:
~/.arduino15/packages/industrialshields/hardware/avr/1.1.43/boards.txt


Tam sa to dá pohľadať, ale spravme si to trochu krajšie:

Vylistovanie zoznamu cpu a názvov dosiek

sed -n -e '/^##/{n;n;/cpu/p}' boards.txt > extr01.txt


Časť súboru s vyextrahovanými cpu:

ardbox.menu.cpu.ardboxanalog=Ardbox Analog
ardbox.menu.cpu.ardboxanaloghf232=Ardbox Analog HF w/ HW RS-232
ardbox.menu.cpu.ardboxanaloghf485=Ardbox Analog HF w/ HW RS-485
ardbox.menu.cpu.ardboxanaloghfplus232=Ardbox Analog HF+ w/ HW RS-232
ardbox.menu.cpu.ardboxanaloghfplus485=Ardbox Analog HF+ w/ HW RS-485
ardbox.menu.cpu.ardboxanaloghflegacy=Ardbox Analog HF (legacy)


A vyextrahovaný cpu a názov dosky, oddelenej <tab>:

sed -n 's/.*\.cpu\.\(.*\)=\(.*\)/\1\t\2/p' extr01.txt  > subor.txt


Opäť časť súbory po tomto príkaze:

ardboxanalog	Ardbox Analog
ardboxanaloghf232	Ardbox Analog HF w/ HW RS-232
ardboxanaloghf485	Ardbox Analog HF w/ HW RS-485
ardboxanaloghfplus232	Ardbox Analog HF+ w/ HW RS-232
ardboxanaloghfplus485	Ardbox Analog HF+ w/ HW RS-485
ardboxanaloghflegacy	Ardbox Analog HF (legacy)


Keď to skombinujeme, tak napríklad pre dosku Ardbox Analog HF w/ HW RS-485 (jedná sa o dosku s hardvérovým RS-485), máme FQBN:
industrialshields:avr:ardbox:cpu=ardboxanaloghf485


A s týmto sa dá ďalej pracovať.

 

 

Kompilácia pomocou arduino-cli

Na úvod si opíšme základné príkazy arduino-cli. Tie sa zadávajú nasledovne:
arduino-cli <príkaz> [prepínače], kde príkazy sa skladajú zvyčajne z viacerých slov. Nebudem uvádzať všetky príkazy, ale len tie, ktoré sa bežne používajú:


Program rozpoznáva tieto prepínače

prepínačprepínačopis
skráteneplný názov 
-b--fqbnplne kvalifikovaný názov dosky
-h–-helpnápoveda
-p–-portadresa portu pripojenej doske, napr. /dev/ttyACM1
-P–-programmertyp programátora, napr. atmel_ice
-v–-verbosebohatší výstup
-t–-verifyskontrolovanie nahranej binárky po nahratí

 

príkazupresnenieopispríklad
boarddetailsvypíše informácie o doskearduino-cli board details -b arduino:avr:uno
 listvypíše zoznam pripojených dosiekarduino-cli board list
 listallvypíše zoznam inštalovaných dosiekarduino-cli board list all
 searchhľadanie inštalovanej doskyarduino-cli board search uno
compile preklad programu- bude uvedený nižšie -
corelistvypíše zoznam nainštalovaných dosiekarduino-cli core list
 installstiahnutie a nainštalovanie dosky a závislostíarduino-cli core install arduino:samd
 searchhľadanie v zozname dosiek na inštaláciu 1arduino-cli core search industrialshields
 uninstallodinštalovanie dosky a závislostiarduino-cli core uninstall arduino:samd
 upgradepovýši verziu nainštalovaných dosiekarduino-cli core upgrade
daemon spustenie arduino-cli na porte 50051arduino-cli daemon
liblistvypíše zoznam nainštalovaných knižnícarduino-cli lib list
 examplesvypíše zoznam príkladov pre všetky knižnicearduino-cli lib examples
 installnainštaluje knižnicu (možnosť zadania i git-u)arduino-cli lib install AudioZero
 searchstiahne zoznam udržiavaných knižníc a umožní v ňom hľadaniearduino-cli lib search rs232
 uninstallodinštalovanie knižnicearduino-cli lib uninstall AudioZero
 upgradepovýši verziu nainštalovaných knižnícarduino-cli lin upgrade
monitor spustí v konzole "serial monitor"arduino-cli monitor -p /dev/ttyACM0
upload nahranie binárky do dosky- bude uvedené nižšie

 

Samotná kompilácia

…je jednoduchá:
arduino-cli compile -b <FQBN> <program.ino>


Prípadne môžeme použiť prepínať -v a kochať sa, ako ten šikovný arduino-cli krásne pracuje.


Trochu konkrétneho výpisu (hodil by sa celý, ak by sme boli honorovaní od počtu riadkov ☺):

/home/richard/.arduino15/arduino-cli compile -v -b industrialshields:avr:mduino:cpu=mduino58plus bf-220.ino

FQBN: industrialshields:avr:mduino:cpu=mduino58plus
Using board 'mduino' from platform in folder: /home/richard/.arduino15/packages/industrialshields/hardware/avr/1.1.43
Using core 'industrialshields' from platform in folder: /home/richard/.arduino15/packages/industrialshields/hardware/avr/1.1.43

Detecting libraries used...

/home/richard/.arduino15/packages/industrialshields/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c 
-g -Os -w -std=gnu++11 -fpermissive
 -fno-exceptions -ffunction-sections 
-fdata-sections -fno-threadsafe-statics 
-flto -w -x c++ -E -CC -mmcu=atmega2560 
-DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_MEGA2560 
-DARDUINO_ARCH_AVR -DMDUINO_PLUS -DMDUINO_58_PLUS 
-I/home/richard/.arduino15/packages/industrialshields/hardware/avr/1.1.43/cores/industrialshields 
-I/home/richard/.arduino15/packages/industrialshields/hardware/avr/1.1.43/variants/mduinoplus
/tmp/arduino/sketches/41FF550E4390E30E91E0F3E204F4BC3E/sketch/bf-220.ino.cpp -o /dev/null

Alternatives for Wire.h: [Wire@1.0]

ResolveLibrary(Wire.h)
  -> candidates: [Wire@1.0]

/home/richard/.arduino15/packages/industrialshields/tools/avr-gcc/7.3.0-atmel3.6.1-arduino5/bin/avr-g++ -c -g 
-Os -w -std=gnu++11 -fpermissive -fno-exceptions 
-ffunction-sections -fdata-sections -fno-threadsafe-statics 
-flto -w -x c++ -E -CC -mmcu=atmega2560 -DF_CPU=16000000L 
-DARDUINO=10607 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR 
-DMDUINO_PLUS -DMDUINO_58_PLUS 
-I/home/richard/.arduino15/packages/industrialshields/hardware/avr/1.1.43/cores/industrialshields 
-I/home/richard/.arduino15/packages/industrialshields/hardware/avr/1.1.43/variants/mduinoplus 
-I/home/richard/.arduino15/packages/industrialshields/hardware/avr/1.1.43/libraries/Wire/src

⋮
⋮
⋮

Sketch uses 27040 bytes (10%) of program storage space. Maximum is 253952 bytes.
Global variables use 2109 bytes (25%) of dynamic memory, leaving 6083 bytes for local variables. Maximum is 8192 bytes.

Used library      Version Path
Wire              1.0     /home/richard/.arduino15/packages/industrialshields/hardware/avr/1.1.43/libraries/Wire
LiquidCrystal I2C 1.1.2   /home/richard/.prog/arduino-1.5.7/Moje/libraries/LiquidCrystal_I2C-1.1.2
EEPROM            2.0     /home/richard/.arduino15/packages/industrialshields/hardware/avr/1.1.43/libraries/EEPROM
blink-tf          1.0     /home/richard/.prog/arduino-1.5.7/Moje/libraries/blink-tf
debounce-tf       1.0     /home/richard/.prog/arduino-1.5.7/Moje/libraries/debounce-tf

Used platform         Version Path
industrialshields:avr 1.1.43  /home/richard/.arduino15/packages/industrialshields/hardware/avr/1.1.43

Nahrávanie

Na začiatok jedno upozornenie. Ak používame originálne Arduino IDE, tak po stlačení tlačidla Upload sa zdrojový kód preložil a až potom nahral.
Pri použití arduino-cli sa nahrá obsah v /tmp/arduino/sketches/.
Takže ak si nie sme istí, či sme máme skompilovaný najaktuálnejší kód, je lepšie to pred nahrávaním spraviť.


Syntax pre nahrávanie je:

~/.arduino15/arduino-cli upload -v -b <FQBN> -p <port> <program.ino>


Napríklad: ~/.arduino15/arduino-cli upload -v -b industrialshields:avr:mduino:cpu=mduino58plus -p /dev/ttyACM0 bf-220.ino

 

Obsah ďalšej časti

Nabudúce si v rýchlosti ukážeme, ako si spraviť Makefile, aby sme to mali predsa len trochu efektívnejšie.

Poznámky:

1

Ak sú pridané do arduino-cli.yaml napríklad tieto riadky:

board_manager:
  additional_urls:
    - https://arduino.esp8266.com/stable/package_esp8266com_index.json

Teraz by sa mohlo zdať, že ručné pridanie dosiek, ako sme to robili v prvej časti seriálu je zbytočné. Nie je tomu tak, pretože niektoré dosky nie sú k dispozícii s json opisom. A samozrejme, je to potrebné poznať, ak si vyrábame vlastnú dosku, alebo modifikujeme existujúcu (konkrétny príklad - keď sme požadovali v IndustrialShields úpravu plošného spoja, aby RS232/RS485 nebol pripojený na UART piny Leonardo-a, ale na iné, s využitím SoftwareSerial, tak dosky boli dávno vyrobené, predané, aplikované v stroji, ale nikto neaktualizoval softvérové náležitosti 😉, tak sme to robili sami).