SAD - Simple Arduino Debugger

Debugging a spol.
Debugging je sústava úkonov spojená s hľadaním chýb, ich analyzovaním a v neposlednom rade aj ich odstránením. Vo svete „bežného“ programovania na to existujú šikovné nástroje, ako napríklad známy GDB (GNU Debugger) pre jazyky C, C++, Ada,… Kedysi boli prepracované debuggery i súčasťou populárnych IDE od Borland-u, ako Turbo Pascal, Turbo C, alebo Delphi.
U mikrokontrolérov je to trochu komplikovanejšie. U niektorých viac, u iných menej. Napríklad ESP32 podporuje hardvérové debuggovanie - napríklad známe, relatívne lacné zariadenia J-Link. Podobné je to aj so zariadeniami s čipom ARM Cortex-M (niektoré arduiná).
U procesorov ATmega, ktoré sú v populárnych arduinách radu Uno, Leonardo, Mega, atď., hardvérové debugovanie nie je možné. Respektívne, existuje prístup známy ako GDBStub, kde je externý hardvérový debugger pripojený na sériové piny mikrokontroléra (alebo virtuálne, definované pomocou SoftwareSerial
), ktorý potom pomocou pluginu pre Visual Studio a Visual Micro dokáže načítať stavy pamäte.
Ak je človek zvyknutý na iné IDE a iné nástroje, tak nebude kvôli tomu siahať na iný operačný systém. A preto sa debuggovanie arduín vždy robilo sústavou výpisov na sériovú konzolu… čo by nebolo zlé, keby to nebolo nemotorné.
Jednoduché riešenie pomocou Sad
Sad je knižnica, ktorá, ako hovorí názov, je simple a teda nedokáže zázraky, ale zásadne zlepší vypisovanie a úpravu premenných v bežiacom programe. Je to skorá verzia, ktorú som naprogramoval v krátkom čase, ale už aj teraz dokáže toto:
- Nastaviť breakpoint-y - ktoré zastavia program v určitom mieste a to:
- ak teda program dorazí do tohto miesta,
- alebo ak je splnená definovaná podmienka.
- Výpis premenných a ich umiestnenie v pamäti.
- Zmena týchto premennných.
Akákoľvek interakcia je samozrejme pomocu sériovej konzoly. Napríklad:
- originálny serial monitor v Arduino IDE,
- externé programy, námatkou:
- CuteCom (https://cutecom.sourceforge.net/),
- serial-term v multifunkčnom GNU Emacs,
- CoolTerm (https://freeware.the-meiers.org/#CoolTerm),
- textový Minicom (v repozitároch distribúcií),
- HTerm (https://der-hammer.info/pages/terminal.html),
- alebo aj možné aj použitie unixového cu.
Vidno, že sa užívateľom nekladú žiadne medze a každý si nájde to svoje.
Inštalácia
Je prostá:
- Naklonovať repozitár príkazom
git clone https://gitlab.com/arduino91/sad-tf
, alebo si ho stiahnuť z tohto odkazu klinutím na modré tlačidlo CODE a zvoliť si typ archívu (napr. .zip). - Celý adresár si nakopírovať do priečinu s knižnicami, ktorý nesie meno libraries a je podpriečinkom zadanej cesty v Arduino IDE, alebo v
arduino-cli.yaml
, alebo vpreferences.txt
pre Arduino IDE.
Potom sa príklad použitia „objaví“ i v príkladoch priamo v Arduino IDE. - A dá sa použiť i lokálne, v konkrétnom projekte, ak sa k nemu nakopírujú súbory
Sad_tf.cpp
aSad_tf.h
.
Príklady použitia
Vloženie knižnice
Ak ju máme nainštalovanú v dedikovanom priečinku s knižnicami, tak:
#include <Sad_tf.h>
Ak ju chceme použiť lokálne v projekte, a máme spomínané súbory nakopírované v adresári s projektom, tak:
#include "Sad_tf.h"
Vytvorenie inštancie triedy
… použitím Sad_tf <názov inštancie>;
, napríklad:
Sad_tf breakPoint;
Inicializácia sériovej komunikácie
Ak sme ju nikde v programe zatiaľ nepoužili, tak niekde v setup-e zadáme Serial.begin(<rýchlosť v baudoch>);
, napríklad:
Serial.begin(9600);
Samotné použitie funkcií
Knižnica (nateraz) pozná tieto tri verejné funkcie:
Vloženie breakpoint-u s čítaním/zmenou premenných typu int a byte
Príklad:
breakPoint.BPi(3, "i - int", &i, "j - byte", &j, "k", &k);
Metóda BPi
je tzv. variadická funkcia (teda funkcia s premenlivým počtom argumentov) a má tieto parametre:
- 1. parameter je počet sledovaných premenných (v našom príklad sú 3 - i, j a k);
- samotné premenné, ktoré sa skladajú z dvojíc: opis premennej - adresa premennej.
Takže to, čo zadáme do úvodzoviek sa nám vypíše do konzoly ako text (napr. meno premennej, alebo jej opis,…), a druhý argument je vždy adresa premennej. Kto sa nekamaráti s touto terminológiou, tak tomu stačí informácia, že sa zadá znak & a za ním označenie (názov) premennej, tak to máme v programe.
Vloženie breakpoint-u s čítaním/zmenou premenných typu long
Príklad:
breakPoint.BPl(1, "m", &m);
Čo je úplne identické s použitím predchádzajúcej funkcie.
Vloženie breakpoint-u, ktorý zastaví program pri splnení podmienky
Funkcie predtým uvedené zastavia program, keď ku ním program proste „dorazí“. Táto funkcia zastaví vykonávanie programu, ak je splnená nejaká podmienka a tou je aritmetické porovnanie ľubovoľnej premennej so zadanou hodnotou.
Príklad napovie:
breakPoint.BPwi(3, "eq50", &i, "i - watched int", &i, "j - byte", &j);
Parameter eq50 a za ním &i znamenajú, že program sa zastaví, ak premenná i dosiahne hodnotu 50.
Teda možnosti sú:
eqXX
(equal to XX) - rovný XXgtXX
(greater than XX) - väčší ako XXltXX
(lower than XX) - menší ako XX
Čo sa dá robiť, keď sa program zastavil?
Ak sa zastavil neplánovane, tak to je zlé, ale ak sme to takto chceli, tak môžme interagovať s programom, cez sériovú konzolu, nasledovne:
Zastavenie programu, napríklad pri podmienke vyzerá takto:
::: Watched breakpoint :::
:List of variables:
#0: eq50 = 50 @ memory: 2297
#1: i - watched int = 50 @ memory: 2297
#2: j - byte = 100 @ memory: 2299
Vypíšu sa nám zadané premenné a ich adresy. Zadaním h
z konzoly sa vypíše nápoveda:
> h
:Help:
lv = list variables
cv = change variable
h = print this help lines
c = continue executing program
Zadaním lv
sa (opäť) vypíšu obsahy premenných. Zadaním cv
môžeme zvolenú premennú modifikovať, pričom zadáme jej označenie (napr. premenná č. 1) a následne jej novú hodnotu.
> cv
:List of variables:
#0: i - int = 1 @ memory: 2297
#1: j - byte = 2 @ memory: 2299
:Enter variable number (q = quit): 1
> 1
:Enter NEW value for variable "j - byte" (q = quit): 500
> 500
Program nekontroluje, či novo zadaná premenná má zmysel, či sedí údajový typ a podobne. Proste „natrvdo“ zapíše na správne pamäťové miesto nový údaj, ktorý v prípade zadania nepatričnej hodnoty môže spôsobiť i pád programu. Zadaním c
postúpime k ďalšiemu breakpoint-u. Ešte detail: maximálny počet argumentov týchto funkcií je definovaný v Sad_tf.h
, príkaz #define numVars 10
.
Záverom
Túto knižnicu som spravil, aby som si uľahčil hľadanie chýb v mojich programoch. A teda robí to, čo som považoval za potrebné a pre mňa využiteľné. Ak však má niekto nápad, čo by sa tam dalo pridať, nech ma kontaktuje. Ešte detail - preklad z dokumentácie na gitlabe:
Výhody
- Jednoduché používanie.
- Jednoduchá úprava knižnice.
- Žiadne divné triky jazyka C.
Nevýhody
Priložená knižnica „zožerie“ cca 4490 bajtov úložného priestoru programu a cca 450 bajtov dynamickej pamäte. Ak teda váš program beží podľa očakávania, je lepšie knižnicu „odincludovať“ a body prerušenia odstrániť. Zrejme existuje trik, ako ignorovať body prerušenia, ak nie je definovaný SAD_TF_H
, vytvorením makra falošnej/prázdnej funkcie, ale nezistil som, ako to urobiť, ak je funkcia inštanciou metódy.
Ak to niekto vie, dajte mi vedieť
Máte aj vy zaujímavú konštrukciu, alebo článok a chceli by ste sa o to podeliť s viac ako 360.000 čitateľmi? Tak neváhajte a dajte nám vedieť, radi ju uverejníme a to vrátane obrazových a video príloh. Rovnako uvítame aj autorov teoretických článkov, či autorov zaujímavých videí z oblasti elektroniky / elektrotechniky.
Kontaktujte nás!