Differences

This shows you the differences between two versions of the page.

Link to this comparison view

si:teme2022:tema2 [2023/12/10 23:28]
florin.stancu
si:teme2022:tema2 [2023/12/12 12:00] (current)
florin.stancu old revision restored (2023/01/13 22:44)
Line 1: Line 1:
-====== Tema 2 - Home Weather Monitoring System ​======+====== Tema 2 - Christmas LEDs ======
  
-  ​* **Publicare**:​ +* **Publicare**:​ 
-    * **11 Decembrie ​2023**+  * **11 Decembrie ​2022 //17:50//**
  
-  ​* **Termen de predare**:​ +* **Termen de predare**:​ 
-    * <color red>**13 Ianuarie ​2024 23:55** - deadline HARD</​color>​+  * <color red>**15 Ianuarie ​2023 23:55** - deadline HARD</​color>​
  
-<​hidden>​ +* **Changelog:​** 
-  ​* **Changelog:​** +  * //**14 Ianuarie 2023 22:30**// - mărit deadline-ul până duminica ​;) 
-    * //**05 Ianuarie 2023 HH:II**// - TODO+  ​* ​//**13 Ianuarie 2023 11:15**// - corectat numele fișierelor:​ ''​url.txt''​ + ''​checksum.txt''​ (CU extensie). 
-</hidden>+  * //**05 Ianuarie 2023 13:40**// - reparat RESTful endpoints din text să fie ca în scriptul de Python de demo.
  
 <​note>​ <​note>​
 **Obiective**:​ **Obiective**:​
-  * construirea unei distribuții Linux minimaliste;+  * construirea unei distribuții Linux complete, build folosind Yocto; 
 +  * creare layere + pachete Yocto;
   * configurări de bază Linux;   * configurări de bază Linux;
   * servicii de sistem Linux;   * servicii de sistem Linux;
-  * dezvoltare aplicații ​IoT+  * dezvoltare aplicații ​RESTful; 
-  * utilizare ​interfață ​serială (UART & TTY) pe Linux;+  * dezvoltare aplicații Terminal UI
 +  * interfață ​GPIO Linux;
   * optimizări de spațiu;   * optimizări de spațiu;
 </​note>​ </​note>​
  
 <note important>​ <note important>​
-Pentru a rezolva tema, este recomandat să folosiți [[https://​github.com/​cs-pub-ro/​SI-Lab-VM/​releases/​|mașina virtuală ​SI 2023]] cu toate uneltele necesare ​gata instalate!+Pentru a rezolva tema, este recomandat să folosiți [[https://​github.com/​cs-pub-ro/​SI-Lab-VM/​releases/​|mașina virtuală ​Yocto 2022 (~22GB)]] cu distribuția Yocto gata compilată și cache-uită,​ altfel timpul de compilare pe un laptop modest poate fi chiar și de 10 ore! 
 +Puteți lucra în paralel cu laboratorul pe aceiași mașină (veți folosi descriptori de ''​kas''​ (în format ''​yml''​) din fișiere diferite + layere separate).
 </​note>​ </​note>​
- 
-//TODO// 
  
 <ifauth @si> <ifauth @si>
-<color red>CINE VEDE RESTUL ​E ASISTENT ;) </​color>​+<color red>CINE VEDE ASTA E ASISTENT ;) </​color>​ 
 +</​ifauth>​ 
 + 
 +===== Storyline / Enunț =====
  
-===== Enunț =====+A venit Crăciunul! Ca viitori ingineri ai unei facultăți de renume din țară (//​***ahem***//​),​ dorim să impresionăm familia / rudele / pisica / vecinii construind o instalație de pom controlabilă din Internet of Things!
  
-Dorim să realizăm o aplicație IoT care primește date de la țiva senzori meteo (temperatură, umiditate, ploaie ​-- datele vor fi emulate) și îi face disponibili pe o interfață ​web a unui Raspberry PI (de asemeneaemulat în qemu).+Așadar, ne apucăm de treabă: luăm o bandă cu LED-uri și începem prin dezvoltarea unei aplicații care să le poată controla ​de la distanță, printr-o interfață ​RESTful HTTP. 
 +Însă intervine problema: pe ce o rulăm? Ne amintim ce am studiat la cursul și laboratoarele de S.I și ne dăm seama că avem un Raspberry PI mai vechi aruncat într-o cutie, deci mai rămâne doar de construit / configurat o distribuție lightweight de **Linux** ([[https://​www.huffpost.com/​archive/​in/​entry/​bill-gates-best-secret-santa_a_21631414|sorrySanta]]ce se va interfața cu hardware-ul instalației de lumini și va oferi suport pentru rularea aplicației și conectarea la Internet.
  
-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 aplicație web de vizualizare a senzorilor, ce va prelua datele de pe interfață UART (formatul descris ​mai jos).+Ca și cerință principală,​ va trebui să realizați o imagine incorporabilă Linux folosind Yocto ce va expune pe rețea un server HTTP cu API REST-ful (detalii / specificație mai jos) pentru primirea de comenzi de control al LED-urilor
  
-Avețîn imaginea următoare un exemplu de pagină web ce va fi afișată (însă aspectul nu prea contează):+De asemenea, dorim să vedem, în consolă, o simulare grafică (ASCII Art) a bradului de Crăciun cu luminițele aprinse ​în starea actuală
 +Un exemplu de pom luminat poate fi văzut în captura de mai jos (asciinema):
  
-TODO+<​html>​ 
 +<a href="​https://​asciinema.org/​a/​YIEhjwqJlYsYrWdD2nsIn4OX7"​ target="​_blank"><​img style="​max-width:​ 300px;"​ src="​https://​asciinema.org/​a/​YIEhjwqJlYsYrWdD2nsIn4OX7.svg"​ /></​a>​ 
 +</​html>​
  
 ===== Cerințe ===== ===== Cerințe =====
Line 45: Line 53:
 === Imaginea Linux de bază: === === Imaginea Linux de bază: ===
  
-Pas inițialrealizarea unei imagini de bază de Linux (kernel ​+ rootfsce va fi folosită ca punct de plecare / suport pentru programele & serviciile cerute de restul cerințelor:+  * Imaginea sistemului trebuie generată cu Yocto, pornind de la instrucțiunile prezente în [[:si:​laboratoare:​06]];​ 
 +  * Sistemul trebuie să ruleze în QEMU ARM, folosind un kernel ​Yocto pentru machine type ''​qemuarm'';​ 
 +  * Sistemul trebuie să aibă un utilizator ''​root''​ cu parola ''​tema2''​ (obligatoriu!!)
 +  * Sistemul trebuie să aibă hostname-ul ''​tema2'';​ 
 +  * Sistemul trebuie să-și preia automat IP-ul folosind DHCP pe singura interfață disponibilă;​ 
 +  * Sistemul trebuie să ruleze SSH pe portul 22; 
 +  * Sistemul trebuie să ruleze daemon-ul Avahi/mDNS și să răspundă la numele ''​tema2.local''​.
  
-  * Imaginea trebuie construită din componente de la zerokernel compilat + generat rootfs; +=== RESTful HTTP endpoint===
-  * **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):​ +
-    * [[https://​buildroot.org/​|Buildroot]] -- recomandat, puteți obține cele mai reduse dimensiuni! +
-    * [[https://​www.debian.org/​|Debian]],​ prin [[https://​ocw.cs.pub.ro/​courses/​si/​laboratoare/​08|qemu + debootstrap]] -- nerecomandat (se vor obține dimensiuni destul de mari, ''​500MB ~ 1GB''​) și nu vor fi ușor depunctate (10%); +
-    * [[https://​alpinelinux.org/​|Alpine Linux]] bootstrapuit folosind [[https://​wiki.alpinelinux.org/​wiki/​Bootstrapping_Alpine_Linux|apk.static]] -- procedură similară cu ''​debootstrap'',​ însă se vor obține imagini mult mai mici (recomandat,​ însă va trebui [[https://​github.com/​alpinelinux/​alpine-chroot-install|să vă documentați]] bine înainte)! +
-    * [[https://​www.yoctoproject.org/​|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);​ +
-  * 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 [[https://​interrupt.memfault.com/​blog/​emulating-raspberry-pi-in-qemu#​running-qemu|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 imaginea 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):+  * 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**: [[https://​flask.palletsprojects.com|flask]] / [[https://​docs.cherrypy.dev|CherryPy]] / [[https://​fastapi.tiangolo.com/​|FastAPI]] (pick any); 
 +      * **NodeJS**: [[https://​expressjs.com/​|ExpressJS]] / [[https://​loopback.io/​|Loopback]] / other 1000s of libraries;​ 
 +      * **PHP** (//+ Apache / Nginx / Lighttpd etc.//): well... cam e făcut pentru așa ceva, dar va trebui să configurați URL rewriting pe serverul http :P ; 
 +      * **Golang**: [[https://​pkg.go.dev/​net/​http|net/​http]] ​(aici nu se justifică să descărcați altceva)
 +      * **Rust**[[https://​docs.rs/​http/​latest/​http/​|http]] (built in, baby!); 
 +      * **C (for hardcore developers)**:​ [[https://​facil.io/​|Facil]] / [[https://​github.com/​babelouest/​ulfius|Ulfius]] 
 +  * **//​Hint://​** alegeți ori ceva ce doriți să învățați sau pe cel cu care sunteți familiar și căutați-i layer / pachet pentru Yocto ;)
  
-  * utilizator ''​root''​ cu parola ''​tema2''​ (obligatoriu: ​să ne putem autentifica în consola emulată)+<​note>​ 
-  * hostname-ul ''​tema2'';​ +Serverul trebuie ​să pornească automat la boot (ca daemon). În Yocto [[https://​docs.yoctoproject.org/​dev-manual/​common-tasks.html#​enabling-system-services|aveți două opțiuni de bază]]: **SysVInit** ​(aka ''​rc.d''​/''​runlevels'', ​instalat implicit -- nu trebuie ​să mai compilați nimic) și **SystemD** ​(mai ușor de definit serviciile, însă ​trebuie ​compilat și poate dura //~1h//, depinde de puterea de calcul a sistemului). 
-  * 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ă);​ +</​note>​
-  * 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''​)!+=== Terminal UI program: ===
  
-<note warning>​ +  * Pe lângă serviciul web, va trebui să dezvoltați un program (numit ''​christmas-tree''​) rulabil ca ''​root''​ care să afișeze la stdout un ASCII ART (pe consolă, folosind [[https://chrisyeh96.github.io/​2020/​03/​28/​terminal-colors.html|secvențe escape ANSI]]); 
-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țDOAR fișierele de configurație ​surse ce doriți să apară în imaginea finală ​ce le vor suprascrie pe cele implicite.+  * Programul va afișa, în mod dinamic (actualizare timp real, cu latența de preferat de ordinul secundelor),​ un pom de Crăciun frumos luminat / colorat după ultima stare configurată prin API-ul RESTful (serverul HTTP). 
 +  * La fel ca la serviciul web, puteți folosi orice limbaj + biblioteci ​de desenare pe consolă doriți, exemple: 
 +    * **Python**: [[https://​docs.python.org/​3/​howto/​curses.html|curses ​(built-in)]] / [[https://​github.com/​Textualize/​rich|Rich]] / [[https://​pypi.org/​project/​urwid/​|urwid]];​ 
 +    * **NodeJS**: [[https://​github.com/​chjj/​blessed|blessed]] / [[https://​github.com/​cronvel/​terminal-kit|Terminal Kit]]; 
 +    * **PHP**: [[https://​climate.thephpleague.com/​|Climate]];​ 
 +    * **Golang**: [[https://​github.com/​gdamore/​tcell|TCell]] / [[https://​github.com/​rthornton128/​goncurses|goncurses]];​ 
 +    * **Rust**: [[https://​github.com/​jeaye/​ncurses-rs|ncurses-rs]] / [[https://​github.com/​gyscos/​cursive|cursive]];​ 
 +    * **C**: [[https://​invisible-island.net/​ncurses/​|ncurses (the OG)]]; 
 +  * Puteți face comunicarea între cele 2 procese (program TUI + server HTTPprin orice mecanism vă pune Linux / limbajul la dispoziție (unix pipessockeți, RPC framework al limbajului, sistem de fișiere -- însă aici veți avea de furcă la notificarea schimbărilor :P); 
 +  ​Acest program trebuie ​**OBLIGATORIU** să se numească ''​christmas-tree''​ șsă fie în ''​PATH''​ (rulabil direct prin acest nume într-un terminal)! Acesta va fi pornit automat, prin ''​ssh'',​ pentru testare facilă! 
 +  * Cât despre design-ul pomului ​elementelor afișate, aveți libertate deplină (cât timp se înțelege ​ce este și luminițele au culori :D);
  
-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 [[https://​buildroot.org/​downloads/​manual/​manual.html#​rootfs-custom|recomandările oficiale de customizare]].+=== Bonus taskGPIO ===
  
-+ citiți enunțul până la capăt pentru a vedea cerințele finale! +Dorim să trimitem comenzile primite de serverul HTTP către instalația hardware de leduri. ​ 
-</​note>​+Astfel:
  
-=== HTTP Server ​Web UI===+  * Mașina de qemu dispune de un [[https://​www.qemu.org/​docs/​master/​system/​arm/​virt.html?​highlight=pl061|controller de GPIO PL061]] pe care îl vom folosi să simulăm această interacțiune. 
 +  * Pe partea de Linux, aveți API de [[https://​blog.lxsang.me/​post/​id/​33|userspace pentru dispozitivele GPIO]] bazat pe sistemul de fișiere virtual ''/​sys''​ (API vechi) sau ''/​dev''​ + eventual, puteți găsi biblioteci în limbajul ales; 
 +  * Va trebui, însă, să [[https://​docs.yoctoproject.org/​kernel-dev/​common.html|re-configurați kernelul Yocto]] și să activați driverul [[https://​www.kernelconfig.io/​config_gpio_pl061|PL061]] al dispozitivului GPIO emulat de qemu; 
 +  * Puteți folosi orice mapare grup / led la pini GPIO doriți, singura cerință este ca, la schimbarea stării (sau culorilor) acestora, și GPIO-urile asociate să-și modifice starea aferentă!
  
-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 80pentru controlul luminilor (definite mai jos); +=== Contract ​(API===
-  * Puteți folosi orice limbaj de programare / scripting / framework pentru a construi acest endpoint; exemple: +
-      * **Python**: [[https://​docs.python.org/​3/​library/​http.server.html|http.server]] / [[https://​flask.palletsprojects.com|flask]] / [[https://​djangoproject.com/​|Django]] / etc.; +
-      * **NodeJS**: [[https://​nodejs.org/​api/​http.html|http]] / [[https://​expressjs.com/​|ExpressJS]] / other 1000s of libraries;​ +
-      * **PHP** (//+ Apache / Nginx / Lighttpd etc.//): cu sau fără framework (recomandat);​ +
-      * **Golang**: [[https://​pkg.go.dev/​net/​http|net/​http]] (bonus: dimensiuni mici ale aplicațiilor!);​ +
-      * **Rust**: [[https://​docs.rs/​http/​latest/​http/​|http]] (built in libraries + dimensiuni ff. mici, la fel ca la GoLang!); +
-      * **C/C++ (for hardcore developers)**:​ [[https://​facil.io/​|Facil]] / [[https://​github.com/​oatpp/​oatpp|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)!+
  
-<​note>​ +Sistemul va reprezenta un pom de Crăciun cu o serie de //luminițe// organizate în ''​NG'' ​//grupuri// de câte ''​1..n'' ​LED-uri fiecare (fiecare grup poate conține număr diferit de luminițe). 
-Serverul trebuie să pornească automat la boot (ca daemon). Majoritatea distribuțiilor folosesc [[https://www.digitalocean.com/community/tutorials/systemd-essentials-working-with-services-units-and-the-journal|systemd]] ca ''​init''​ și manager ​de serviciideci va trebui ​să creați un astfel de descriptor ​pentru ​aplicația web.+Parametrii aceștia putețsă-i alegeți la liber și să-i hardcodați (în funcție ​de câte luminițe aveți loc să reprezentați în ASCII Art-ul din terminal)însă ar fi drăguț ​să aveți minim 3 grupuri (e.g., ​pentru ​fiecare etaj al bradului sau pe diagonală).
  
-Î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). +Fiecare grup are ca identificator unic (unde numerotarea începe de la ''​1''​!) este un vector ​de LED-uri (de dimensiune statică).
-</​note>​+
  
-Datele de la senzori le veți prelua de la un alt serviciudescris în subsecțiune următoare. +Valoarea fiecărui LED dintr-un grup va fi ID-ul numeric al culorii acestuiafolosind [[https://​chrisyeh96.github.io/​2020/​03/​28/​terminal-colors.html|culorile clasice din terminal]]:​ 
-Dacă nu rezolvați acest task, puteți să prezentați pur și simplu câteva date de test în interfața Web.+  * ''​0''​ (//black//) (echivalent al LED-ului stins); 
 +  * ''​1''​ (<color red/​black>//​red//</​color>​);​ 
 +  * ''​2''​ (<color green/​black>//​green//</​color>​);​ 
 +  * ''​3''​ (<color yellow/​black>//​yellow//</​color>​);​ 
 +  * ''​4''​ (<color blue/​black>//​blue//</​color>​);​ 
 +  * ''​5''​ (<color magenta/​black>//​magenta//</​color>​);​ 
 +  * ''​6''​ (<color cyan/​black>//​cyan//</​color>​);​ 
 +  * ''​7''​ (<color white/​black>//​white//</​color>​);​
  
 +Astfel, se definesc următoarele endpointuri RESTful HTTP (atenție: API-ul este strict!):
 +  * ''​GET /​api/​groups'':​ va întoarce un obiect JSON cu proprietatea ''​NG''​ (numărul de grupuri disponibile),​ e.g.: ''​{"​NG":​ 3}'';​
 +  * ''​GET /​api/​group/<​G>/​state'':​ va întoarce un obiect JSON cu cheila ''​NL'':​ numărul de leduri din grupul curent, și ''​LC'':​ lista actuală de culori ale LED-urilor grupului ''<​G>''​ (fără caracterele ''<>'',​ sunt doar pentru a denota o variabilă),​ e.g., ''​{"​NL":​ 8, "​LC":​ [0, 0, 0, 1, 4, 2, 0, 0]}'';​
 +  * ''​POST /​api/​group/<​G>/​static'':​ va primi un obiect JSON cu o singură cheie: ''​LC''​ cu valoarea: o listă (JSON Array) de culori pentru fiecare LED din grupul ''<​G>'',​ și va întoarce OK (HTTP 200); desigur, aceste noi setări trebuiesc propagate către aplicația de terminal ce redă ASCII Art-ul;
 +  * ''​POST /​api/​group/<​G>/​animate''​ [**BONUS**]:​ va primi un obiect cu o cheie, ''​MC''​ care conține o matrice de culori pentru fiecare pas al animației, apoi pentru fiecare LED din grupul ''<​G>''​ și va întoarce OK (HTTP 200); tranzițiile vor fi făcute la fiecare secundă și va fi repetată automat până la revenirea la cazul simplu (cererea de mai sus); exemplu de mutare a culorilor asupra tuturor pozițiilor dintr-un grup: <​code>​
 +[
 +  [1, 2, 3, 0, 0, 0, 0, 0],
 +  [0, 1, 2, 3, 0, 0, 0, 0],
 +  [0, 0, 1, 2, 3, 0, 0, 0],
 +  [0, 0, 0, 1, 2, 3, 0, 0],
 +  [0, 0, 0, 0, 1, 2, 3, 0],
 +  [0, 0, 0, 0, 0, 1, 2, 3],
 +  [3, 0, 0, 0, 0, 0, 1, 2],
 +  [2, 3, 0, 0, 0, 0, 0, 1],
 +]
 +</​code>​
  
-=== Sensor data acquisition daemon===+Toate cererile vor folosi formatul ''​Content-Typeapplication/​json''​ atât la input (pentru cererile ''​POST''​),​ cât și la răspuns.
  
-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'',​ vizibil ​în guest Linux ca ''​/​dev/​ttyUSB0''​);+Vedeți exemple ​de utilizare ​în fișierul ​''​test.py'' ​din schelet.
  
-  * Programul ​va rula într-o buclă de citire de la dispozitiv, parsare și trimitere date către . +<note important>​ 
-  * La fel ca la serviciul web, puteți folosi orice limbaj / biblioteci de conectare pe dispozitivul serial ​(chiar și ''​bash'' ​:D )+Tema va fi testată în QEMU (''​v6.2+'' ​pe Ubuntu 22.04pentru placa [[https://qemu.readthedocs.io/en/latest/system/arm/virt.html|virt]] (este deja tipul implicit ​pentru ​build-urile Yocto ale ''​qemuarm'', ​cel folosit la laborator). 
-    * **Python**: ​[[https://pypi.org/​project/​pyserial/​|pyserial]];​ +</note>
-    * **NodeJS**: [[https://​www.npmjs.com/​package/​serialport|serialport]];​ +
-    * **PHP**: [[https://​www.php.net/​manual/en/​book.dio.php|DirectIO]];​ +
-    * **Golang**: [[https://​pkg.go.dev/​go.bug.st/​serial|goserial]] sau alte biblioteci similare (sunt multe cu același nume); +
-    * **Rust**: [[https://​docs.rs/​serialport/latest/serialport/|serialport]];​ +
-    * **C**: [[https://blog.mbedded.ninja/​programming/​operating-systems/​linux/​linux-serial-ports-using-c-cpp/​|POSIX + termios]]+
-  * 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! +
- +
-==== 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ă: <​code>​ +
-TIMESTAMP; LOCATION; SENSOR_NAME;​ SENSOR_VALUE;​ FLAGS (optional) +
-</code> +
- +
-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''​). 
  
-===== Instrucțiuni pentru rularea imaginii folosind QEmu =====+===== Helpers + Mașină virtuală ​=====
  
-Ca și punct de pornire, puteți descărca un {{si:teme2023:TODO-skel.tar.gz|schelet inițial cu scripturi + structură recomandată}} (**v0.1**).+Ca și punct de pornire, puteți descărca un {{si:teme2022:si-tema2-skel-2022-0-1.tar.gz|schelet inițial cu scripturi + structură recomandată}} (**v0.1**).
 Aceasta conține: Aceasta conține:
 +  * Makefile pentru generarea arhivelor cerute (înlocuiți-l pe cel de acum din VM, este inutil :D);
 +  * script de rulare qemu pe host (folosit pentru rularea directă a imaginii de distribuit, fără Yocto);
 +  * un fișier descriptor pentru //kas// diferit de cel din laborator (numit ''​tema2.yml''​);​
 +  * un script de testat endpointul RESTful (+ exemplu utilizare API) folosind python (''​test.py''​);​
 +  * un README.skel.txt pe care ar fi util să-l citiți ;)
 +  * **Important:​** citiți codul sursă al scripturilor și verificați (e.g., căile) să fie adecvate setup-ului vostru!
  
-  * 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);​ +Recomandarea ​de co-existență pentru tema2 + laborator folosind același VM cu Yocto: ​fișierele ​kas cu denumiri ​diferite (''​tema2.yml'' ​vs ''​kas.yml''​) ​ce vor importa seturi diferite ​de layere (desigurcele de bază vor rămâne, însă se recomandă crearea unui layer numit ''​meta-tema2'' ​șsă creați în interiorul lui configurațiile ​pachetele necesare tuturor task-urilor).
-  * un script Python ​''​sensors-emu.py''​ ce emulează datele ​de la senzoriintegrat cu ''​launch-tema2.sh'' ​(vedețcod sursă / help);+
  
-Aceste scripturi au fost testate în VM-ul oficial folosit la laborator+<​note>​ 
-Dacă aveți ​setup propriu, puteți cere ajutor pe Teams / Forum dacă apar probleme.+Nu uitați să inspectați configurația de resurse a VM-ului (și să le ajustați pentru PC-ul vostru)
 +Compilarea unor pachete poate eșua dacă nu aveți ​suficient RAM (''​8GB''​ ar trebui să fie OK pentru majoritatea cazurilor). 
 +</​note>​
  
 ===== Trimitere ===== ===== Trimitere =====
  
 Soluția temei va fi trimisă în două moduri (vă rugăm să respectați convențiile de denumire cu exactitate!):​ 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) -> [[TODO|pe Moodle]] +  * **arhivă cu codul sursă** + Readme + hash și alte metainformații (vedeți mai jos) -> [[https://​curs.upb.ro/​2022/​mod/​assign/​view.php?​id=102647|pe Moodle]] 
-  * **arhivă cu binarele / imaginea rulabilă** -> le urcați pe [[https://​ctipub-my.sharepoint.com|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''​).+  * **arhivă cu binarele / imaginea rulabilă** -> le urcați pe [[https://​ctipub-my.sharepoint.com|OneDrive / Sharepoint-ul ​UPB]] ș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**): +**Arhiva cu binarele** (''​.tar.gz''​ pls) trebuie să conțină (de preferat ​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). +  * ''​rootfs.img'':​ imaginea partiției rootfs în format RAW utilizabil de qemu (ori partiția ext4, ori disk image); 
-  * ''​vmlinuz-tema2'': ​imaginea ​kernel-ului compatibil cu QEMU; +  * ''​kernel'': ​binarul ​kernel-ului compatibil cu QEMU (scheletul îl copiază automat din cache-ul Yocto)
-  * ''​launch-tema2.sh'':​ script de pornire QEMU (vedeți scheletul dat); +  * ''​launch_bin.sh'':​ script de pornire QEMU (vedeți scheletul dat); 
-  * includeți șscripturile suplimentare necesare pentru rulare ​(e.g., simulatorul de senzori ​în Python); +  * Dacă doriți să ne prezentațalt scenariu demonstrativ ​(decât cel inclus ​în schelet), includeți un script numit ''​test.py''​. 
-  * **NU INCLUDEȚI**:​ cache-ul de build al Buildroot / Yocto (poate avea ''​6-20 GB''​!), DOAR artefactele finale! +  * **NU INCLUDEȚI**: ​directorul build cache al yocto (yep, acela de > 20GB!); 
-  * Această arhivă nu ar trebui să depășească ''​500MB''​ ([[https://​stackoverflow.com/​questions/​18855850/​create-a-tar-xz-in-one-commandfolosițtar.xz]] pentru rată de compresie bună).+  * Această arhivă nu ar trebui să depășească ''​500MB''​ (șasta în cazuri extreme).
  
-**Arhiva cu fișierele sursă** (''​.zip''​ pls) OBLIGATORIU să conțină:​ +**Arhiva cu fișierele sursă** (''​.zip''​ pls) este 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 preferatorganizat într-o structură Unix-like: ''​./​etc/'',​ ''​./​usr/​bin'',​ ''​./​opt/​*''​ etc.); **NU COPIAȚI ROOTFS-UL GENERAT!** +  * scripturile proprii de Yocto (layerrețete, fișier ''​yml'' ​pentru ​''​kas''​) + sursele ​aplicației ​(în orice limbaje ați ales); 
-  * 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 funcționarea ​soluției, configurații speciale de optimizare folosite etc. 
-  * 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.gz** a binarelor;
-  * 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ă!   * 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);+  * **NU INCLUDEȚI**:​ fișiere sursă ale Poky alte layere ​Yocto / biblioteci / frameworkuri descărcabile de pe Internet (menționați în Readme ce ați folosit); ​puteți include bblayers.conf și local.conf dacă le-ați modificat manual (în afara ''​kas''​).
   * **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)!   * **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).   * Această arhivă nu ar trebui să depășească ''​1MB''​ (aveți restricție pe Moodle).
Line 179: Line 200:
 Din 100p total, aveți: Din 100p total, aveți:
   * (30p) Imaginea și funcționalitățile de bază (trebuie să ruleze în qemu!);   * (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''​);​ +  ​* (30p) Endpoindul ​web RESTful ​așa cum este el descris mai sus (API-ul este strict!)
-  ​* (30p) Serviciul ​web de prezentare ​a; +  * (30p) Programul ​care randează ASCII art-ul cerut la consolă;
-  * (30p) Daemonul ​care achiziționaează datele pe UART;+
   * (10p) Readme scris clar și care descrie complet arhitectura și implementarea funcționalităților cerute.   * (10p) Readme scris clar și care descrie complet arhitectura și implementarea funcționalităților cerute.
  
 Bonus: Bonus:
-  * (10p) Aspect / funcționalitate deosebită (e.g., grafice ​în timp ale datelor, implementări tehnice eficiente etc.);+  * (10p) GPIO writing (necesar să compilați driverul ''​PL061'' ​în kernel);
   * (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!);​   * (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!);​
  
 <note important>​ <note important>​
-Imaginile ​care nu au au fost construite de la zero sau nu rulează deloc (cu excepția unor greșeli minore) nu vor fi punctate!+Soluțiile ​care nu au folosit Yocto sau nu rulează deloc (cu excepția unor greșeli minore) nu vor fi punctate!
 </​note>​ </​note>​
  
Line 195: Line 215:
  
   * 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!   * 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//! +  * :!: **ATENȚIE**:​ orice formă de plagiat nu va fi permisă și va duce la depunctare totală / restanță / //that which must not be named, the E-word//! 
-  * Pe Moodle găsiți și [[TODO|un forum]] ;) La fel pe Teams, avem un canal de discuții.+  * Pe Moodle găsiți și [[https://​curs.upb.ro/​2022/​mod/​forum/​view.php?​id=102648|un forum]] ;) La fel pe Teams, avem un canal de discuții.
  
 ===== Resurse ===== ===== Resurse =====
  
-  * [[:​si:​laboratoare:​04]] 
   * [[:​si:​laboratoare:​06]]   * [[:​si:​laboratoare:​06]]
   * [[:​si:​laboratoare:​07]]   * [[:​si:​laboratoare:​07]]
-  ​* [[:​si:​laboratoare:​08]] +  * [[https://asciinema.org/a/YIEhjwqJlYsYrWdD2nsIn4OX7|Exemplu de pom ASCII]]
-  * [[:​si:​laboratoare:​08]] +
-  ​* [[https://buildroot.org/downloads/manual/​manual.html|Buildroot manual]]+
  
-</​ifauth>​ 
  
si/teme2022/tema2.1702243722.txt.gz · Last modified: 2023/12/10 23:28 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