This shows you the differences between two versions of the page.
|
si:teme2025:tema2 [2025/12/14 13:55] florin.stancu created |
si:teme2025:tema2 [2025/12/21 11:19] (current) florin.stancu |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Tema 2 - RPI+GPIO Internet of Trees (2025) ====== | + | ====== Tema 2 - RPI/GPIO Internet of Trees (2025) ====== |
| * **Publicare**: | * **Publicare**: | ||
| - | * **14 Decembrie 2025 22:00** | + | * **15 Decembrie 2025 18:00** |
| * **Termen de predare**: | * **Termen de predare**: | ||
| * <color red>**18 Ianuarie 2025 23:55** - deadline HARD</color> | * <color red>**18 Ianuarie 2025 23:55** - deadline HARD</color> | ||
| + | |||
| + | <hidden> | ||
| + | * **Changelog:** | ||
| + | * //**15 Ianuarie 2025 HH:II**// - TODO; | ||
| + | </hidden> | ||
| + | |||
| + | <note> | ||
| + | **Obiective**: | ||
| + | * construirea unei distribuții Linux minimaliste; | ||
| + | * configurări de bază Linux; | ||
| + | * servicii de sistem Linux; | ||
| + | * dezvoltare aplicații IoT; | ||
| + | * optimizări de spațiu; | ||
| + | * utilizare GPIOs din aplicațiile Linux; | ||
| + | </note> | ||
| + | |||
| + | <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 2025]] cu toate uneltele necesare gata instalate! | ||
| + | </note> | ||
| + | |||
| + | <ifauth @si> | ||
| + | <color red>CINE VEDE RESTUL E ASISTENT ;) </color> | ||
| + | </ifauth> | ||
| + | |||
| + | ===== Enunț ===== | ||
| + | |||
| + | Dorim să realizăm un firmware minimalist pentru un dispozitiv IoT ce va controla niște LED-uri ("ipotetice") prin GPIO + aplicație web folosind un Raspberry PI (emulate folosind [[https://www.qemu.org/|qemu]]). | ||
| + | |||
| + | Pe scurt, va trebui să realizați o imagine incorporabilă cu Linux ce va implementa o aplicație ce va controla o presupusă instalație de lumini a bradului de Crăciun prin GPIO (folosind [[https://web.archive.org/web/20250715003035/https://blog.lxsang.me/post/id/33|Linux GPIO API]]) și expune pe rețea un server HTTP cu o pagină web de vizualizare și control a luminilor (aici aveți libertate deplină asupra desenului / animațiilor / controalelor oferite). | ||
| + | |||
| + | Exemplu de frontend web (aspectul nu contează, dar puteți să faceți ceva mai drăguț dacă aveți timp/chef pentru bonus): | ||
| + | |||
| + | {{si:teme2025:web-screenshot.png?340}} | ||
| + | |||
| + | ===== 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): | ||
| + | * [[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 vor fi depunctate datorită dimensiunii enorme, wear&tear-ul SSD-ului celui care corectează tema etc. (''-20p''); | ||
| + | * [[https://alpinelinux.org/|Alpine Linux]] bootstrap-uit folosind [[https://wiki.alpinelinux.org/wiki/Bootstrapping_Alpine_Linux|apk.static]] -- procedură similară cu ''debootstrap'', însă se vor obține imagini destul de mici (recomandat pentru avansați, puteți folosi scriptul [[https://github.com/alpinelinux/alpine-chroot-install|alpine-chroot-install]], dar studiați-i codul bine înainte)! | ||
| + | * [[https://www.yoctoproject.org/|Yocto Linux]] - very steep learning curve, necesar 50GB + 8GB RAM pentru compilare, doar pentru cei care au mai folosit!. | ||
| + | * **NU se acceptă**: rootfs gata construit / descărcabil (e.g., imaginea cu //Debian// / //Raspberry OS//); | ||
| + | * **Kernel** compilat de voi cu ''LOCALVERSION=%%"-si-<prenume.nume>"%%'' (altfel nu se punctează acest aspect! 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'' (recomandat, ''raspi4b'' nu bootează ușor cu un kernel custom); vedeți mai jos config-uri de kernel testate deja pentru compatibilitate + aveți script de rulare în schelet; | ||
| + | * 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 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 ''tema2025'' (obligatoriu: să ne putem autentifica în consola emulată); | ||
| + | * hostname-ul ''tema2025''; | ||
| + | * 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ă -- setare deja prezentă în scriptul de rulare din schelet); | ||
| + | * să ruleze SSH pe portul 22 (și să fie activată autentificarea cu ''root'' + parolă, aka setarea ''PermitRootLogin''!); | ||
| + | |||
| + | Rezolvarea acestei cerințe este OBLIGATORIE pentru obținerea oricărui fel de punctaj (altfel nu avem ce testa => ''0p'')! | ||
| + | |||
| + | <note warning> | ||
| + | **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 //distro 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]] (folosiți OVERLAY, e cel mai ușor + elegant). | ||
| + | |||
| + | + citiți enunțul până la capăt pentru a vedea cerințele finale! | ||
| + | </note> | ||
| + | |||
| + | === Compilare Kernel === | ||
| + | |||
| + | Recomandăm folosirea kernelului ''mainline'', descărcabil de pe [[https://kernel.org/]] (sau Github, [[https://github.com/torvalds/linux/|torvalds/linux]]). **NU LUAȚI MASTER-ul** sau alte branch-uri experimentale! Folosiți un branch/tag de versiune (e.g., ''v6.12''). | ||
| + | |||
| + | La configurarea kernelului, **va trebui să setați parametrul ''LOCALVERSION'' la valoarea ''%%-si-<prenume.nume>%%''** (folosiți username-ul de pe Moodle în loc de placeholderl ''%%<prenume.nume>%%'', e.g. ''%%-si-florin.stoian%%''!). [[https://unix.stackexchange.com/questions/194129/linux-kernel-version-suffix-config-localversion|Vedeți aici]] variabilele implicate, TLDR: nu uitați să dezactivați ''LOCALVERSION_AUTO'' pentru a putea set versiunea voastră custom! | ||
| + | |||
| + | Pentru o testare rapidă a sistemului rădăcină, puteți folosi imaginea ''vmlinuz-test'' inclusă în scheletul de temă în scheletul de temă (atenție: compatibil doar cu ''raspi3b'' cu device tree-ul ''bcm2837-rpi-3-b.dtb''). | ||
| + | |||
| + | **Au fost testate** versiunile ''v6.12'' și ''v6.6'', compilate atât automat prin ''buildroot'' (însă se configurează mai special, vedeți mai jos), cât și manual. Așadar, aveți două opțiuni de compilare: | ||
| + | |||
| + | == 1. Compilare manuală == | ||
| + | |||
| + | Pur și simplu se descarcă codul sursă [[https://github.com/torvalds/linux/|torvalds/linux]] de pe git (ori din GitHub release, arhivă .tar.gz mult mai mică) și să dă ''make'' ca [[:si:laboratoare/08|în laborator]] (nu uitați să modificați ''LOCALVERSION''!)! | ||
| + | |||
| + | <note tip> | ||
| + | NU uitați ''ARCH=arm64'' și configurația inițială a arhitecturii, ''defconfig'' (pe mainline NU există ''bcm27*_defconfig'')! | ||
| + | </note> | ||
| + | |||
| + | Pentru a [[https://lists.gnu.org/archive/html/qemu-devel/2021-06/msg03171.html|a nu avea probleme cu copierea/instalarea modulelor încărcabile dinamic]] (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 lor pe sistemul rădăcină (în ''<rootfs>/lib/modules''). Alternativ, va trebui să instalați modulele ''.ko'' rezultate într-un overlay folosind ''make ... modules_install'' și apoi copia pe rootfs-ul vostru! | ||
| + | |||
| + | == 2. Compilare automată prin Buildroot == | ||
| + | |||
| + | Pentru cei care folosesc ''buildroot'', aveți opțiunea de a compila kernelul Linux (în ''menuconfig'', aveți ''BR2_LINUX_KERNEL'' cu toate opțiunile de descărcare necesare). | ||
| + | |||
| + | Însă procesul de adaptare a configurației de kernel necesită pași + documentare suplimentară (//still pretty much recommended!//): | ||
| + | |||
| + | * va trebui să folosiți kernelul mainline (''torvalds/linux''); se recomandă utilizarea unei reguli de descărcare a arhivei ''tar.gz'' de pe GitHub ([[https://buildroot.org/downloads/manual/manual.html#github-download-url|documentație aici]] cu ce să puneți la URL de descărcare) + exemplu la [[https://gitlab.com/buildroot.org/buildroot/-/blob/master/configs/raspberrypi3_64_defconfig?ref_type=heads|config-ul oficial Buildroot pentru raspberrypi]]; | ||
| + | * va trebui ori să patchuiți ''linux/linux.hash'' și să adăugați hash-urile arhivei descărcate de pe GitHub asociate versiunii voastre, sau dezactiva de tot verificarea de hash prin opțiunea ''BR2_DOWNLOAD_FORCE_CHECK_HASHES=n'' (însă este mai complicat și necesită modificarea variabilei ''BR_NO_CHECK_HASH_FOR'' direct din Makefile, aceasta nu e expusă în Kconfig!!); | ||
| + | * pentru a încărca automat modulele de kernel pe un rootfs de Buildroot, aveți nevoie de o soluție de [[https://buildroot.org/downloads/manual/manual.html#_dev_management|gestiune a dispozitivelor Linux]]; puteți ori să folosiți ''systemd'', ori va trebui configurat EUDEV (recomandat), exemplu de config ce trebuie efectuat (depinde de ce ''defconfig'' ați ales dacă sunt prezente sau nu): <code> | ||
| + | # se poate alege și biblioteca ucLibC, însă am avut probleme cu python3-flask | ||
| + | BR2_TOOLCHAIN_BUILDROOT_MUSL=y | ||
| + | BR2_SHARED_STATIC_LIBS=y | ||
| + | BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y | ||
| + | </code> | ||
| + | * soluție alternativă ar fi să faceți ca la compilare manuală, să compilați tot kernel image-ul ca monolit, fără module încărcabile (''MODULES=n'')! | ||
| + | * pentru a customiza kernelul (va trebui să modificați, cel puțin: ''LOCALVERSION*''), aveți target-ul buildroot ''make linux-menuconfig'' (atenție: nu uitați să faceți save / backup la config-ul de kernel după modificare, [[https://buildroot.org/downloads/manual/manual.html#customize-store-package-config|citiți în manual cum]]); | ||
| + | |||
| + | |||
| + | == Precizări comune la compilarea kernelului == | ||
| + | |||
| + | Deși e prezent în ''defconfig'' (în caz că vreți să optimizați), nu uitați să verificați / includeți driverele de GPIO și USB Ethernet necesare testării! | ||
| + | |||
| + | 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 [[https://github.com/raspberrypi/linux/issues/2151#issuecomment-321961979|aici]] sau [[https://forums.raspberrypi.com/viewtopic.php?t=238262#p1478536|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ă). | ||
| + | |||
| + | <note tip> | ||
| + | Dacă nu vedeți nimic la bootarea kernelului, înseamnă că ori imaginea sau device tree-ul sunt proaste (și este dificil de dat seama), ori consola serială implicită este configurată greșit din kernel command line. | ||
| + | Asigurați-vă că aveți parametrii kernel de [[https://www.raspberrypi.com/documentation/computers/configuration.html#enabling-early-console-for-linux|earlycon corecți]] pentru varianta de Raspberry PI emulată. Dacă vedeți mesaje inițiale în consolă, însă se blochează ulterior în procesul de boot și nu apare login prompt-ul, atunci înseamnă că parametrul ''console='' al kernelului este incorect (încercați alt dispozitiv serial, e.g., ''ttyAMA<i>'', ''ttyS<i>'' etc.). | ||
| + | </note> | ||
| + | |||
| + | <note important> | ||
| + | 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 trebui să scrieți în README ce ați încercat și ce rezultate ați avut! | ||
| + | </note> | ||
| + | |||
| + | === HTTP Server / Web UI: === | ||
| + | |||
| + | Dorim ca sistemul să expună un server HTTP pe portul 80 o interfață web minimalistă care să prezinte o diagramă a stării luminițelor (GPIO-urilor) și va oferi cel puțin o comandă de control (e.g., start / stop al animației, randomizat beculețele/GPIO-urile aprinse etc.). | ||
| + | |||
| + | * Va trebui să rulați automat la boot, ca daemon, un server http ce va asculta pe portul 80; | ||
| + | * NU contează așa mult ce desenați (e.g., puteți pune un fundal cu brad și poziționa luminițele prin coordonate custom pentru a ne pune în tema sărbătorilor mai bine, sau folosi o matrice simplă dacă nu e chef); | ||
| + | * NU este obligatoriu să aveți animație real-time a stării LED-urilor / GPIO-urilor emulate! Este suficient să se schimbe la refresh sau automat cu perioadă mare (1-5 secunde); JavaScript-ul care să animeze realtime va fi considerat bonus! | ||
| + | * 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; | ||
| + | * **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)! | ||
| + | * Dacă aplicația nu pornește automat (și veți fi depunctați), lăsați pe rootfs un script de pornire în ''/srv/''! | ||
| + | |||
| + | <note> | ||
| + | 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 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). | ||
| + | </note> | ||
| + | |||
| + | <note> | ||
| + | Pentru ''Buildroot'', dacă folosiți un interpretor / limbaj care necesită dependințe externe, citiți secțiunea [[https://buildroot.org/downloads/manual/manual.html#adding-packages|Adding Packages]]. | ||
| + | Pentru Python aveți incluse deja o mulțime de biblioteci populare. | ||
| + | Pentru Golang, citiți secțiunea [[https://buildroot.org/downloads/manual/manual.html#_infrastructure_for_go_packages|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 lui standard. | ||
| + | </note> | ||
| + | |||
| + | Interogarea și controlul GPIO-urilor puteți să o realizați fie folosind un alt serviciu / program separat, sau să fie thread nou în cadrul serverului web. | ||
| + | Modul de interfațare va fi descris în subsecțiune următoare. | ||
| + | |||
| + | Dacă nu doriți să rezolvați și acel task, puteți să prezentați pur și simplu câteva date de test (i.e. hardcodate) în interfața Web. | ||
| + | |||
| + | === GPIO Control === | ||
| + | |||
| + | Pe lângă serviciul web, va trebui să dezvoltați un serviciu de control al GPIO-urilor, cu specificația: | ||
| + | |||
| + | * Recomandarea ar fi să faceți un serviciu daemon care va primi comenzi de la serverul web și va rula o buclă internă de bit toggling pe interfața GPIO a Linux-ului. | ||
| + | * Mai întâi, citiți aici documentație despre [[https://web.archive.org/web/20250715003035/https://blog.lxsang.me/post/id/33|Linux GPIO API]]. | ||
| + | * Va fi necesar să controlați doar primii 20 de GPIOs (pinii indexați 0-19 ai ''/dev/gpiochip0'') | ||
| + | * Atenție: [[https://pinout.xyz/|numerotarea pinilor pe Raspberry PI]] NU corespunde cu organizarea logică a acestora! | ||
| + | * În vizualizatorul de GPIO atașat de QEMU, s-a folosit o simplificare: pinii sunt indexați de la 0 la 20 și afișați pe 2 coloane! | ||
| + | * Organizarea vizuală NU contează (e.g., dacă desenați în interfața web un brad, puteți atribui orice culoare / poziție oricărui pin); NU este necesară utilizarea tuturor pinilor, doar a unei majorități utile; | ||
| + | * Vizualizatorul inclus NU necesită astfel de prezentare (e.g., forma unui brad), fiind folosit strict pentru a testa acționarea GPIO-urilor; opțional, ca bonus, puteți să-l modificați să ilustreze același lucru ca aplicația web; | ||
| + | * Atenție: dacă doriți să folosiți culori RGB, veți avea nevoie de 3 GPIO-uri diferite, deci atenție ce planificați de la început! | ||
| + | * De asemenea, pasul de animație nu ar trebui să fie mai rapid de 500ms (i.e., frecvență sub ''2Hz''); | ||
| + | * NU faceți PWM + NU FOLOSIȚI întreruperi de GPIO (nu au fost implementate în qemu :( ); | ||
| + | * La fel ca la serviciul web, puteți folosi orice limbaj / biblioteci (chiar și ''bash'') pentru acționarea GPIO-urilor, însă e recomandată biblioteca GPIOD dacă este disponibilă: | ||
| + | * **Python**: [[https://github.com/brgl/libgpiod/blob/master/bindings/python/README.md|gpiod]] (din BR2: pur și simplu activați pachetele ''python3'' și [[https://github.com/buildroot/buildroot/blob/master/package/libgpiod/libgpiod.mk|libgpiod]] versiunea 1, că în v2, e disponibil abia în [[https://github.com/buildroot/buildroot/commit/b243b77ebe5eedf8fbc683d5539d9bf386da4420|buildroot master]]); | ||
| + | * **NodeJS**: [[https://www.npmjs.com/package/node-libgpiod|node-libgpiod]]; | ||
| + | * **PHP**: [[https://github.com/PiPHP/GPIO|PiPHP GPIO]]; | ||
| + | * **Golang**: [[https://periph.io/|periph.io]]; | ||
| + | * **Rust**: [[https://docs.rs/rppal/latest/rppal/|rppal]] or whatever că nu folosesc Rust; | ||
| + | * **C**: [[https://libgpiod.readthedocs.io/|libgpiod]] (also see: tutorialul de GPIO de mai sus e în C); | ||
| + | * Puteți face comunicarea între cele 2 procese (de la serverul HTTP la daemonul de GPIO) prin orice mecanism vă pune Linux / limbajul la dispoziție (unix pipes, sockeți, RPC framework al limbajului, chiar și niște fișiere simple text + polling pentru o implementare rudimentară); | ||
| + | * Deaemonul (dacă este separat) trebuie să pornească automat cu sistemul! | ||
| + | * Dacă daemonul nu pornește automat (și veți fi depunctați), lăsați pe rootfs un script de pornire TOT în ''/srv/''! | ||
| + | |||
| + | ==== Vizualizator GPIO în consolă ==== | ||
| + | |||
| + | Pentru a vedea dacă acționarea voastră de GPIO funcționează, punem la dispoziție în schelet un program CLI simplu de Python ce se conectează la QEmu prin [[https://www.qemu.org/docs/master/devel/testing/qtest.html|protocolul qtest]] inspirat de aici: [[https://ihateyour.cloud/post/20201204-1.html]]. | ||
| + | |||
| + | {{si:teme2025:gpio-viewer-screenshot.png}} | ||
| + | |||
| + | Acesta face polling la starea GPIO-urilor în memoria VM-ului de qemu și afișează colorat pe ecran la intervale de 200ms (din acest motiv este impusă restricția de frecvență a animațiilor)! | ||
| + | |||
| + | <note warning> | ||
| + | Pentru testare, veți porni manual script-ul ce generează astfel de date **în paralel** cu ''qemu''! | ||
| + | |||
| + | Implicit, socketul de qtest este creat de către scriptul de ''launch-tema2'' folosind linia de comandă qemu. Dacă faceți ceva custom, nu uitați să includeți! De asemenea, vedeți calea unde este creat socketul de control qtest (prin ''/tmp'' și schimbați / ștergeți la nevoie) | ||
| + | </note> | ||
| + | |||
| + | ===== Schelet temă ===== | ||
| + | |||
| + | Ca și punct de pornire, puteți descărca un {{si:teme2025:si-tema2-skel-2025_rev1.zip|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 ''gpio-viewer.py'' ce vizualizează starea regiștrilor hardware emulați ai GPIO-urilor, integrat cu ''launch-tema2.sh'' (comunică printr-un socket de qtest în ''/tmp'', vedeți cod sursă); | ||
| + | * o imagine de kernel ''vmlinuz-test'' compilată ca monolit (''MODULES=n'') cu strictul necesar de drivere (consolă serială PL011 & 8250, USBNET, IP_PNP, BRCM platform devices, GPIOs etc.); | ||
| + | |||
| + | <note warning> | ||
| + | Atenție: scriptul de ''launch-tema2.sh'' rulează qemu cu parametrul ''-qtest <socket_path>'', ce va da eroare dacă nu există acel UNIX socket creat (de către aplicația ''gpio-viewer.py''). Dacă doriți să rulați VM-ul FĂRĂ GPIO Viewer, folosiți ''make run A=%%--%%no-qtest'' sau direct ''./launch-tema2.sh %%--%%no-qtest''! | ||
| + | </note> | ||
| + | |||
| + | ===== Trimitere ===== | ||
| + | |||
| + | Deoarece Moodle nu acceptă dimensiuni foarte mari, soluția temei va fi împărțită și 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) -> [[https://curs.upb.ro/2025/mod/assign/view.php?id=86207|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 accesibil tuturor conturilor (sau, cel puțin cu permisiuni la ''florin.stancu@upb.ro''), însă nepublicat (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'' atașabil prin ''losetup'', NU qcow sau altele!); 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, dacă mai sunt (e.g., viewerul de GPIO-uri în CLI, dacă l-ați modificat); | ||
| + | * **NU INCLUDEȚI**: cache-ul de build al Buildroot / Yocto (poate avea ''6-20 GB''!), DOAR artefactele finale (copiați-le manual sau folosiți ceva similar ca în Makefile-ul din schelet)! | ||
| + | * Această arhivă nu ar trebui să depășească ''500MB'' ([[https://stackoverflow.com/questions/18855850/create-a-tar-xz-in-one-command|folosiți tar.xz]] pentru rată de compresie bună). | ||
| + | |||
| + | <note important> | ||
| + | Pe Sharepoint, dați link CĂTRE FIȘIERUL ARHIVEI, NU CĂTRE UN ÎNTREG DIRECTOR! | ||
| + | |||
| + | Noi avem scripturi care automatizează descărcarea, veți fi depunctați dacă nu urmați aceste convenții! | ||
| + | Ar trebui să meargă descărcate automat punând ''&download=1'' la finalul URL-ului ;) | ||
| + | </note> | ||
| + | |||
| + | **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!** (doar OVERLAY-ul, dacă ați folosit); | ||
| + | * fișierele de configurație (''.config'') ale kernel și/sau buildroot -- **obligatoriu** dacă 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 **de pe Sharepoint!** (uploadată anterior); | ||
| + | * 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). | ||
| + | |||
| + | <note> | ||
| + | Puteți folosi Makefile-ul din scheletul temei pentru generarea acestor două arhive, însă este recomandată verificarea manuală a arhivelor după generare! | ||
| + | </note> | ||
| + | |||
| + | <note warning> | ||
| + | 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)! | ||
| + | </note> | ||
| + | |||
| + | ===== Notare ===== | ||
| + | |||
| + | Din 100p total, aveți: | ||
| + | * (40p) Imaginea și funcționalitățile de bază (trebuie să ruleze în qemu!); | ||
| + | * ''-20p'' depunctare pentru imaginea SD cu rootfs-ul ce depășește 256MB (testat cu interpretorul Python în Buildroot, tot se încadrează în limită!); | ||
| + | * se contorizează fără kernel, acesta poate avea max. ''64M'' -- deși nu e imposibil să-l faceți s depășească această dimensiune, încercați să nu! | ||
| + | * ''-10p'' depunctare pentru kernel necompilat de voi (ori îl folosiți pe cel furnizat de noi în schelet, ori cel furnizat de voi nu conține ''%%LOCALVERSION="-si-<prenume.nume>"%%''); | ||
| + | * //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! | ||
| + | * (20p) Aplicația web de prezentare/control a luminițelor; | ||
| + | * (30p) Daemonul/thread-ul care setează/animează GPIO-urile; | ||
| + | * (10p) Readme scris clar și care descrie procesul urmat, arhitectura și implementarea funcționalităților cerute. | ||
| + | |||
| + | Bonus: | ||
| + | * (10p) Aspect / funcționalitate deosebită (e.g., animații realtime, controale extra ale GPIO-urilor, arhitecturi de sistem elegante, utilizare de pachete/layers pe Buildroot sau Yocto 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!); | ||
| + | |||
| + | <note important> | ||
| + | Imaginile care nu au au fost construite personal sau nu rulează deloc (cu excepția unor greșeli minore) nu vor fi punctate! | ||
| + | </note> | ||
| + | |||
| + | ===== 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ță! | ||
| + | * Pe Moodle găsiți și [[https://curs.upb.ro/2025/mod/forum/view.php?id=86208|un forum]] ;) | ||
| + | |||
| + | ===== Resurse ===== | ||
| + | |||
| + | * [[:si:laboratoare:2025:06]] | ||
| + | * [[:si:laboratoare:2025:07]] | ||
| + | * [[:si:laboratoare:2025:08]] | ||
| + | * [[:si:laboratoare:2025:09]] | ||
| + | * [[https://buildroot.org/downloads/manual/manual.html|Buildroot manual]] | ||
| + | |||