Tema 2 - Weather Monitoring System (2023)

  • Publicare:
    • 15 Decembrie 2023
  • Termen de predare:
    • 16 Ianuarie 2024 23:55 - deadline HARD

Obiective:

  • construirea unei distribuții Linux minimaliste;
  • configurări de bază Linux;
  • servicii de sistem Linux;
  • dezvoltare aplicații IoT;
  • utilizare interfață serială (UART & TTY) pe Linux;
  • optimizări de spațiu;

Pentru a rezolva tema, este recomandat să folosiți mașina virtuală SI 2023 cu toate uneltele necesare gata instalate!

Enunț

Dorim să realizăm o aplicație IoT care primește date de la câțiva senzori meteo (temperatură, umiditate, ploaie – senzorii vor fi emulați) și afișează datele într-o interfață web ce rulează pe un Raspberry PI (de asemenea, emulat folosind qemu).

Ca și cerință principală, va trebui să realizați o imagine incorporabilă cu Linux ce va expune pe rețea un server HTTP cu o pagină web de vizualizare a senzorilor + un serviciu de achiziție a datelor de la senzori printr-o interfață UART (aveți formatul descris mai jos).

Exemplu de frontend web (însă aspectul nu contează):

Cerințe

Imaginea Linux de bază:

Pas inițial: realizarea unei imagini de bază de Linux (kernel + rootfs) ce va fi folosită ca punct de plecare / suport pentru programele & serviciile cerute de restul cerințelor:

  • Imaginea trebuie construită din componente de la zero: kernel compilat + rootfs;
  • Rootfs-ul să ocupe cât mai puțin posibil (vedeți mai jos punctajele); se poate folosi orice distribuție & abordare de generat rootfs (atât printre cele studiate la laborator, cât și celelalte populare în industrie):
    • Buildroot – recomandat, puteți obține cele mai reduse dimensiuni!
    • Debian, prin qemu + debootstrap – nerecomandat (se vor obține dimensiuni destul de mari, 500MB ~ 1GB) și vor fi depunctate (-10p);
    • Alpine Linux bootstrapuit folosind apk.static – procedură similară cu debootstrap, însă se vor obține imagini mult mai mici (recomandat, însă va trebui să vă documentați bine înainte)!
    • Yocto Linux - pentru experți ;)
    • NU se acceptă: rootfs gata construit / descărcabil (e.g., arhivă cu favorite distro de pe site-ul oficial sau third-party);
  • Kernel compilat de voi cu LOCALVERSION="-tema2" (altfel se depunctează! vedeți mai jos);
  • Sistemul (rootfs + kernel) să fie compilat pe AArch64 (i.e.: arm64) și să poată fi rulat în qemu folosind machine type raspi3b (vedeți mai jos config-uri de kernel testate deja pentru compatibilitate + script de rulare recomandat);
  • Imaginea trebuie împachetată într-un fișier disk SD (a cărui dimensiune trebuie să fie o putere a lui 2, cum găsiți precizat prin tutoriale) – alegeți, însă, o dimensiune cât mai mică posibil (e.g., dacă imaginea voastră ocupă 70MB, creați disk SD de 128MB).

Sistemul trebuie să conțină următoarele configurații de bază (ne ajută pe noi, în special, să automatizăm partea de testare):

  • utilizator root cu parola tema2 (obligatoriu: să ne putem autentifica în consola emulată);
  • hostname-ul tema2;
  • să-și preia automat IP-ul folosind DHCP pe prima interfață disponibilă (recomandat: folosiți la rulare parametrul de kernel net.ifnames=0, astfel încât numele primei interfețe să fie eth0 pentru o configurație portabilă);
  • să ruleze SSH pe portul 22 (la fel, să fie activată autentificarea cu root + parolă!);
  • să ruleze Avahi mDNS daemon și să răspundă la numele tema2.local (opțional, dar ne ajută la testare; setupul pe host se face mai dificil, însă pe mașina emulată, însă este suficient să fie compilat/instalat pachetul avahi-daemon - sau echivalentul în distribuția aleasă - și testa cu ping tema2.local).

Rezolvarea acestei cerințe este OBLIGATORIE pentru obținerea oricărui fel de punctaj (altfel nu avem ce testa ⇒ 0p)!

Inb4: veți avea de customizat rootfs-ul. După cum va trebui să separați fișierele / codul / scripturile sursă de imaginea binară obținută ca rezultat al procesului de build (care poate fi semi-manual sau complet automatizat – ce preferați), recomandăm organizarea unui overlay – subdirector al temei unde includeți DOAR fișierele de configurație / surse ce doriți să apară în imaginea finală ce le vor suprascrie pe cele implicite.

Pentru rootfs-ul construite prin tehnică de package-based bootstrapping, puteți copia ulterior acest overlay folosind cp -ar sau rsync -a.

Pentru BuildRoot, citiți recomandările oficiale de customizare.

+ citiți enunțul până la capăt pentru a vedea cerințele finale!

Compilare Kernel

Un prim avertisment: din păcate, kernel-urile descărcate de pe repository-ul raspberrypi/linux NU SUNT COMPATIBILE CU qemu! Deci a nu se folosi!

Recomandăm folosirea kernelului mainline, descărcabil de pe https://kernel.org/ (sau Github, torvalds/linux). NU LUAȚI MASTER-ul sau alte branch-uri experimentale! Folosiți un branch de versiune (e.g., v6.1).

Au fost testate versiunile v6.1 și v6.6, compilate atât automat prin buildroot, cât și manual (descărcat branch de pe git și make cu CROSS_COMPILE). NU uitați ARCH=arm64 și configurația inițială a arhitecturii, defconfig (pe mainline NU există bcm27*_defconfig)!

Pentru a nu avea probleme cu driverele externe (e.g.: mmc, să nu vadă rootfs-ul, sau să nu se încarce automat driverul de rețea usb-net), recomandăm dezactivarea modulelor de kernel, adică MODULES=n din menuconfig – acest lucru va face integrarea tuturor driverelor în imaginea de kernel și va omite copierea modulelor pe sistemul rădăcină (în /lib/modules). Pentru cei care folosesc buildroot, aveți make linux-menuconfig.

La configurarea kernelului, va trebui să setați parametrul LOCALVERSION la valoarea -tema2 (sau ceva derivat, puteți să vă puneți și numele ;). Vedeți aici variabilele implicate, TLDR: nu uitați să dezactivați LOCALVERSION_AUTO pentru a putea modifica!

Deși e prezent în defconfig (în caz că vreți să optimizați), nu uitați să includeți driver-ul pentru dispozitivul serial ce emulează senzorii, model FTDI FT232H.

În final, la rularea prin qemu, trebuie să folosiți device tree-ul care începe cu bcm2837-, deoarece rulați kernel-ul mainline. Vedeți explicația aici sau aici. DTB-ul îl puteți compila voi (din kernel: make dtbs, sau, la buildroot, aveți setare în meniu) sau prelua din altă parte (cât timp funcționează).

Dacă aveți probleme cu kernelul și/sau nu rulează corect în qemu, atunci puteți omite / include un kernel pre-compilat, însă cu depunctare (-10p). Însă va trebuin să scrieți în README ce ați încercat și ce rezultate ați avut!

HTTP Server / Web UI:

Dorim ca sistemul să expună un server HTTP pe portul 80 o interfață web minimalistă care să prezinte datele de la senzorii primiți prin UART:

  • Sistemul va trebui să ruleze un server http ce va asculta după cereri HTTP (pe portul 80) pentru controlul luminilor (definite mai jos);
  • Puteți folosi orice limbaj de programare / scripting / framework pentru a construi acest endpoint; exemple:
    • Python: http.server / flask / Django / etc.;
    • NodeJS: http / ExpressJS / other 1000s of libraries;
    • PHP (+ Apache / Nginx / Lighttpd etc.): cu sau fără framework;
    • Golang: net/http (bonus: dimensiuni mici ale aplicațiilor!);
    • Rust: http (built in libraries + dimensiuni ff. mici, la fel ca la GoLang!);
    • C/C++ (for hardcore developers): Facil / Oat++ / etc. – performanță++ && dimensiuni%–% ;)
  • Atenție: Dacă alegeți să compilați rootfs prin Buildroot, veți avea de scris/făcut rost de scripturi de compilare + împachetare atât pentru codul vostru + toate dependințele necesare (e.g., la Python PIP / VirtualEnv, pachete npm pentru NodeJS etc.)! Se poate, desigur, face cross compiling, însă trebuie folosit compilatorul de la Buildroot (same thing for Yocto)!

Serverul trebuie să pornească automat la boot (ca daemon). Majoritatea distribuțiilor folosesc systemd ca init și manager de servicii, deci va trebui să creați un astfel de descriptor pentru aplicația web.

În BuildRoot și Yocto aveți mai multe opțiuni de init system-uri, la alegere: Busybox (cel mai light dintre toate, se scriu scripturi sh), SysVInit (aka rc.d/runlevels) sau SystemD (mai popular și bine documentat, însă trebuie compilat și poate adăuga ~1-2h în plus la timpul de compilare, depinde de puterea de calcul a sistemului).

Pentru BuildRoot, dacă folosiți un interpretor / limbaj care necesită dependințe externe, citiți secțiunea Adding Packages. Pentru Python aveți incluse deja o mulțime de biblioteci populare. Pentru Golang, citiți secțiunea Infrastructure for Go packages a manualului. În general, pentru cei care doresc să folosească un limbaj compilat, este util ghidul general de generare a pachetelor compilate pentru build system-ul preferat.

Datele de la senzori le veți prelua de la un alt serviciu, descris în subsecțiune următoare. Dacă nu rezolvați acest task, puteți să prezentați pur și simplu câteva date de test în interfața Web.

Sensor data acquisition daemon:

Pe lângă serviciul web, va trebui să dezvoltați un daemon de achiziție a datelor de pe un dispozitiv serial (emulat prin QEmu ca usb-serial model FTDI FT232H, vizibil în guest Linux ca /dev/ttyUSB0);

  • Programul va rula într-o buclă de citire de la dispozitiv, parsare și trimitere date către .
  • La fel ca la serviciul web, puteți folosi orice limbaj / biblioteci de conectare pe dispozitivul serial (chiar și bash :D ):
  • Puteți face comunicarea între cele 2 procese (de la daemonul de achiziție date seriale la server HTTP) prin orice mecanism vă pune Linux / limbajul la dispoziție (unix pipes, sockeți, RPC framework al limbajului, chiar și sistem de fișiere pentru o implementare rudimentară);
  • Acest program trebuie OBLIGATORIU să se numească iotsensord și să pornească automat cu sistemul!

<hint> Fiind serială emulată, baud rate-ul configurat nu contează! (merge aproape orice e standard).

Instalați picocom în imagine pentru depanare facilă!</hint>

Format date seriale

Dispozitivul serial emulat va trimite informații codificate în text (ASCII), câte o linie per senzor, un mesaj fiind terminat printr-un caracter simplu LF (\n).

Formatul folosit va fi similar CSV-ului, însă câmpurile vor fi separate prin caracterul ;, având sintaxa generală:

TIMESTAMP; LOCATION; SENSOR_NAME; SENSOR_VALUE; FLAGS (optional)

Unde:

  • TIMESTAMP este o valoare intreagă, Unix Timestamp, exprimată în secunde de la Unix Epoch (01.01.1970 00:00);
  • LOCATION va reprezenta locația senzorului și va avea următoarele valori: ext – exterior (i.e., afară), int interior (i.e., în casă);
  • SENSOR_NAME: este denumirea senzorului; vor fi definiți senzorii: humidity (relative humidity, procentaj), temp (temperatură, în grade Celsius) și rain (boolean, 0 / 1);
  • SENSOR_VALUE: valoarea senzorului; număr întreg, de obicei, însă la valorile de temperatură pot apărea și cu virgulă mobilă (e.g., 23.5); nu apare nicio unitate de măsură, acestea fiind implicit cele de mai sus;
  • FLAGS: câmp opțional (poate să lipsească), poate avea valoarea ERROR pentru a alerta (din interfața web) faptul că a apărut o eroare la senzorul fizic și datele nu sunt valide (se va citi valoarea 0 la câmpul VALUE).

Pentru testare, veți porni manual script-ul ce generează astfel de date în paralel cu qemu!

Este recomandat să faceți parsarea liniilor tolarabilă la erori (e.g., să nu crape daemon-ul când primesc un fragment parțial al unui senzor, doar să îl ignore), altfel riscați să fiți depunctați dacă se ajunge la vreun race condition!

Instrucțiuni pentru rularea imaginii folosind QEmu

Ca și punct de pornire, puteți descărca un schelet inițial cu scripturi + structură recomandată (v0.1). Aceasta conține:

  • Makefile util pentru construirea arhivelor; obligatoriu să-l studiați + editați, nu face ce trebuie nemodificat!
  • script de testare launch-tema2.sh pe sistemul gazdă (va rula qemu cu fișierele kernel+imagine, vedeți mai jos, la conținutul arhivei, ce denumiri folosește);
  • un script Python sensors-emu.py ce emulează datele de la senzori, integrat cu launch-tema2.sh (comunică printr-un FIFO în /tmp, vedeți cod sursă);

Aceste scripturi au fost testate în VM-ul oficial folosit la laborator. Dacă aveți setup propriu, puteți cere ajutor pe Teams / Forum dacă apar probleme.

Trimitere

Soluția temei va fi trimisă în două moduri (vă rugăm să respectați convențiile de denumire cu exactitate!):

  • arhivă cu codul sursă + Readme + hash și alte metainformații (vedeți mai jos) → pe Moodle
  • arhivă cu binarele / imaginea rulabilă → le urcați pe Sharepoint-ul contului Microsoft de student și dați share prin Link Public (pe care ni-l trimiteți doar nouă în fișierul url.txt).

Arhiva cu binarele (.tar.*z pls; se acceptă gz și xz) trebuie să conțină (obligatoriu: să folosiți strict aceste denumiri de fișiere):

  • tema2.img: imaginea finală (format raw!); poate conține sau nu partiții (dar va trebui să adaptați scriptul de rulare).
  • vmlinuz-tema2: imaginea kernel-ului compatibil cu QEMU;
  • launch-tema2.sh: script de pornire QEMU (vedeți scheletul dat);
  • includeți și scripturile suplimentare necesare pentru rulare (e.g., simulatorul de senzori în Python);
  • NU INCLUDEȚI: cache-ul de build al Buildroot / Yocto (poate avea 6-20 GB!), DOAR artefactele finale!
  • Această arhivă nu ar trebui să depășească 500MB (folosiți tar.xz pentru rată de compresie bună).

Arhiva cu fișierele sursă (.zip pls) OBLIGATORIU să conțină:

  • sursele aplicației (în orice limbaje ați ales), scripturi custom folosite pentru build și/sau overlay-ul copiat pe rootfs (orice ați inclus extra peste sistemul de bază – de preferat, organizat într-o structură Unix-like: ./etc/, ./usr/bin, ./opt/* etc.); NU COPIAȚI ROOTFS-UL GENERAT!
  • fișierele de configurație (.config) ale kernel și/sau buildroot – obligatoriu dacă unde e cazul! folosiți numele kernel_config și buildroot_config în arhiva cu sursele (în niciun caz nu le lăsați hidden!);
  • fișier README.txt cu explicații referitoare la modul de construire al imaginii, arhitectura soluției, configurații speciale de optimizare folosite etc.
  • fișier url.txt cu URL către arhiva .tar.*z a binarelor PE Sharepoint!;
  • fișier checksum.txt care să conțină hash-ul SHA256 al arhivei cu binarele (obținut cu sha256sum); ATENȚIE: verificați și re-verificați (de încă 2 ori) conținutul fișierului la încărcare pe Moodle cu hash-ul real deoarece tema nu va fi punctată dacă diferă!
  • NU INCLUDEȚI: fișiere sursă ale Buildroot / Yocto / biblioteci / frameworkuri / VirtualEnv descărcabile de pe Internet (menționați în Readme ce ați folosit);
  • Hint: pentru a include un fișier la crearea automată a arhivei prin make source_archive, pur și simplu copiați-l pe rădăcină (sau într-un director care nu este ignorat – verificați Makefile-ul din schelet)!
  • Această arhivă nu ar trebui să depășească 1MB (aveți restricție pe Moodle).

Folosiți Makefile-ul din scheletul temei pentru generarea acestor două arhive, însă este recomandată verificarea manuală a arhivelor după generare!

Nu vor fi punctate temele care nu au hash-ul SHA256 al arhivei încărcat pe Moodle sau cele al căror hash nu corespunde cu arhiva downloadată de pe platforma de hosting la momentul corectării (este folosit și pentru a verifica upload / modificări apărute după deadline)!

Notare

Din 100p total, aveți:

  • (30p) Imaginea și funcționalitățile de bază (trebuie să ruleze în qemu!);
    • -10p depunctare pentru imagini rootfs ce depășesc 200MB (disk usage al partiției ext4);
    • -10p depunctare pentru kernel-uri necompilate de voi (sau care nu au LOCALVERSION=”-tema2” sau similare);
    • Notă: chiar și cu depunctare, a avea un sistem funcțional în qemu este obligatoriu pentru a lua restul de puncte acordate pe task-urile următoare!
  • (30p) Serviciul web de prezentare a valorilor de la senzori;
  • (30p) Daemonul care achiziționaează datele pe UART;
  • (10p) Readme scris clar și care descrie procesul urmat, arhitectura și implementarea funcționalităților cerute.

Bonus:

  • (10p) Aspect / funcționalitate deosebită (e.g., grafice în timp ale datelor, implementări tehnice eficiente etc.);
  • (10p) Optimizări deosebite de spațiu ale imaginii finale (cele mai mici 10 imagini primite, însă doar dintre cele care implementează toate task-urile!);

Imaginile care nu au au fost construite personal sau nu rulează deloc (cu excepția unor greșeli minore) nu vor fi punctate!

Precizări

  • Tema are deadline HARD (nu mai sunt admise soluții după expirare), așadar se recomandă să vă apucați din timp de rezolvarea acesteia!
  • :!: ATENȚIE: orice formă de plagiat nu va fi permisă și va duce la depunctare totală / restanță + avertisment oficial la decanat!
  • Pe Moodle găsiți și un forum ;) La fel pe Teams, avem un canal de discuții.

Resurse

si/teme2023/tema2.txt · Last modified: 2024/01/12 18:01 by florin.stancu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0