Differences

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

Link to this comparison view

si:teme2023:tema2 [2023/12/12 23:33]
florin.stancu
si:teme2023:tema2 [2024/01/12 18:01] (current)
florin.stancu
Line 1: Line 1:
-====== Tema 2 - Home Weather Monitoring System ======+====== Tema 2 - Weather Monitoring System ​(2023) ​======
  
   * **Publicare**:​   * **Publicare**:​
-    * **11 Decembrie 2023**+    * **15 Decembrie 2023**
  
   * **Termen de predare**:   * **Termen de predare**:
-    * <color red>**13 Ianuarie 2024 23:55** - deadline HARD</​color>​+    * <color red>**16 Ianuarie 2024 23:55** - deadline HARD</​color>​
  
 <​hidden>​ <​hidden>​
   * **Changelog:​**   * **Changelog:​**
-    * //**05 Ianuarie 2023 HH:II**// - TODO;+    * //**15 Ianuarie 2023 HH:II**// - TODO;
 </​hidden>​ </​hidden>​
  
Line 25: Line 25:
 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ă SI 2023]] cu toate uneltele necesare gata instalate!
 </​note>​ </​note>​
- 
-//TODO// 
  
 <ifauth @si> <ifauth @si>
 <color red>CINE VEDE RESTUL E ASISTENT ;) </​color>​ <color red>CINE VEDE RESTUL E ASISTENT ;) </​color>​
 +</​ifauth>​
  
 ===== Enunț ===== ===== Enunț =====
  
-Dorim să realizăm o aplicație IoT care primește date de la câțiva senzori meteo (temperatură,​ umiditate, ploaie -- datele ​vor fi emulate) și îi face disponibili pe o interfață web a unui Raspberry PI (de asemenea, emulat ​în qemu).+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 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ă 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).
  
-Aveți în imaginea următoare un exemplu ​de pagină ​web ce va fi afișată ​(însă aspectul nu prea contează):+Exemplu ​de frontend ​web (însă aspectul nu contează):
  
-TODO+{{si:​teme2023:​web-screenshot.png?​500}}
  
 ===== Cerințe ===== ===== Cerințe =====
Line 54: Line 53:
     * [[https://​www.yoctoproject.org/​|Yocto Linux]] - pentru experți ;)     * [[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);​     * **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);+  * **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);​   * 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 disk SD de ''​128MB''​).   * 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''​).
Line 69: Line 68:
  
 <note warning> <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.+**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 rootfs-ul construite prin tehnică de //​package-based bootstrapping//,​ puteți copia ulterior acest overlay folosind ''​cp -ar''​ sau ''​rsync -a''​.
Line 82: Line 81:
 Un prim avertisment:​ din păcate, kernel-urile descărcate de pe repository-ul [[https://​github.com/​raspberrypi/​linux|raspberrypi/​linux]] NU SUNT COMPATIBILE CU ''​qemu''​! Deci a nu se folosi! Un prim avertisment:​ din păcate, kernel-urile descărcate de pe repository-ul [[https://​github.com/​raspberrypi/​linux|raspberrypi/​linux]] NU SUNT COMPATIBILE CU ''​qemu''​! Deci a nu se folosi!
  
-Deci 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 de versiune (e.g., ''​v6.1''​).+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 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''​). **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''​)! NU uitați ''​ARCH=arm64''​ și configurația inițială a arhitecturii,​ ''​defconfig''​ (pe mainline NU există ''​bcm27*_defconfig''​)!
  
-Pentru a [[https://​lists.gnu.org/​archive/​html/​qemu-devel/​2021-06/​msg03171.htmla|nu avea probleme cu driverele externe]] (atât ''​mmc'', ​cât și driverul de rețea ''​usb-net'' ​pot face probleme dacă sunt încărcate ca module și acestea lipsesc de pe rootfs), 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''​.+Pentru a [[https://​lists.gnu.org/​archive/​html/​qemu-devel/​2021-06/​msg03171.htmla|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 ;). [[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 modifica! La configurarea kernelului, va trebui să setați parametrul ''​LOCALVERSION''​ la valoarea ''​-tema2''​ (sau ceva derivat, puteți să vă puneți și numele ;). [[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 modifica!
  
-Î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 [[https://​github.com/​raspberrypi/​linux/​issues/​2151#​issuecohttps://​lists.gnu.org/​archive/​html/​qemu-devel/​2021-06/​msg03171.htmlmment-321961979|aici]] sau [[https://​forums.raspberrypi.com/​viewtopic.php?​t=238262#​p1478536|aici]]. DTB-ul îl puteți compila voi sau prelua din altă parte (nu se depunctează).+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 [[https://​github.com/​raspberrypi/​linux/​issues/​2151#​issuecohttps://​lists.gnu.org/​archive/​html/​qemu-devel/​2021-06/​msg03171.htmlmment-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 important>​ <note important>​
Line 105: Line 106:
       * **Python**: [[https://​docs.python.org/​3/​library/​http.server.html|http.server]] / [[https://​flask.palletsprojects.com|flask]] / [[https://​djangoproject.com/​|Django]] / etc.;       * **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;       * **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);+      * **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!);​       * **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!);       * **Rust**: [[https://​docs.rs/​http/​latest/​http/​|http]] (built in libraries + dimensiuni ff. mici, la fel ca la GoLang!);
Line 130: Line 131:
 === Sensor data acquisition daemon: === === 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'',​ vizibil în guest Linux ca ''/​dev/​ttyUSB0''​);​+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 .   * Programul va rula într-o buclă de citire de la dispozitiv, parsare și trimitere date către .
Line 142: Line 143:
   * 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ă);​   * 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!   * 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 ==== ==== Format date seriale ====
Line 158: Line 164:
   * ''​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;   * ''​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''​).   * ''​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''​).
 +
 +<note warning>
 +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!
 +</​note>​
  
 ===== Instrucțiuni pentru rularea imaginii folosind QEmu ===== ===== Instrucțiuni pentru rularea imaginii folosind QEmu =====
  
-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:​teme2023:​si-tema2-skel-2023.v1.tar.gz|schelet inițial cu scripturi + structură recomandată}} (**v0.1**).
 Aceasta conține: 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);​   * 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''​ (vedeți cod sursă ​/ help);+  * 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. Aceste scripturi au fost testate în VM-ul oficial folosit la laborator.
Line 173: Line 186:
  
 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/​2023/​mod/​assign/​view.php?​id=92200|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|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''​).
  
Line 182: Line 195:
   * includeți și scripturile suplimentare necesare pentru rulare (e.g., simulatorul de senzori în Python);   * 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!   * **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''​ ([[https://​stackoverflow.com/​questions/​18855850/​create-a-tar-xz-in-one-commandfolosiți tar.xz]] pentru rată de compresie bună).+  * 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ă).
  
 **Arhiva cu fișierele sursă** (''​.zip''​ pls) OBLIGATORIU să conțină: **Arhiva cu fișierele sursă** (''​.zip''​ pls) OBLIGATORIU să conțină:
Line 199: Line 212:
  
 <note warning> <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-ul după deadline)!+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>​ </​note>​
  
Line 211: Line 224:
   * (30p) Serviciul web de prezentare a valorilor de la senzori;   * (30p) Serviciul web de prezentare a valorilor de la senzori;
   * (30p) Daemonul care achiziționaează datele pe UART;   * (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 ​procesul urmat, ​arhitectura și implementarea funcționalităților cerute.
  
 Bonus: Bonus:
Line 218: Line 231:
  
 <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!+Imaginile care nu au au fost construite ​personal ​sau nu rulează deloc (cu excepția unor greșeli minore) nu vor fi punctate!
 </​note>​ </​note>​
  
Line 225: Line 238:
   * 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ță + //​avertisment oficial la decanat//!
-  * 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/​2023/​mod/​forum/​view.php?​id=92202|un forum]] ;) La fel pe Teams, avem un canal de discuții.
  
 ===== Resurse ===== ===== Resurse =====
Line 236: Line 249:
   * [[https://​buildroot.org/​downloads/​manual/​manual.html|Buildroot manual]]   * [[https://​buildroot.org/​downloads/​manual/​manual.html|Buildroot manual]]
  
-</​ifauth>​ 
  
si/teme2023/tema2.1702416803.txt.gz · Last modified: 2023/12/12 23:33 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