This shows you the differences between two versions of the page.
si:iot2025:lab01 [2025/07/12 18:09] robert_ionut.alexa created |
si:iot2025:lab01 [2025/08/11 12:50] (current) dan.tudose |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Lab 01 ===== | + | ===== Laboratorul 01. NuttX - Configurare și instalare ===== |
+ | |||
+ | Bine ați venit la școala de vară IoT Summer School! | ||
+ | |||
+ | Î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/Hacktor-Watch-2.0/|Hacktor Watch]], dezvoltat în facultate și bazat pe un microprocesor **ESP32 S3** la care au fost adăugate: | ||
+ | * doua butoane externe | ||
+ | * un display cu touch | ||
+ | * un senzor de haptics | ||
+ | * un accelerometru si giroscop | ||
+ | |||
+ | Mai jos puteți vedea diagrama hardware a ceasului: | ||
+ | |||
+ | {{ :si:iot2025:hacktor_watch_2.0.jpg?600 }} | ||
+ | |||
+ | 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 ===== | ||
+ | |||
+ | ==== Linux ==== | ||
+ | |||
+ | Dacă rulați pe un sistem cu Linux nativ, continuați de la pasul [[lab01#compilarea_si_incarcarea_pe_placa|Compilarea și încărcarea pe placă]]. | ||
+ | |||
+ | ==== Windows ==== | ||
+ | |||
+ | Pentru a putea rula pe Windows, va trebui să vă configurați o mașină virtuală de Linux prin care să aveți acces la porturile USB ale host-ului - astfel conectarea la placă se va face direct prin USB de pe mașina virtuală. Pentru instalarea Linuxului puteți folosi [[https://repository.grid.pub.ro/cs/so/linux-2021/so-ubuntu-20-04.ova|mașina virtuală]] de la SO din anul 3 - este suficient să aveți un sistem Linux minimal, doar din linie de comandă. Alternativ, puteți instala orice altă distribuție de Linux (Ubuntu, Linux Mint, etc.). | ||
+ | |||
+ | Pentru a instala mașina virtuală, este recomandat să folosiți [[https://vmware.pub.ro/|VMware Workstation 16 pro]], deoarece este foarte ușor de configurat. | ||
+ | |||
+ | Dacă nu aveți acces la VMware (nu aveți licență), puteți să folosiți și [[https://www.virtualbox.org/|VirtualBox]], dar cu niște pași în plus pentru a-l configura. | ||
+ | |||
+ | În mod normal, o mașină virtuală prin VirtualBox nu este accesibilă direct de pe host. Totuși, pentru a vă putea conecta la mașina virtuală prin SSH (folosind [[https://mobaxterm.mobatek.net/|MobaXterm]], de exemplu), puteți urmări pașii de mai jos: | ||
+ | * intrați în setările mașinii virtuale și adăugați a 2a interfață de rețea. Prima va fi o interfață host-only pentru a permite conectivitatea de la host la guest (ssh), iar a 2a interfață va fi sub un NAT pentru a putea avea acces la internet. | ||
+ | * porniți mașina virtuală. Testați cu ''ping 8.8.8.8'' că sunteți conectat la Internet. | ||
+ | * adăugați o adresă IP statică pe a 2a interfață folosind subrețeaua ''192.168.56.0/24''. De exemplu, puteți folosi ''192.168.56.56/24''. Alternativ, puteți configura un client de DHCP. | ||
+ | |||
+ | Pentru a putea avea acces la portul USB direct din mașina virtuală, din bara de sus selectați ''Devices'' > ''USB devices'' > ''controller-ul UART''. | ||
+ | |||
+ | Momentan WSL-ul nu are suport nativ pentru interacțiunea cu diferite device-uri peste USB. Dacă doriți să folosiți totusi WSL, puteți folosi acest [[https://learn.microsoft.com/en-us/windows/wsl/connect-usb|tool]] open source. | ||
+ | |||
+ | ==== MacOS ==== | ||
+ | |||
+ | 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ă ===== | ||
+ | |||
+ | Pașii de mai jos trebuie urmați ca utilizator privilegiat (root): | ||
+ | * instalarea pachetelor (dependințelor) pe Linux | ||
+ | * 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 | ||
+ | * compilarea în urma căreia va rezulta un binar | ||
+ | * încărcarea binarului pe placă | ||
+ | |||
+ | Dacă doriți să continuați ca utilizator neprivilegiat, puteți consulta tutorialul de [[https://blog.espressif.com/getting-started-with-esp32-and-nuttx-fd3e1a3d182c|aici]]. | ||
+ | |||
+ | ==== Instalarea pachetelor lipsă ==== | ||
+ | |||
+ | <code> | ||
+ | apt-get update | ||
+ | # apt-get upgrade -y /* optional, realizeaza actualizarea intregului sistem */ | ||
+ | apt-get install -y bison flex gettext texinfo libncurses5-dev libncursesw5-dev gperf automake libtool pkg-config build-essential gperf genromfs libgmp-dev libmpc-dev libmpfr-dev libisl-dev binutils-dev libelf-dev libexpat-dev gcc-multilib g++-multilib picocom u-boot-tools util-linux chrony libusb-dev libusb-1.0.0-dev kconfig-frontends python3-pip | ||
+ | </code> | ||
+ | |||
+ | ==== Descărcarea toolchain-ului ==== | ||
+ | |||
+ | <code> | ||
+ | wget https://github.com/espressif/crosstool-NG/releases/download/esp-12.2.0_20230208/xtensa-esp32s3-elf-12.2.0_20230208-x86_64-linux-gnu.tar.xz | ||
+ | tar -xf xtensa-esp32s3-elf-12.2.0_20230208-x86_64-linux-gnu.tar.xz | ||
+ | mkdir /opt/xtensa | ||
+ | mv xtensa-esp32s3-elf/ /opt/xtensa/ | ||
+ | echo "export PATH=\$PATH:/opt/xtensa/xtensa-esp32s3-elf/bin" >> ~/.bashrc | ||
+ | source ~/.bashrc | ||
+ | </code> | ||
+ | |||
+ | ==== Descărcarea repository-urilor ==== | ||
+ | |||
+ | <code> | ||
+ | git clone git@github.com:radupascale/hectorwatch-nuttx.git | ||
+ | cd hectorwatch-nuttx | ||
+ | git submodule init | ||
+ | git submodule update | ||
+ | </code> | ||
+ | |||
+ | <note tip> | ||
+ | NuttX folosește două directoare separate: | ||
+ | * nuttx, care conține sistemul de operare: scheduler, drivere, sisteme de fișiere, etc. | ||
+ | * 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. | ||
+ | |||
+ | Repository-ul hectorwatch-nuttx conține nuttx și apps ca submodule care trebuie inițializate (descărcate) separat. | ||
+ | </note> | ||
+ | |||
+ | <note important> | ||
+ | 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> | ||
+ | wget https://github.com/espressif/esp-nuttx-bootloader/releases/download/latest/bootloader-esp32s3.bin | ||
+ | wget https://github.com/espressif/esp-nuttx-bootloader/releases/download/latest/partition-table-esp32s3.bin | ||
+ | </code> | ||
+ | |||
+ | Cu toate acestea, Hectorwatch-nuttx conține deja binarele precompilate in **esp32s3-bins**. | ||
+ | </note> | ||
+ | |||
+ | ==== Compilarea și rularea ==== | ||
+ | |||
+ | Pentru a configura si compila NuttX, folosiți următoarea secvență de comenzi: | ||
+ | |||
+ | <code> | ||
+ | cd ~/hectorwatch-nuttx/nuttx | ||
+ | ./tools/configure.sh -l hacktorwatch:usbnsh | ||
+ | make -j$(nproc) | ||
+ | </code> | ||
+ | |||
+ | Î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: | ||
+ | |||
+ | {{ :si:iot2025:hacktor_buttons.jpg?300 }} | ||
+ | |||
+ | 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''. | ||
+ | |||
+ | 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". | ||
+ | |||
+ | Pentru a vă conecta la placă veți folosi ''picocom /dev/ttyACM0 -b 115200''. | ||
+ | |||
+ | <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> | ||
+ | |||
+ | Observați flag-ul "-m" și denumirea diferită a portului usb. | ||
+ | </note> | ||
+ | |||
+ | Î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ă nu aveți erori, ar trebui să vă apară un log asemănător cu cel de mai jos: | ||
+ | |||
+ | {{ :si:iot2025:nuttx_esp32s3_flash_log.png?750 |}} | ||
+ | |||
+ | În final, odată ce vă conectați la ceas, ar trebui să obțineți un log precum cel de mai jos: | ||
+ | |||
+ | {{ :si:iot2025:nuttx_esp32s3_picocom.png?600 }} | ||
+ | |||
+ | ===== Exerciții ===== | ||
+ | |||
+ | **1.** Folosind sistemul de build al NuttX, activați compilarea aplicației "Hello, World!". Codul sursă îl puteți găsi în ''apps/examples/hello''. Odată încărcat pe placă, rulați aplicația din linie de comandă. | ||
+ | |||
+ | <note tip> | ||
+ | * pentru a putea compila "Hello, World!" trebuie să activați config-ul ''CONFIG_EXAMPLES_HELLO'' folosind ''make menuconfig''. Căutarea unui anume config se poate face la fel ca in VIM, folosind ''/'' urmat de string-ul dorit. | ||
+ | * odată compilat și încărcat NuttX, utilizați comanda ''?'' pentru a vedea cum se poate rula aplicația. | ||
+ | </note> | ||
+ | |||
+ | **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> | ||
+ | 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> | ||
+ | |||
+ | ===== Resurse ===== | ||
+ | * [[https://nuttx.apache.org/docs/latest/|Documentatia oficiala NuttX]] | ||
+ | * [[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://developer.espressif.com/blog/nuttx-adding-porting-an-app/| Building Applications on NuttX]] |