Differences

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

Link to this comparison view

si:laboratoare:07 [2020/12/04 17:07]
stefan_radu.maftei
si:laboratoare:07 [2023/11/22 12:59] (current)
florin.stancu
Line 1: Line 1:
-===== Laboratorul 07. Fitbit SDK - Clock Face ===== +====== Laboratorul 07. Kernel Build System ======
-Până acum target-ul nostru a fost RaspberryPi,​ dar în acest laborator și următorul noul target va fi un produs Fitbit, și anume **Fitbit Versa 3** sau **Fitbit Sense** (produse lansate anul acesta). Vom utiliza //Fitbit Software Development Kit// (//SDK//) pentru a dezvolta o față de ceas (clock face) în cadrul acestui laborator, și o aplicație (app) în laboratorul următor, folosind mediul de dezvoltare pus la dispoziție de către Fitbit (Fitbit Studio) și simulatorul (Fitbit OS Simulator). Documentația pentru dezvoltatorii de aplicații Fitbit se poate găsi pe [[https://​dev.fitbit.com/​]].+
  
-===== Setup ===== +Kernel-ul reprezintă o parte a sistemului de operare responsabilă cu accesul la hardware și managementul dispozitivelor dintr-un sistem de calcul (exprocesoul, memoria, dispozitivele de I/O)De asemenea, el are rolul de a simplifica accesul la diferitele dispozitive hardware, oferind o interfață generică pentru aplicații prin intermediul system-call-urilorÎn spatele interfeței generice se află porțiuni din kernel, numite drivere, care implementeză comunicația cu dispozitivele hardware. Un alt rol al kernel-ului este de a izola aplicațiile între ele, atât pentru stabilitatea sistemului, cât și din considerente de securitate.
-Setup-ul oficial poate fi găsit [[https://dev.fitbit.com/getting-started/​|aici]] la secțiunea //What You’ll Need//.+
  
-<note tip>Vă recomandăm să folosiți **Windows** sau **macOS** pentru aceste laboratoare!<​/note>+| {{ :​si:​lab:​2015:​kernel:​architecture.png?​300 |Architectura unui sistem de operare [By Bobbo (Own work) [CC-BY-SA-3.0 (http://​creativecommons.org/​licenses/​by-sa/​3.0) or GFDL (http://​www.gnu.org/​copyleft/​fdl.html)],​ via Wikimedia Commons]}} | 
 +^ Architectura unui sistem de operare ^
  
-Pentru a putea folosi infrastructura pusă la dispoziție ​de către Fitbit va trebui ​să urmați pașii: +Pentru a îndeplini toate aceste sarcini, codul kernel-ului rulează într-un mod special ​de lucru al procesorului,​ fapt care îi permite ​să execute o serie de instrucțiuni privilegiate. Acest mod privilegiat de lucru nu este accesibil aplicațiilor obișnuiteSpunem că aplicațiile rulează în //user-space// (modul neprivilegiat),​ iar kernel-ul rulează în //kernel-space// (modul privilegiat).
-  - Creați-vă un cont Fitbit accesând [[https://​www.fitbit.com/​signup|acest link]]. +
-  - Descărcați simulatorul (Fitbit OS Simulator) pentru [[https://simulator-updates.fitbit.com/download/latest/​win|Windows]] sau [[https://​simulator-updates.fitbit.com/​download/​latest/​mac|macOS]]. Nu există support pentru Linux, dar există workarounds pentru acest lucru în cazul în care doriți să utilizați Linux la aceste laboratoare (urmați pașii de [[https://github.com/bingtimren/fitbit-sim-starter|aici]] pentru a rula simulatorul pe Linux). +
-  - Accesați [[https://​studio.fitbit.com/​|Fitbit Studio]], mediul de dezvoltare online pus la dispozție pentru developeri. +
-<note important>​Conectați-vă atât la Fitbit Studio, cât și la simulator cu **același** cont Fitbit creat mai sus!</​note>​+
  
-===== Arhitectura unei aplicații folosind Fitbit SDK ===== +===== Linux =====
-<note tip>​Informațiile următoare se regăsesc în documentația oficială: https://​dev.fitbit.com/​build/​guides/​application/</​note>​+
  
 +Linux este numele unui kernel creat de către Linus Torvalds, care stă la baza tuturor distribuțiilor GNU/Linux. Inițial, el a fost scris pentru procesorul Intel 80386 însă, datorită licenței permisibile,​ a cunoscut o dezvoltare extraordinară,​ în ziua de astăzi el rulând pe o gamă largă de dispozitive,​ de la ceasuri de mână până la super-calculatoare. Această versatilitate,​ cât și numărul mare de arhitecturi și de periferice suportate, îl face ideal ca bază pentru un sistem embedded.
  
-O aplicație tipică are următoarea structură de directoare: +<​note>​ 
-  * ''/​app/''​ - directorul conține logica aplicației care urmează a fi executată pe device. Un fișier ''​index.js''​ trebuie să existe în acest director, altfel operația ​de build va eșua. +Arhitecturile suportate ​de kernel-ul Linux se pot afla listând ​conținutul directorului ​''​arch'' ​din cadrul surselor
-  * ''/​companion/''​ - director opțional, conține logica companion-ului care este executată pe device-ul mobil (capabil să facă request-uri către Internet și să comunice cu aplicația). Dacă existe un fișier ''​index.js''​ atunci componenta companion ​se va builda. +</note>
-  * ''/​common/''​ - director opțional, ​conține fișiere care pot fi folosite atât de aplicație, cât și de companion. +
-  * ''​/settings/'' ​- director opțional, conține informații despre setările aplicației+
-  * ''​/resources/''​ - directorul conține toate resursele care sunt folosite de aplicație. +
-  * ''​package.json''​ - fișierul de configurare pentru aplicație.+
  
-<note important>​ +Linux este un kernel cu o arhitectură monolitică,​ acest lucru însemnând că toate serviciile oferite de kernel rulează în același spațiu de adresă și cu aceleași privilegii. Linux permite însă și încărcarea dinamică de cod (în timpul execuției) în kernel prin intermediul modulelor. Astfel, putem avea disponibile o multime de drivere, însă cele care nu sunt folosite des nu vor fi încarcate ​și nu vor rulaSpre deosebire de aplicații însă, care rulează în modul neprivilegiat (//user-space//​) ​și nu pot afecta funcționarea kernel-uluiun modul are acces la toată memoria kernel-ului și se execută în //​kernel-space//​ (poate executa orice instrucțiune privilegiată). Un bug într-un modul sau un modul malițios poate compromite întregul ​sistem
-Tipurile de resurse din directorul ''/​resources/''​ sunt: + 
-  * ''/​resources/​index.view''​ - fișier obligatoriu,​ aici este definită interfațcu utilizatorul ​(fișier SVG) +Dezvoltarea kernel-ului Linux se face în mod distribuit, folosind sistemul de versionare Git. Versiunea oficială ​kernel-ului,​ denumită //​mainline//​ sau //vanilla// este disponibilă ​în repository-ul lui Linus Torvalds, la adresa [[https://​git.kernel.org/pub/scm/​linux/​kernel/​git/​torvalds/​linux.git]]. 
-  * ''​/resources/widget.defs'' ​fișier obligatoriuacesta controlează ce widget-uri de sistem ​sunt disponibile pentru ​fi folosite ​în ''​index.view''​. + 
-  * ''​/resources/*.css'' ​fișiere CSS care pot schimba aspectul elementelor din ''​index.view''​+Versiunea oficială este însă rar folosită într-un sistem embedded nemodificatăEste foarte comun ca fiecare sistem să folosească o versiune proprie a kernelului (numită un //tree//) bazată mai mult sau mai puțin pe versiunea oficială. Datorită licenței GPLv2 a kernelului, însă, orice producător care folosește o versiune modificată a kernelului este obligat să pună la dispoziție modificările aduse
-  * ''​/resources/*.png'' ​și '' ​/resources/*.jpg'' ​imagini ce pot fi folosite ​în ''​index.view''​ folosind tag-ul ''​<image>''​.+ 
 +Aceste modificări sunt puse la dispoziție sub formă de //patch//-uri care trebuie aplicate unei anumite versiuni de kernelO altă modalitate, care este folosită ​și de către fundația RaspberryPi,​ este de a publica un repository de Git cu versiunea modificată (un //tree// alternativ)Datorită modelului distribuit de dezvoltare suportat de Git, această a doua metodă are avantajul că permite dezvoltarea ușoară în paralel a celor două versiuni. Modificările făcute într-una pot fi portate și în cealaltă, iar Git va ține minte ce diferențe există în fiecare versiuneCele două versiuni sunt de fapt două //branch//-uri de dezvoltare, care se întâmplă să fie găzduite pe servere diferite. 
 + 
 +<note> 
 +Kernel-ul folosit pe RaspberryPi,​ care include suportul pentru SoC-ul Broadcom BCM2835 folosit de acesta, se găsește la adresa [[https://​github.com/​raspberrypi/​linux.git]].
 </​note>​ </​note>​
  
 +===== Linux kernel build system =====
 +
 +Pentru compilare și generarea tuturor componentelor kernel-ului (ex: imaginea principală - //​vmlinux//,​ module, firmware) Linux folosește un sistem de build dezvoltat o dată cu kernel-ul, bazat pe utilitarul //make//. Acest sistem de build însă nu seamănă cu clasicul //​config/​make/​make install//, deși ambele sunt bazate pe utilitarul //make//.
 +
 +Toți pașii de compilare sunt implementați ca target-uri pentru //make//. De exemplu, pentru configurare se poate folosi target-ul ''​config''​. Acestă metodă de configurare însă nu este recomandată deoarece oferă o interfață foarte greoaie de configurare a kernel-ului.
 +
 +<note tip>
 +Target-ul ''​help''​ oferă informații despre aproape toate operațiile suportate de către sistemul de build.
 +
 +<code shell>
 +$ make help
 +</​code>​
 +</​note>​
 +
 +Operațiile oferite sunt grupate în diferite categorii:
 +  * //​cleaning//​ - conține target-uri pentru ștergerea fișierelor generate la compilare
 +    * spre deosebire de ''​clean'',​ ''​mrproper''​ șterge în plus toate fișierele generate, plus configurarea și diferite fișiere de backup
 +  * //​configuration//​ - conține diferite target-uri pentru generarea unei configurări a kernelului; există target-uri care permit:
 +    * generarea unui fișier de configurare nou; ex: ''​defconfig'',​ ''​allmodconfig'',​ ...
 +    * actualizarea unui fișier de configurare existent; ex: ''​olddefconfig'',​ ''​localyesconfig'',​ ...
 +    * editarea unui fișier de configurare existent; ex: ''​menuconfig'',​ ''​nconfig'',​ ...
 +  * //generic// - conține target-uri generice; există target-uri pentru:
 +    * compilare; ex: ''​all''​ - target-ul implicit care este executat la o invocare simplă a lui ''​make'',​ iar ''​vmlinux''​ și ''​modules''​ compilează imaginea kernel-ului și, respectiv, modulele selectate
 +    * instalare; ex: ''​headers_install'',​ ''​module_install'',​ ...
 +    * informații;​ ex: ''​kernelrelease'',​ ''​image_name'',​ ...
 +  * //​architecture dependent// - conține target-uri dependente de architectură,​ care diferă în funcție de arhitectura selectată; există target-uri pentru;
 +    * generarea de imagini în diferite formate: compresate (''​zImage''​ și ''​bzImage''​),​ pentru U-Boot (''​uImage''​),​ ...
 +    * generarea de configurări implicite pentru sisteme bazate pe arhitectura selectată; ex: ''​*_defconfig''​
 +
 +<​note>​
 +Arhitectura care va fi compilată este selectată de variabila de mediu ''​ARCH''​.
 +
 +<code shell>
 +$ ARCH=x86 make [<​targets>​]
 +sau
 +$ make ARCH=x86 [<​targets>​]
 +</​code>​
 +</​note>​
  
-===== Exerciții ===== 
 <note important>​ <note important>​
-În cadrul simulatorului setați **Versa 3** sau **Sense** ca de tip device (Settings -> Device Type). Vom folosi versiunea 5.0 a SDK-ului.+Dacă arhitectura nu este setată explicit, se folosește implicit arhitectura sistemului pe care se face compilarea.
 </​note>​ </​note>​
  
-0. Urmați primii 3 pași de la secțiunea //Create Your First Project// (SetupCreate ​New Project, Installing) de pe https://dev.fitbit.com/​getting-started/. În urma acestui exercițiu ar trebui ​să apară aceeași față de ceas (clock face) în simulator ca cea din ghid.+În cele mai multe situații se dorește compilarea unui kernel pentru un sistem deja existent, fie pentru a adăuga sau elimina funcționalitățsau pentru a actualiza versiunea ​de kernel folosită. În aceste cazuri folosirea target-urilor de generare a unei configurații noichiar și celor care generează o configurație implicită pentru arhitectura noastră nu sunt neapărat utileEste posibil ca kernel-ul existent ​să aibă deja o configurație personalizată care se dorește doar a fi actualizată/​modificată folosind target-urile ​de editare
  
-1Ne propunem ​să creăm o nouă față de ceas (cea din GIF-ul de mai jos)Pentru aceasta ​puteți edita pe cea de la exercițiul anterior ​sau să creați un nou proiect ​și să alegeți ca template tot //Digital Clock//. Descărcați ​template-ul pentru laborator de [[https://drive.google.com/file/d/1DUrDt1szMPLCVOwq5MPfcUtjeSdRhygJ/​view?​usp=sharing|aici]] și aplicați-l în cadrul proiectului. Rulați aplicația în simulator+Un kernel care rulează poate conține fișierul de configurare (de obicei în format comprimat //gzip//) din care a fost compilat, dacă această funcționalitatea a fost selectată la buildAcest fișier se regăsește în ''/​proc/​config.gz''​. Tot ce rămâne este să extragem acest fișier și să-l modificăm conform dorințelor. 
-<note tip> + 
-Exercițiile ​din laborator se rezolvă în fișierul ​''​app/​index.js''​. Template-ul conține comentarii ​de tip //TODO// pentru fiecare subpunct ​al exercițiilor. Vom utiliza doar Device APIs, documentația lor se află [[https://dev.fitbit.com/build/reference/device-api/| aici]]Limbajul ​de programare utilizat ​este Javascriptdar ne vom limita ​la funcționalitățile ​de bază.+===== Device Tree Structure ===== 
 + 
 +Device Tree-ul este structura de date, la nivelul kernel-ului,​ care descrie componentele hardware prezente pe sistem, care nu pot fi descoperite automat de kernel. El este prezent pe sistemele cu arhitecturi ARM, dar si pe alte sisteme (nu pe cele care se bazeaza pe arhitectura x86). Fiecare intrare a device tree-ului descrie o componenta individuala. 
 + 
 +Device Tree-ul este stocat in 2 fisiere: ''​.dtb''​ (device tree blob), in format binar, si ''​.dts''​ (device tree source), in format text. Ambele tipuri de fisiere se gasesc in ''​arch/<​arhitectura>/​boot/​dts'',​ fiind generate de target-ul ''​dtbs''​ al comenzii ''​make''​. 
 + 
 +===== Testare ===== 
 + 
 +Pentru a testa un nou kernel acesta trebuie instalat pe //target//. Această procedură diferă de la sistem la sistem, iar pe RaspberryPi constă în copierea acestuia pe card-ul SD în partiția ​de //boot// sub numele de ''​kernel8.img''​. În momentul dezvoltării și testării unui nou kernel, instalarea fiecărei versiuni a acestuia pe //target// reprezintă un bottleneck major. 
 + 
 +O alternativă la instalarea kernel-ului pe //​target// ​reprezintă încărcarea acestuia prin rețea direct ​pe de //host//-ul folosit ​la dezvoltare, dacă există suport din partea bootloader-ului. Din păcate, bootloader-ul implicit de pe RaspberryPi nu are suport pentru a încărca o imagine de kernel de pe rețea. Un bootloader care oferă însă acestă facilitate este //U-Boot// [[#​referinte| [2]]], el folosind protocolul TFTP pentru a boota o imagine de kernel prin rețea. 
 + 
 +===== Instalare pachete/​programe din surse ===== 
 + 
 +De multe ori ne lovim de problema instalării unui pachet ​sau a unui program pe care îl găsim doar pe un repository public, de cele mai multe ori bazat pe Git. Astfel, pentru a ne putea folosi de acel pachet/​program,​ trebuie ​să cunoaștem următoarele utilitare:​ 
 + 
 +==== Git ==== 
 + 
 +Opțiuni școmenzi git: 
 + 
 +   - ''​git clone //<​repo>//''​ - va aduce toate fișierele conținute de repository-ul //repo// pe mașina locală. 
 +   - ''​git pull''​ - actualizează ​un repository deja clonat local la ultima versiune remote. 
 +   - ''​git checkout //<​branch>//''​ sau ''​git checkout //<​tag>//''​ - actualizează fișierele locale la versiunea indicată de //branch// sau de //tag//. Un repository poate avea mai multe branch-uri, care pot fi văzute ca niște versiuni diferite ale repository-ului. Un exemplu uzual de folosire a branch-urilor este pentru organizarea diferitelor versiuni ale aceluiași program. 
 +   - ''​git apply //<patch file>//''​ - aplică pe fișierele locale modificările conținute de fișierul ​//patch//. 
 + 
 + 
 + 
 +====== Exerciții ====== 
 + 
 +**0.** Pregăriri 
 + 
 +<​hidden>​ 
 +  * **Pentru asistenți:​** descărcați [[https://github.com/cs-pub-ro/SI-rpi-debian-scripts/releases|de aici imaginea '​rpi-full.img'​ pentru Raspberry PI (v2)]] și scrieți-o pe Raspberry PI folosind un disk imager (ori cu un card reader, ori bootați un U-Boot, schimbați cardul SD, ''​mmc rescan'',​ apoi ''​ums mmc 0''​ (găsiți disk-ul accesibil de pe calculatorul la care e conectat prin USB Type-C)
 +</​hidden>​ 
 + 
 +  * Descarcati ultima varianta de kernel Linux pentru Raspberry Pi, de [[https://​github.com/​raspberrypi/​linux.git|aici]]. <​code>​ 
 +git clone https://​github.com/​raspberrypi/​linux.git --depth=1</​code>​ 
 + 
 +  * Instalati pachetele ''​bc'',​ ''​bison'',​ ''​flex'',​ ''​libssl-dev'',​ ''​libc6-dev'',​ ''​libncurses5-dev'',​ ''​crossbuild-essential-arm64''​. 
 + 
 +  * Generati configurarea implicita a kernel-ului (tip: defconfig). <code
 +cd linux/ 
 +export KERNEL=kernel8 
 +make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig 
 +</​code>​ 
 + 
 +  * Modificati ​din ''​menuconfig'' ​numele imaginii de kernel 
 + 
 +<note tip>​General Setup -> Local Version</​note>​ 
 +<note tip><​code>​ 
 +make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig 
 +</​code></​note>​ 
 + 
 +  * Verificati daca driver-ul de mmc este activat (nu ca modul) 
 + 
 +<​note ​tip>trebuie sa vedeti ''​MMC [=y]''​ </note> 
 + 
 +  * Compilati nucleul, device tree blob-urile si modulele de nucleu. <​code>​ 
 +make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image Image.gz modules dtbs -j$(nproc)<​/code> 
 + 
 +<note important>​Procesul de compilare va dura destul de mult. Daca folositi o masina virtuala, dati-i cat mai multe nuclee, pentru a reduce timpul</note> 
 + 
 +  * Cat se compileaza nucleul, inspectati fisierul ''​.dts''​ corespunzator placii RaspberryPI 4B. <​code>​ 
 +arch/arm64/​boot/​dts/​broadcom/​bcm2711-rpi-4-b.dts</​code>​ 
 + 
 +  * Kernelul nostru experimental se instalează folosind următorii pași: <​code>​ 
 +# se presupune că aveți deja montate imaginea / cardul SD al RPi-ului (citiți mai jos!) 
 +sudo env PATH=$PATH make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_PATH=<​path_catre_partitia_de_boot>​ install 
 +sudo env PATH=$PATH make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=<​path_catre_partitia_de_rootfs>​ modules_install 
 + 
 +# Notă: nu suprascrieți device tree-ul deoarece o versiune greșită ar strica u-boot-ul ​:
 +# Dar așa s-ar copia: 
 +#sudo cp arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b.dtb <​path_catre_partitia_de_boot>​/ 
 +#sudo cp arch/​arm64/​boot/​dts/​overlays/​bcm2711-rpi-4-b.dtb* <​path_catre_partitia_de_boot>/​overlays/​ 
 + 
 +# Redenumim imaginea ​de kernel (e deja cea compresata) 
 +sudo mv <​path_catre_partitia_de_boot>/​vmlinuz-<​versiunea-noua>​ <​path_catre_partitia_de_boot>/​vmlinuz-student 
 + 
 +# Demontam partitiile 
 +sudo umount <​path_catre_partitia_de_boot>​ 
 +sudo umount <​path_catre_partitia_de_rootfs>​ 
 + 
 +# Oprim ums 
 +</​code>​ 
 + 
 +  * **Notă**: dacă aveți probleme cu USB device passthrough-ul pe Raspberry PI, este suficient să copiem DOAR fișierul vmlinuz pe partiția de bootcea FAT32. Pentru aceasta, bootați-l în modul ''​ums''​ din U-Boot, conectat ​la USB Type-C) și copiați DOAR fișierul ''​arch/​arm64/​boot/​Image.gz''​ sub numele ​de ''​vmlinuz-student''​. 
 + 
 +<note tip>​Pentru a porni ums, urmati urmatorii pasi: 
 +  * conectati adaptorul de seriala la laptop 
 +  * ''​picocom /​dev/​ttyUSB0 -b 115200''​ 
 +  * conectati cablu de alimentare 
 +  * la un moment dat va aparea **Hit any key to stop autoboot:​**;​ apasati orice tasta 
 +  * daca nu ati intrat in meniul de U-Boot, apasati Ctrl-C 
 +  * din meniul de U-Boot, dati comanda ''​ums mmc 0''​ 
 +  * partitiile ar trebui sa fie vizibile: **/​dev/​sda1**(root) si **/​dev/​sda2**(rootfs) 
 +  * daca nu vi le monteaza sistemul de operare automat, montati-le ​
 </​note>​ </​note>​
  
-{{:​si:​laboratoare:​si_clock.gif?​400|}}+<note important>​ 
 +U-boot din imaginea nouă este configurat să booteze automat ''​vmlinuz-student'',​ dacă există!
  
-2. Deocamdată fațde ceas indică doar oradar nu și statisticile afișate in cele 4 cadrane. Pentru acest exercițiu ne propunem ​să selectăm prima opțiune (pașii). +Acesta va aștepta 10 secundepermițând să întrerupeți procesul ​pentru a putea re-accesa modul ''​ums'' ​pentru a rescrie imaginea pe viitor
-  - obțineți restul elementelor de UI (hr, floors, battery) și apoi adăugați acele variabile într-un array. + 
-  - creați un array pentru ​culorile celor 4 cadrane. +Puteți ​vedea [[https://github.com/cs-pub-ro/SI-rpi-debian-scripts/​blob/​labsi/configs/​labsi-rpi4/files/uboot-script.txt|codul sursă al scriptului de u-boot ​aici]]. ​
-  - completați funcția **initializeStat()** astfel incât să seteze ca opțiunea cu pași să fie cea selectată inițial (la start-up), funcția nu trebuie să întoarcă nimic. Trebuie să setați culoarea cadranului și label-ului, dar și textul label-ului (''​statLabel''​). Inițializați variabila ''​currStat''​ care va stoca opțiunea curentă+
-<note tip> +
-**Hints**:​ +
-  * În Javascript, o constantă se definește astfel ''​const my_const = 0''​. +
-  * În Javascript, o variabilă se definește astfel ''​let my_var = 0''​. +
-  * În Javascript, un array se definește astfel ''​const cars = ["​Volvo",​ "​BMW",​ "​Dacia",​ "​Skoda"​]''​. +
-  * Pentru a obține un element UI putem folosi ''​document.getElementById(<​id>​)''​ din //​Document//​ API, ''<​id>''​ fiind id-ul definit deja în ''/​resources/​index.view''​. +
-  * Puteți ​alege orice culori doriți de [[https://dev.fitbit.com/build/guides/user-interface/css/|aici]]. Cele utilizate în exemplu sunt ''"​darkturquoise",​ "​fb-red",​ "​orange",​ "​limegreen"''​. +
-  * Pentru a seta culoarea unui element ''​x''​ se poate folosi ''​x.style.fill = "​red"''​. +
-  * Pentru a seta textul unui element text ''​x''​ se poate folosi ''​x.text = "​Steps"''​.+
 </​note>​ </​note>​
  
-3. Ne dorim ca fața de ceas să itereze prin cele 4 cadrane la apăsarea ecranului (click pe ecran în simulator). Funcția care a fost setată să se apeleze la un eveniment de click/tap este funcția ''​changeStat()''​Completați-o astfel încât la fiecare apel să se selecteze următoarea opțiune (setând culoarea, textul îl vom seta la următorul exercițiu)Înainte de a seta noua opțiune asigurați-vă că ați deselectat-o pe cea anterioară (setați-i culoarea alb).+  * Porniti RaspberryPI-ul cu noua versiune, ​ca in [[https://ocw.cs.pub.ro/​courses/​si/​laboratoare/​06#​exercitii|laboratorul 6]].
  
-4. Pentru ca fațde ceas să fie completă, trebuie să îi adăugăm și datele pentru fiecare opțiune selectată. Completați funcția ''​fillInStatLabel()''​ astfel încât la fiecare apel să se seteze text-ul afișat din variabila ''​statLabel''​ în funcție ​de opțiunea curentă. Va trebui să includeți și să apelați API-urile pentru ​//user-activity// (pașifloors)//​heart-rate//​ (hr) și //power// (baterie) ​pentru a obține datele. +<note warning>​ 
-<note tip> +Dacă nu ați copiat modulele externe pe rootfs-ul de pe Raspberry PI al noului kernel, Linux se va plânge când bootează că lipsesc o parte din modulele necesare de anumite dispozitive hardware ​software non-esențiale (//ahem: multe suntdefaptnecesare ​pentru a avea suport ​pentru ​rețelistică ​în Linux//), însă procesul ​de boot ar trebui să se finalizeze.
-**Hints**:​ +
-  * Folosiți un [[https://​www.w3schools.com/​js/​js_switch.asp|switch statement]] ​pentru ​a interoga variabila opțiunii curente ''​currStat''​. +
-  * Textul afișat poate fi de forma **<​Opțiune>:​ Valoare** +
-  * Pentru a crea un șir de caractere ​în care aveți mai multe variabile puteți folosi : ''​my_string =  `${var_string}:​ ${var_number}`''​. +
-  * Pentru a extrage numărul de pași și floors se utilizează variabila **today** din API-ul ​//user-activity//​ astfel: https://​dev.fitbit.com/​build/​reference/​device-api/​user-activity/​. +
-  * Pentru a extrage procentajul bateriei se utilizează variabila **battery** din API-ul //power// astfel: https://​dev.fitbit.com/​build/​reference/​device-api/​power/​. +
-  *  Pentru a extrage numărul ​de bătăi ale inimii pe minut se procedează astfel: https://​dev.fitbit.com/​build/​guides/​sensors/​heart-rate/​. **ATENȚIE**:​ folosiți variabila ''​hrm''​ pentru a nu inițializa de fiecare dată un nou obiect. +
-  * In ''​package.json''​ selectati permisiunile pentru //​Activity//​ si //Heart Rate//.+
 </​note>​ </​note>​
  
-===== Resurse ​===== +====== Referințe ====== 
-  * {{:​lab:​2015:​tools:​sol:​tools_sol.zip|Soluție laborator}} + 
-  ​[[https://drive.google.com/file/d/1DUrDt1szMPLCVOwq5MPfcUtjeSdRhygJ/​view?​usp=sharing|Template Laborator]] +  ​[[https://www.raspberrypi.com/documentation/computers/linux_kernel.htmlGhid compilare kernel RaspberryPi]] 
-  ​[[https://nodejs.org/en/knowledge/​getting-started/​npm/​what-is-the-file-package-json/| What is the file `package.json`?​]] +  ​[[https://www.thegoodpenguin.co.uk/blog/build-boot-linux-on-raspberry-pi-3-model-b/| Ghid compilare U-Boot pentru RaspberryPi]] 
-  * [[https://​dev.fitbit.com/​getting-started/| Getting Started with Fitbit SDK]] + 
-  * [[https://​dev.fitbit.com/​build/​reference/​device-api/| Fitbit SDK Device API Reference]] +
-  * [[https://​dev.fitbit.com/​build/​guides/​| Fitbit SDK Guides]]+
si/laboratoare/07.1607094423.txt.gz · Last modified: 2020/12/04 17:07 by stefan_radu.maftei
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