Bine ați venit în laboratorul de Sisteme Încorporate!
În cadrul acestui laborator, ne propunem să vă familiarizăm cu sisteme de operare RTOS (Real-Time Operating System) - în speță 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 Hacktor Watch, dezvoltat în facultate și bazat pe un microprocesor ESP32 S3 la care au fost adăugate:
Mai jos puteți vedea diagrama hardware a ceasului:
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.
Dacă rulați pe un sistem cu Linux nativ, continuați de la pasul Compilarea și încărcarea pe placă.
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ă.
Puteți descărca VM-ul pentru Sisteme Incorporate de aici pe GitHub.
Pentru a instala mașina virtuală, este recomandat să descărcați VMware Workstation 17 Pro, deoarece este singura soluție de virtualizare pe Windows cu funcționalitate de USB Passthrough funcțională pentru embedded development (din păcate, VirtualBox are multe buguri pe acest punct).
Instalați pachetele necesare, asigurați-vă că aveți Homebrew în sistem.
pip install esptool brew update brew install x86_64-elf-gcc u-boot-tools bash picocom
Clonați repo-ul și instalați Kconfig-frontends compatibile cu MacOS:
git clone https://bitbucket.org/nuttx/tools.git cd tools/kconfig-frontends patch < ../kconfig-macos.diff -p 1 ./configure --enable-mconf --disable-shared --enable-static --disable-gconf --disable-qconf --disable-nconf make make install
Descărcați crosscompiler-ul pentru MacOS și adăgați-l în PATH. Eventual faceți această setare permanentă prin adăugarea în ~/.bashrc sau ~/.zshrc (nu uitați de source
ulterior - pașii sunt similari cu instrucțiunile de Linux).
export PATH=$PATH:/path/to/xtensa-esp-elf/bin
Continuați cu Descărcarea repository-urilor. Urmăriți setul de instrucțiuni specifice MacOS.
Pașii de mai jos trebuie urmați ca utilizator privilegiat (root):
Dacă doriți să continuați ca utilizator neprivilegiat, puteți consulta tutorialul de aici.
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 pip install esptool pyserial
pipx upgrade esptool pipx install --force esptool echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc source ~/.bashrc
Atenție: pe mașina virtuală, aveți toolchain-ul deja descărcat și adăugat în PATH (vedeți în /opt/xtensa
).
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
git clone --recurse-submodules https://github.com/radupascale/hectorwatch-nuttx cd hectorwatch-nuttx
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.
Pentru a configura și compila NuttX, folosiți următoarea secvență de comenzi:
cd ~/hectorwatch-nuttx/nuttx ./tools/configure.sh -l hacktorwatch:usbnsh make -j$(nproc)
./tools/configure.sh -m hacktorwatch:usbnsh make -j$(sysctl -n hw.ncpu) make flash ESPTOOL_PORT=/dev/cu.usbmodem01 ESPTOOL_BAUD=115200 ESPTOOL_BINDIR=../esp32s3-bins sudo picocom -b 115200 /dev/cu.usbmodem01
Observați flag-ul ”-m” și denumirea diferită a portului usb. Verificați cu ls /dev/cu.*
specific ce port aveți (01 sau 2101 etc.).
În funcție 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:
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
. Apăsați Enter
de 3 ori pentru a debloca (,) consola NSH!
Î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:
În final, odată ce vă conectați la ceas, ar trebui să obțineți un log precum cel de mai jos:
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ă.
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.?
pentru a vedea cum se poate rula aplicația.
2 (Bonus). Folosind make menuconfig
, dezactivați aplicația “Hello, World!” pe care ați activat-o la Exercițiul 1. Recompilați și reîncărcați sistemul de operare. Verificați dacă aplicația mai este disponibilă în linia de comandă a NuttX. Acum ștergeți fișierele de configurare și compilare folosind make distclean
. Apoi, reinițializați sistemul de build pentru placa Hacktor Watch și recompilați. Observați diferența dintre make clean
și make distclean
(așa cum este menționat în nota tip).
make clean
- șterge doar fișierele obiect compilatemake distclean
- șterge orice fișier asociat cu config-ul actual pentru a putea reinițializa sistemul de build de la zero.