This shows you the differences between two versions of the page.
si:iot2025:lab01 [2025/07/13 10:38] robert_ionut.alexa [Linux] |
si:iot2025:lab01 [2025/08/11 12:50] (current) dan.tudose |
||
---|---|---|---|
Line 3: | Line 3: | ||
Bine ați venit la școala de vară IoT Summer School! | Bine ați venit la școala de vară IoT Summer School! | ||
- | In cadrul scolii de vara, ne propunem sa va familiarizam cu sisteme de operare RTOS (NuttX) care se preteaza mai degraba microcontrollerelor decât sistemelor de tip desktop. | + | În cadrul școlii de vară, ne propunem să vă familiarizăm cu sisteme de operare RTOS (Real time operating system) - NuttX - care se pretează mai degrabă microcontrolerelor decât sistemelor de tip desktop. |
- | În acest laborator veți învăța cum să compilați și să încărcați sistemul de operare NuttX pe smartwatch-ul [[https://github.com/dantudose/open-smartwatch|Hector Watch]], dezvoltat in facultate si bazat pe un modul **ESP32 S3 mini** la care au fost adaugate: | + | În acest laborator veți învăța cum să compilați și să încărcați sistemul de operare NuttX pe smartwatch-ul [[https://github.com/dantudose/Hacktor-Watch-2.0/|Hacktor Watch]], dezvoltat în facultate și bazat pe un microprocesor **ESP32 S3** la care au fost adăugate: |
- | * patru butoane externe | + | * doua butoane externe |
- | * un step counter | + | |
* un display cu touch | * un display cu touch | ||
* un senzor de haptics | * un senzor de haptics | ||
- | * un accelerometru | + | * un accelerometru si giroscop |
- | * un cititor de carduri microSD | + | |
- | Mai jos puteti vedea si o poza cu PCB-ul ceasului: | + | Mai jos puteți vedea diagrama hardware a ceasului: |
- | [[https://github.com/radupascale/smartwatch-licenta|{{ si:laboratoare:pcb2_no_bg.png?500 }}]] | + | {{ :si:iot2025:hacktor_watch_2.0.jpg?600 }} |
- | Pentru a putea fi folosit pe microcontrollere, NuttX are un memory-footprint foarte scăzut (de ordinul câtorva sutelor de kilobytes). Un alt feature care îl face potrivit sistemelor low-end este faptul că nu folosește mecanismele de memorie virtuală (mai costisitoare atat din punct de vedere hardware cat si software) în mod implicit, acest mod de operare numindu-se flat-mode addressing. | + | Pentru a putea fi folosit pe microcontrolere, NuttX are un memory-footprint foarte scăzut (de ordinul câtorva sute de kilobytes). Un alt feature care îl face potrivit sistemelor low-end este faptul că nu folosește mecanismele de memorie virtuală (mai costisitoare atât din punct de vedere hardware, cât și software) în mod implicit, acest mod de operare numindu-se flat-mode addressing. |
===== Setup ===== | ===== Setup ===== | ||
Line 44: | Line 42: | ||
==== MacOS ==== | ==== MacOS ==== | ||
- | Pentru a rula pe MacOS puteți urmări tutorialul de [[https://github.com/robertalexa2000/nuttx-esp32-docs/blob/si_labs/bringup/macos_tutorial.md|aici]]. | + | Pentru a rula pe MacOS, urmăriți tutorialul de [[https://github.com/robertalexa2000/nuttx-esp32-docs/blob/si_labs/bringup/macos_tutorial.md|aici]]. |
===== Compilarea și încărcarea pe placă ===== | ===== Compilarea și încărcarea pe placă ===== | ||
Line 52: | Line 50: | ||
* descărcarea unui compilator (toolchain), deoarece arhitectura target este Xtensa, deci nu putem compila cu gcc-ul default de pe distribuțiile de Linux x86 | * descărcarea unui compilator (toolchain), deoarece arhitectura target este Xtensa, deci nu putem compila cu gcc-ul default de pe distribuțiile de Linux x86 | ||
* descărcarea repository-urilor de NuttX: nuttx, apps | * descărcarea repository-urilor de NuttX: nuttx, apps | ||
- | * descărcarea tabelei de partiții și a bootloader-ului. Acestea sunt precompilate pentru fiecare release (versiune) de NuttX, însă pot fi compilate și din linie de comandă. | ||
* compilarea în urma căreia va rezulta un binar | * compilarea în urma căreia va rezulta un binar | ||
* încărcarea binarului pe placă | * încărcarea binarului pe placă | ||
Line 87: | Line 84: | ||
<note tip> | <note tip> | ||
- | NuttX folosește 2 directoare separate: | + | NuttX folosește două directoare separate: |
* nuttx, care conține sistemul de operare: scheduler, drivere, sisteme de fișiere, etc. | * nuttx, care conține sistemul de operare: scheduler, drivere, sisteme de fișiere, etc. | ||
- | * apps, care conține aplicațiile. | + | * nuttx-apps, care conține aplicațiile. |
Una din etapele compilării presupune ca sistemul de build să creeze o bibliotecă statică denumită ''libapps.a'' care va fi adăugată la binarul de NuttX în etapa de linking. | Una din etapele compilării presupune ca sistemul de build să creeze o bibliotecă statică denumită ''libapps.a'' care va fi adăugată la binarul de NuttX în etapa de linking. | ||
- | Repository-ul hectorwatch-nuttx contine nuttx si apps ca submodule care trebuie initializate (descarcate) separat. | + | Repository-ul hectorwatch-nuttx conține nuttx și apps ca submodule care trebuie inițializate (descărcate) separat. |
</note> | </note> | ||
<note important> | <note important> | ||
- | Pentru a putea rula NuttX, este nevoie sa incarcati bootloader-ul si tabela de partitii in memoria flash a ESP32-ului. Acestea pot fi compilate manual (daca aveti nevoie de modificari la bootloader, de exemplu), dar exista si binare precompilate pe care le puteti descarca de pe github: | + | Pentru a putea rula NuttX, este nevoie să încărcați bootloader-ul și tabela de partiții în memoria flash a ESP32-ului. Acestea pot fi compilate manual (dacă aveți nevoie de modificări la bootloader, de exemplu), dar există și binare precompilate pe care le puteți descărca de pe github: |
<code> | <code> | ||
Line 104: | Line 101: | ||
</code> | </code> | ||
- | Cu toate acestea, Hectorwatch-nuttx contine deja binarele precompilate in **esp32s3-bins**. | + | Cu toate acestea, Hectorwatch-nuttx conține deja binarele precompilate in **esp32s3-bins**. |
</note> | </note> | ||
- | ==== Descărcarea tabelei de partiții și a bootloader-ului ==== | + | ==== Compilarea și rularea ==== |
+ | |||
+ | Pentru a configura si compila NuttX, folosiți următoarea secvență de comenzi: | ||
<code> | <code> | ||
- | mkdir esp-bins | + | cd ~/hectorwatch-nuttx/nuttx |
- | curl -L "https://github.com/espressif/esp-nuttx-bootloader/releases/download/latest/bootloader-esp32.bin" -o esp-bins/bootloader-esp32.bin | + | ./tools/configure.sh -l hacktorwatch:usbnsh |
- | curl -L "https://github.com/espressif/esp-nuttx-bootloader/releases/download/latest/partition-table-esp32.bin" -o esp-bins/partition-table-esp32.bin | + | make -j$(nproc) |
</code> | </code> | ||
- | ==== Compilarea și rularea ==== | + | În functie de tipul de placă pe care rulați, este posibil să fie nevoie să apăsați un buton de ''BOOT'' (''IO0'') atunci când încărcați NuttX. Astfel, placa intră în modul de "Download" - în mod normal, placa este în starea de "Boot". Butonul trebuie apăsat doar atunci când se încearcă stabilirea conexiunii cu firmware-ul de pe ESP32. În cazul smartwatch-ului nostru, aveți mai jos o poză atașată care vă arată ce rol au cele doua butoane disponibile pe carcasa: |
- | <code> | + | {{ :si:iot2025:hacktor_buttons.jpg?300 }} |
- | pip3 install esptool | + | |
- | pip3 install pyserial | + | |
- | cd ~/nuttxspace/nuttx | + | |
- | ./tools/configure.sh -l esp32-sparrow-kit:nsh | + | |
- | make EXTRAFLAGS="-DESP32_IGNORE_CHIP_REVISION_CHECK" -j4 | + | |
- | esptool.py erase_flash | + | |
- | make flash ESPTOOL_PORT=/dev/ttyUSB0 ESPTOOL_BAUD=115200 ESPTOOL_BINDIR=../esp-bins | + | |
- | </code> | + | |
- | <note warning> | + | Dacă vrem să încărcăm NuttX pe un ESP32S3 (microcontroller-ul care stă la baza ceasului nostru), pentru a comuta din "Boot" in "Download" nu este suficient să apăsați un singur buton, ci trebuie să urmați o secvență de operații: ''Țineți apăsat BOOT'' -> ''apăsați RESET **o singură dată**'' -> ''ridicați degetul de pe BOOT''. Acum puteți să flash-uiți microcontroller-ul folosind comanda ''make flash ESPTOOL_PORT=/dev/ttyACM0 ESPTOOL_BAUD=115200 ESPTOOL_BINDIR=../esp32s3-bins''. |
- | Oficial, NuttX nu este garantat că funcționează pe revizii vechi ale chip-ului ESP32, și, din păcate, RTOS-ul va bloca rularea cu un PANIC, după cum puteți vedea în [[https://github.com/apache/nuttx/blob/c724ed51fbb36b3e65003e474a3b7517bb91e2e7/arch/xtensa/src/esp32/esp32_start.c#L235|codul sursă de aici]]. | + | |
- | Observăm că putem defini simbolul ''ESP32_IGNORE_CHIP_REVISION_CHECK'' pentru a trece peste această verificare, pe care îl putem insera prin variabla ''EXTRAFLAGS'' ca în exemplul de mai sus. Din păcate, acest workaround va trebui **MEREU** activat la compilare... așadar, **nu-l uitați**! | + | După ce ați terminat procesul de flash, este nevoie de încă un reset pentru a comuta înapoi din modul de "Download" in cel de "Boot". |
- | </note> | + | |
- | <hidden>Uneori, dacă se uită oricare din flaguri sau se configurează greșit proiectul (e.g., nu se pune argumentul cu tipul plăcii bun), compilarea NuttX va crăpa cu mesaje de eroare dubioase. Ca workaround de urgență (dacă nu merge un simplu ''make distclean'' și configure din nou), se recomandă ștergerea directoarelor ''nuttx'' și ''apps'' și re-descărcarea lor pentru a nu pierde timp cu depanarea în zadar... | + | Pentru a vă conecta la placă veți folosi ''picocom /dev/ttyACM0 -b 115200''. |
- | </hidden> | + | |
- | În functie de tipul de placă pe care rulați, este posibil să fie nevoie să apăsați butonul de ''BOOT'' (''IO0'') atunci când încărcați NuttX. Astfel, placa intră în modul de "Download" - în mod normal, placa este în starea de "Boot". Butonul trebuie apăsat doar atunci când se încearcă stabilirea conexiunii cu firmware-ul de pe ESP32, așa cum se poate vedea mai jos: | + | <note important> |
+ | Pentru macOS, folositi următoarele comenzi: | ||
+ | <code> | ||
+ | ./tools/configure.sh -m hacktorwatch:usbnsh | ||
+ | make -j$(sysctl -n hw.ncpu) | ||
+ | make flash ESPTOOL_PORT=/dev/cu.usbmodem101 ESPTOOL_BAUD=115200 ESPTOOL_BINDIR=../esp32s3-bins | ||
+ | sudo picocom -b 115200 /dev/cu.usbmodem01 | ||
+ | </code> | ||
- | {{ :si:laboratoare:nuttx_download_mode.png |}} | + | Observați flag-ul "-m" și denumirea diferită a portului usb. |
- | + | </note> | |
- | Pentru a vă conecta la placă veți folosi ''picocom /dev/ttyUSB0 -b 115200''. | + | |
În cazul în care sistemul de build nu detectează în mod automat calea către repo-ul de apps, aceasta poate fi specificată prin ''-a <path>''. Pentru toți parametri disponibili puteți folosi ''./tools/configure.sh -h''. Alternativ, calea către directorul de apps poate fi configurată prin ''CONFIG_APPSDIR''. | În cazul în care sistemul de build nu detectează în mod automat calea către repo-ul de apps, aceasta poate fi specificată prin ''-a <path>''. Pentru toți parametri disponibili puteți folosi ''./tools/configure.sh -h''. Alternativ, calea către directorul de apps poate fi configurată prin ''CONFIG_APPSDIR''. | ||
- | |||
- | Dacă compilați pentru un alt tip de placă ESP32 - pentru un modul WROOM, de exemplu - trebuie să folosiți ''./tools/configure.sh esp32-devkitc:nsh''. De asemenea, deoarece plăcile Sparrow sunt construite peste modulul WROVER, puteți să folosiți și ''./tools/configure.sh esp32-wrover-kit:nsh''. Însă în acest caz va trebui să configurați manual NuttX-ul prin ''make menuconfig'' astfel încât să aveți acces la componentele hardware adăugate pe Sparrow. | ||
- | |||
- | Încărcarea binarului pe placă se poate face și prin ''esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 write_flash 0x1000 ../esp-bins/bootloader-esp32.bin 0x8000 ../esp-bins/partition-table-esp32.bin 0x10000 nuttx.bin''. | ||
Dacă nu aveți erori, ar trebui să vă apară un log asemănător cu cel de mai jos: | Dacă nu aveți erori, ar trebui să vă apară un log asemănător cu cel de mai jos: | ||
- | {{ :si:laboratoare:nuttx_flash_log.png?750 |}} | + | {{ :si:iot2025:nuttx_esp32s3_flash_log.png?750 |}} |
- | În final, ar trebui să obțineți și un log de boot asemănător cu cel din screenshot-ul atașat: | + | În final, odată ce vă conectați la ceas, ar trebui să obțineți un log precum cel de mai jos: |
- | {{ :si:laboratoare:nuttx_boot_log.png?600 }} | + | {{ :si:iot2025:nuttx_esp32s3_picocom.png?600 }} |
===== Exerciții ===== | ===== Exerciții ===== | ||
Line 165: | Line 155: | ||
</note> | </note> | ||
- | **2.** Asemănător exercițiului anterior, compilați și încărcați aplicația "rgbled". | + | **2. (Bonus)** Compilați NuttX pentru plăcile Sparrow folosind config-ul ''esp32-sparrow-kit:nsh'' și nu uitați să ștergeți mai întâi config-ul deja existent pentru hacktorwatch. |
<note tip> | <note tip> | ||
- | E nevoie de activarea config-ului ''CONFIG_EXAMPLES_RGBLED''. Pentru a putea vedea cum NuttX compilează selectiv, doar pe baza config-urilor activate, vă puteți uita in fișierele ''Kconfig''. | + | In NuttX, există două operații de clean-up, spre deosebire de Makefile-urile clasice care oferă o singură operație: |
+ | * ''make clean'' - șterge doar fișierele obiect compilate | ||
+ | * ''make distclean'' - șterge orice fișier asociat cu config-ul actual pentru a putea reinițializa sistemul de build de la zero. | ||
</note> | </note> | ||
- | |||
- | <note important> | ||
- | Dacă rulați pe plăcuțele verzi, trebuie să schimbați pinii LED-ului: | ||
- | * CONFIG_ESP32_LEDC_CHANNEL0_PIN=25 | ||
- | * CONFIG_ESP32_LEDC_CHANNEL1_PIN=26 | ||
- | * CONFIG_ESP32_LEDC_CHANNEL2_PIN=27 | ||
- | </note> | ||
- | |||
- | **3. Bonus - ** faceți led-ul să clipească o dată pe secundă in roșu, verde, albastru. | ||
===== Resurse ===== | ===== Resurse ===== | ||
Line 184: | Line 167: | ||
* [[https://en.wikipedia.org/wiki/Cross_compiler| What is a cross-compiler?]] | * [[https://en.wikipedia.org/wiki/Cross_compiler| What is a cross-compiler?]] | ||
* [[https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-tools.html| ESP32 toolchain]] | * [[https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-tools.html| ESP32 toolchain]] | ||
- | * [[https://www.environmentallights.com/library/pwm| PWM and LEDs]] | + | * [[https://developer.espressif.com/blog/nuttx-adding-porting-an-app/| Building Applications on NuttX]] |