Tema 2 - Christmas LEDs

* Publicare:

  • 11 Decembrie 2022 17:50

* Termen de predare:

  • 15 Ianuarie 2023 23:55 - deadline HARD

* Changelog:

  • 14 Ianuarie 2023 22:30 - mărit deadline-ul până duminica ;)
  • 13 Ianuarie 2023 11:15 - corectat numele fișierelor: url.txt + checksum.txt (CU extensie).
  • 05 Ianuarie 2023 13:40 - reparat RESTful endpoints din text să fie ca în scriptul de Python de demo.

Obiective:

  • construirea unei distribuții Linux complete, build folosind Yocto;
  • creare layere + pachete Yocto;
  • configurări de bază Linux;
  • servicii de sistem Linux;
  • dezvoltare aplicații RESTful;
  • dezvoltare aplicații Terminal UI;
  • interfață GPIO Linux;
  • optimizări de spațiu;

Pentru a rezolva tema, este recomandat să folosiți 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).

Storyline / 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!

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 (sorry, Santa) 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ă 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.

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):

Cerințe

Imaginea Linux de bază:

  • Imaginea sistemului trebuie generată cu Yocto, pornind de la instrucțiunile prezente în Laboratorul 06. Root filesystem și servicii de sistem;
  • 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.

RESTful HTTP endpoint:

  • 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: flask / CherryPy / FastAPI (pick any);
    • NodeJS: ExpressJS / 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: net/http (aici nu se justifică să descărcați altceva);
    • Rust: http (built in, baby!);
    • C (for hardcore developers): Facil / 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 ;)

Serverul trebuie să pornească automat la boot (ca daemon). În Yocto 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).

Terminal UI program:

  • 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 secvențe escape ANSI);
  • 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:
  • Puteți face comunicarea între cele 2 procese (program TUI + server HTTP) prin orice mecanism vă pune Linux / limbajul la dispoziție (unix pipes, sockeț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 și 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);

Bonus task: GPIO

Dorim să trimitem comenzile primite de serverul HTTP către instalația hardware de leduri. Astfel:

  • Mașina de qemu dispune de un controller de GPIO PL061 pe care îl vom folosi să simulăm această interacțiune.
  • Pe partea de Linux, aveți API de 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ă re-configurați kernelul Yocto și să activați driverul 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ă!

Contract (API)

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). Parametrii aceștia puteți 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ă).

Fiecare grup are ca identificator unic (unde numerotarea începe de la 1!) este un vector de LED-uri (de dimensiune statică).

Valoarea fiecărui LED dintr-un grup va fi ID-ul numeric al culorii acestuia, folosind culorile clasice din terminal:

  • 0 (black) (echivalent al LED-ului stins);
  • 1 (red);
  • 2 (green);
  • 3 (yellow);
  • 4 (blue);
  • 5 (magenta);
  • 6 (cyan);
  • 7 (white);

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:
    [
      [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],
    ]

Toate cererile vor folosi formatul Content-Type: application/json atât la input (pentru cererile POST), cât și la răspuns.

Vedeți exemple de utilizare în fișierul test.py din schelet.

Tema va fi testată în QEMU (v6.2+ pe Ubuntu 22.04) pentru placa virt (este deja tipul implicit pentru build-urile Yocto ale qemuarm, cel folosit la laborator).

Helpers + Mașină virtuală

Ca și punct de pornire, puteți descărca un schelet inițial cu scripturi + structură recomandată (v0.1). 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!

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 (desigur, cele de bază vor rămâne, însă se recomandă crearea unui layer numit meta-tema2 și să creați în interiorul lui configurațiile / pachetele necesare tuturor task-urilor).

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).

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 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.gz pls) trebuie să conțină (de preferat să folosiți strict aceste denumiri de fișiere):

  • rootfs.img: imaginea partiției rootfs în format RAW utilizabil de qemu (ori partiția ext4, ori disk image);
  • kernel: binarul kernel-ului compatibil cu QEMU (scheletul îl copiază automat din cache-ul Yocto);
  • launch_bin.sh: script de pornire QEMU (vedeți scheletul dat);
  • Dacă doriți să ne prezentați alt scenariu demonstrativ (decât cel inclus în schelet), includeți un script numit test.py.
  • NU INCLUDEȚI: directorul build cache al yocto (yep, acela de > 20GB!);
  • Această arhivă nu ar trebui să depășească 500MB (și asta în cazuri extreme).

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

  • scripturile proprii de Yocto (layer, rețete, fișier yml pentru kas) + sursele aplicației (în orice limbaje ați ales);
  • fișier README.txt cu explicații referitoare la funcționarea soluției, configurații speciale de optimizare folosite etc.
  • fișier url.txt cu URL către arhiva .tar.gz a binarelor;
  • 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 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)!
  • 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-ul după deadline)!

Notare

Din 100p total, aveți:

  • (30p) Imaginea și funcționalitățile de bază (trebuie să ruleze în qemu!);
  • (30p) Endpoindul web RESTful așa cum este el descris mai sus (API-ul este strict!);
  • (30p) Programul care randează ASCII art-ul cerut la consolă;
  • (10p) Readme scris clar și care descrie complet arhitectura și implementarea funcționalităților cerute.

Bonus:

  • (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!);

Soluțiile care nu au folosit Yocto 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ță / that which must not be named, the E-word!
  • Pe Moodle găsiți și un forum ;) La fel pe Teams, avem un canal de discuții.

Resurse

si/teme2022/tema2.txt · Last modified: 2023/12/12 12:00 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