CURSUL 07

Modele de Execuție și Planificare în Sistemele Embedded de Timp Real

Durată: 119 min de predare Nivel: licență, anul III - recomandat după Cursul 06 Disciplină: Sisteme Încorporate Laborator asociat: Laboratorul 03 PDF: descarcă suportul EN English version

Un sistem embedded de timp real nu e definit de viteză, ci de garanții: rezultatul corect, livrat prea târziu, este la fel de greșit ca un rezultat incorect. Acest curs formalizează exact ce înseamnă "la timp" - de la lanțul senzor-decizie-actuator și parametrii temporali ai unui task, până la stările unui task RTOS, comutarea de context, și doi algoritmi clasici de planificare (Rate Monotonic și Earliest Deadline First) cu testele lor de schedulabilitate.

1Obiectul și structura cursului6 min

„Sistem de timp real" nu înseamnă „sistem rapid" - înseamnă un sistem ale cărui garanții sunt temporale, nu doar logice. Un sistem foarte rapid, dar fără nicio garanție asupra celui mai prost caz posibil, nu e un sistem de timp real; un sistem lent, dar cu o limită maximă demonstrată și respectată mereu, este.

Recapitulare din Cursul 01
  • Sistemele hard real-time: depășirea deadline-ului produce defectare sau pericol
  • Sistemele firm real-time: depășirea ocazională reduce performanța, fără defectare
  • Sistemele soft real-time: întârzierile afectează calitatea serviciului, nu funcționarea
Astăzi transformăm această clasificare intuitivă în unelte matematice precise.

Rezultate ale învățării

  • Să distingeți corectitudinea logică de corectitudinea temporală a unui sistem
  • Să descompuneți latența end-to-end a unui lanț senzor-decizie-actuator pe componente
  • Să descrieți parametrii temporali ai unui task (C, T, D, J) și stările lui în RTOS
  • Să calculați utilizarea procesorului și să aplicați limita Liu-Layland pentru RMS
  • Să aplicați EDF și să explicați diferența față de planificarea cu priorități fixe
  • Să estimați costul comutării de context și impactul lui asupra utilizării CPU

2Corectitudinea logică și temporală10 min

Corectitudinea unui sistem de timp real
corectitudine = corectitudine_logică + corectitudine_temporală. Corectitudinea logică arată că algoritmul produce rezultatul dorit; corectitudinea temporală arată că rezultatul e produs în intervalul în care mai este util.

O comandă calculată perfect corect, dar aplicată cu întârzierea Δt, devine u_aplicat(t) = u_calculat(t - Δt) - dacă Δt depășește limita acceptată de procesul controlat, funcționarea poate deveni instabilă sau periculoasă, indiferent cât de „corect" a fost calculul.

De ce timpul mediu nu e suficient Un sistem de timp real are nevoie de o limită superioară demonstrată - T_execuție ≤ T_execuție,max și R_i ≤ D_i (timpul de răspuns sub deadline-ul relativ) - nu doar de un timp mediu bun. Timpul mediu e util pentru performanța generală, dar nu demonstrează respectarea deadline-ului.
Exemplu - capcana mediei

O funcție de control rulează de 1000 de ori. În 999 de cazuri, R = 0,5 ms; într-un singur caz, R = 25 ms. Media e (999×0,5 + 25)/1000 ≈ 0,5245 ms - foarte bună. Dacă deadline-ul e 5 ms, acea unică valoare de 25 ms a ratat deadline-ul, oricât de bună arată media. Analiza temporală trebuie făcută pentru scenariul cel mai nefavorabil credibil, nu pentru cazul mediu măsurat în dezvoltare.

Surse tipice ale variației temporale: latența întreruperilor, timpul de blocare pe resurse partajate, timpul de comutare a contextului, interferența produsă de activități cu prioritate mai mare, și variația introdusă de hardware (cache, predicție de ramificații) și software.

3Sistemul reactiv și lanțul senzor-decizie-actuator10 min

Sistemele embedded de timp real sunt, aproape mereu, sisteme reactive: nu execută un calcul izolat, ci răspund continuu la modificări ale mediului fizic, printr-un lanț: proces fizic → senzori → achiziție și condiționare → estimare/decizie/control → actuatoare → feedback către proces.

Latența end-to-end
T_end-to-end = T_senzor + T_achiziție + T_comunicație + T_așteptare + T_calcul + T_actuator
De reținut Optimizarea exclusivă a algoritmului nu garantează îndeplinirea cerinței end-to-end - dacă senzorul actualizează rezultatul lent, sau mesajul e întârziat de o rețea, timpul total poate rămâne prea mare oricât de rapid ar fi algoritmul de control. Lanțul trebuie analizat integral, cu un buget temporal explicit pentru fiecare componentă: D_control = D_senzor + D_transfer + D_software + D_actuator + marjă.
Exemplu - robot mobil

Un robot detectează un obstacol la d = 0,5 m, cu viteza v = 1 m/s. Timpul ideal disponibil până la impact: T_disponibil = d/v = 0,5 s. Din acest interval trebuie scăzute timpul de frânare, întârzierea actuatorului, achiziția senzorului și marja de siguranță - software-ul nu dispune de întreaga jumătate de secundă pentru a lua decizia.

Evenimentele care declanșează un sistem reactiv pot fi periodice (o buclă de control la fiecare 10 ms), sporadice (apariția unei erori), aperiodice (o comandă de la utilizator) sau sincrone/asincrone față de ceasul procesorului - tipul de activare influențează direct arhitectura software și metoda de planificare aleasă, subiectul secțiunilor următoare.

4Domenii de aplicare și cerințe verificabile6 min

Nivelul de criticitate și consecințele întârzierilor diferă radical între domenii: în automotive (frânare, control al motorului, airbag), o întârziere poate costa vieți; în aplicații multimedia, depășirea ocazională a unui deadline produce doar pierderea unui cadru vizibil, fără consecințe de siguranță.

O cerință temporală verificabilă

„Sistemul trebuie să răspundă rapid" nu poate fi verificată. „Pentru fiecare activare a funcției de protecție, comanda actuatorului trebuie generată în maximum 2 ms, în toate condițiile de operare definite" poate - precizează evenimentul de start, evenimentul de final, limita temporală, condițiile de operare și comportamentul la depășirea limitei.

Formulați întotdeauna cerințele temporale cantitativ, verificabil - „suficient de rapid" nu e o specificație, e o intenție.

5Parametrii temporali ai unei activități10 min

O activitate software de timp real se modelează formal ca un task τᵢ, cu patru parametri de bază:

Modelul unui task
τᵢ = (Cᵢ, Tᵢ, Dᵢ, Jᵢ), unde:
Cᵢ = timpul de execuție în cazul cel mai nefavorabil (WCET);
Tᵢ = perioada sau intervalul minim dintre activări;
Dᵢ = deadline-ul relativ;
Jᵢ = jitter-ul de activare.
TermenSemnificație
Determinismgaranția că sistemul respectă o limită temporală cunoscută, nu doar "de obicei"
Latențătimpul dintre un eveniment și reacția sistemului la el
Jittervariația latenței între activări succesive ale aceleiași activități
De ce jitter-ul contează separat de latență Un sistem cu latență medie mică dar jitter mare poate fi mai greu de utilizat decât unul cu latență puțin mai mare, dar constantă - pentru bucle de control, variația imprevizibilă a momentului de eșantionare poate introduce erori greu de modelat, chiar dacă fiecare execuție individuală respectă deadline-ul.

6Rolul și structura unui sistem de operare de timp real8 min

Un RTOS (Real-Time Operating System) oferă aplicației un nivel de abstractizare peste hardware: task-uri, sincronizare, comunicare inter-task, gestiunea timpului și a întreruperilor - fără ca dezvoltatorul să reimplementeze aceste mecanisme de la zero pentru fiecare proiect.

Trei componente centrale ale unui RTOS:

  1. Kernel - miezul care gestionează task-urile, memoria și sincronizarea; oferă primitivele de bază (creare task, semafoare, cozi de mesaje, timere).
  2. Scheduler - decide care task rulează, la fiecare moment de decizie, pe baza politicii de planificare (subiectul central al acestui curs).
  3. Dispatcher - execută efectiv comutarea de context, aplicând decizia scheduler-ului: salvează contextul task-ului curent, restaurează contextul noului task, reia execuția.
RTOS vs. bare-metal

Nu orice sistem embedded de timp real are nevoie de RTOS - pentru aplicații simple, cu puține activități concurente, o buclă principală (superloop) bare-metal, cu întreruperi pentru evenimentele urgente, poate respecta perfect cerințele temporale, cu o complexitate mult mai mică. RTOS-ul devine avantajos când numărul de activități concurente, cu priorități și perioade diferite, crește suficient încât gestionarea lor manuală devine fragilă.

7Stările unui task și comutarea contextului11 min

Un task nu rulează permanent - trece prin mai multe stări pe durata existenței sale.

StareSemnificație
Runningtask-ul execută instrucțiuni pe procesor (cel mult unul, pe un singur nucleu)
Readypregătit să ruleze, dar procesorul e ocupat de alt task
Blockedașteaptă un eveniment (mesaj, semafor, date, timer, resursă)
Suspendedexclus explicit din planificare - reluarea cere o operație dedicată, nu doar un timeout

Tranziția Running → Blocked apare când task-ul solicită o operație care nu poate fi finalizată imediat. La apariția evenimentului așteptat, Blocked → Ready - dar nu automat în Running: task-ul deblocat intră în lista de task-uri pregătite, iar execuția lui depinde de prioritate. Dacă prioritatea task-ului deblocat depășește prioritatea celui curent (p_deblocat > p_curent), scheduler-ul preemptiv poate întrerupe imediat task-ul curent.

Timeout, nu blocare nelimitată

Un task care așteaptă un eveniment trebuie, aproape mereu, să folosească și un timeout - blocarea nelimitată nu e acceptabilă dacă evenimentul așteptat poate să nu mai sosească niciodată (mesaj pierdut, periferic defect). La fel de important: un task nu trebuie să aștepte activ un eveniment într-o buclă (while(!data_available()){}) - asta îl ține Ready/Running, consumând procesor și blocând task-uri cu prioritate egală sau mai mică, exact opusul scopului pentru care există starea Blocked.

Comutarea contextului și costul ei

Comutarea de context salvează starea completă a task-ului curent (registre, program counter, stack pointer, registru de stare) și o restaurează pentru noul task selectat - un cost real, care nu execută funcționalitate utilă a aplicației.

Utilizarea consumată de comutări
U_switch = N_switch × C_switch / T
Exercițiu rezolvat

Un sistem face 5000 de comutări de context pe secundă, fiecare durând 5 µs. Ce fracțiune din procesor se pierde doar cu overhead-ul de comutare?

Vezi rezolvarea

T_switch_total = 5000 × 5 µs = 25 ms pe secundă.

U_switch = 25 ms / 1000 ms = 2,5%

2,5% din capacitatea procesorului se pierde exclusiv cu comutarea de context, înainte de a socoti și timpul petrecut în scheduler și în tratarea întreruperilor. Reducerea numărului de task-uri fragmentate excesiv, evitarea time-slice-urilor prea mici și gruparea activităților reduc direct această pierdere - dar nu în detrimentul clarității arhitecturii sau al izolării funcționalităților critice.

Viata unui task intr-un RTOS preemptiv: puneti tranzitiile in ordine

8Concurență, paralelism și preempție6 min

Trei concepte adesea confundate: concurență (mai multe activități logic active în același interval, indiferent dacă rulează chiar simultan), paralelism (execuție chiar simultană, pe nuclee diferite) și preempție (întreruperea forțată a unui task de către scheduler, în favoarea unuia cu prioritate mai mare).

Pe un microcontroler cu un singur nucleu, task-urile sunt concurente, dar nu paralele - iluzia de simultaneitate vine din comutarea rapidă între ele. Preempția e mecanismul care face posibilă respectarea deadline-urilor: fără ea, un task de prioritate mică, odată pornit, ar bloca task-uri critice, cu prioritate mai mare, până la finalizarea lui.

9Strategii de planificare9 min

Politica de planificare decide, la fiecare moment relevant, care task Ready devine Running.

StrategiePrincipiuPotrivită pentru
Planificare pe priorități (fixe)task-ul Ready cu cea mai mare prioritate ruleazăsisteme cu criticitate diferențiată clar
Round Robintask-urile de aceeași prioritate rotesc, fiecare cu un time-slice fixechitate între task-uri similare

Overhead-ul planificării în sine (timpul petrecut de scheduler pentru a decide, nu doar pentru a comuta contextul) trebuie inclus în orice analiză riguroasă - un algoritm de planificare „optim" pe hârtie, dar prea costisitor de rulat, poate fi impractic pe un microcontroler cu resurse limitate. Criteriile de proiectare relevante: predictibilitate, ușurința de analiză formală, overhead de implementare și comportamentul la suprasarcină (ce se întâmplă exact când sistemul nu mai poate respecta toate deadline-urile).

10Modelul task-urilor, utilizarea și hiperperioada4 min

Pentru un set de n task-uri periodice Γ = {τ1,...,τn}, fiecare cu utilizare Uᵢ = Cᵢ/Tᵢ, utilizarea totală este U = Σ Uᵢ.

Condiție necesară, nu suficientă U ≤ 1 e necesară pentru orice set de task-uri periodice independente pe un singur procesor - dar nu e suficientă pentru orice algoritm de planificare. Un set cu U = 0,5 nu e automat schedulabil - depinde de politica de planificare folosită, exact subiectul următoarelor două secțiuni.

Intervalul după care modelul de activări se repetă complet e hiperperioada: H = cmmmc(T1,...,Tn) - utilă pentru construirea unei diagrame complete de planificare pe exemple mici, dar devine rapid impracticabilă când perioadele sunt numeroase sau nu sunt multipli unele altora.

11Rate Monotonic Scheduling și limita Liu-Layland11 min

Limita Liu-Layland coboara cu numarul de task-uri

Rate Monotonic Scheduling (RMS) e o strategie cu priorități fixe: cu cât perioada unui task e mai mică, cu atât prioritatea lui e mai mare (Tᵢ < Tⱼ ⟹ pᵢ > pⱼ). În ipotezele modelului clasic (task-uri periodice independente, procesor unic, planificare preemptivă, deadline = perioadă, costuri de kernel neglijabile), RMS este optim între algoritmii cu priorități fixe: dacă un set poate fi planificat prin orice atribuire de priorități fixe, poate fi planificat și prin Rate Monotonic.

Limita Liu-Layland
Pentru n task-uri, condiția suficientă: U ≤ n(2^(1/n) - 1). Pentru n → ∞: U_LL → ln 2 ≈ 69,3%.
Număr task-uriU_LL
1100,0%
282,8%
378,0%
475,7%
574,3%
∞69,3%
Suficientă, nu necesară Dacă U ≤ U_LL, setul e garantat schedulabil prin RMS. Dacă U > U_LL, testul e neconcludent - setul poate fi, în continuare, schedulabil (mai ales dacă perioadele sunt armonice - fiecare multiplu întreg al celor mai mici - caz în care RMS poate utiliza procesorul până aproape de 100%). 69,3% nu e o limită maximă universală pentru RMS, e doar pragul garantat de testul simplu.
Exercițiu rezolvat

τ1=(1,5,5), τ2=(2,10,10), τ3=(4,40,40). E setul garantat schedulabil prin RMS?

Vezi rezolvarea

U = 1/5 + 2/10 + 4/40 = 0,2 + 0,2 + 0,1 = 0,5

U_LL(3) = 3(2^(1/3) - 1) ≈ 0,780

Deoarece 0,5 < 0,780, setul este garantat schedulabil prin RMS, în ipotezele modelului clasic.

Simulator Rate Monotonic / EDF - Gantt interactiv

Experimentați crescând C₁ din widget până U depășește limita Liu-Layland pentru 3 task-uri (0,780) - urmăriți dacă τ3 (prioritatea cea mai mică) începe să rateze deadline-uri.

Testul de schedulabilitate Liu-Layland pentru trei task-uri periodice

12Earliest Deadline First10 min

Earliest Deadline First (EDF) folosește priorități dinamice: la fiecare moment de decizie, rulează task-ul Ready cu deadline-ul absolut cel mai apropiat - J* = argmin(dᵢ,ₖ). Prioritatea unui task se poate schimba de la o instanță la alta, pentru că deadline-urile absolute evoluează în timp.

Testul de schedulabilitate EDF
În modelul clasic (task-uri periodice independente, procesor unic, preempție, deadline = perioadă): setul e schedulabil prin EDF dacă și numai dacă U ≤ 1. EDF poate utiliza teoretic 100% din capacitatea procesorului pentru acest model - un avantaj net față de limita ~69,3% a RMS.
RMS sau EDF - potriviți afirmația cu algoritmul potrivit
Prețul flexibilității EDF EDF are administrare mai complexă (o coadă ordonată după deadline, nu priorități statice), comportament mai greu de urmărit în depanare, și degradare mai puțin intuitivă la suprasarcină: într-un sistem cu priorități fixe (RMS), task-urile de prioritate mare rămân protejate, iar cele de prioritate mică ratează deadline-uri; într-o suprasarcină EDF, mai multe task-uri pot rata deadline-uri simultan, inclusiv unele considerate „importante" - un comportament mai greu de anticipat și testat exhaustiv.

Condiția simplă U ≤ 1 nu e suficientă pentru toate variantele EDF - dacă deadline-urile sunt mai mici decât perioadele (D < T), e nevoie de o analiză mai fină a cererii de procesor pe intervale, dincolo de scopul acestui curs introductiv.

13Erori frecvente5 min

  • „Timp mediu de execuție bun înseamnă sistem de timp real corect." Fals - un sistem poate avea media excelentă și, totuși, rata ocazional deadline-uri critice. Analiza trebuie făcută pentru cazul cel mai nefavorabil, nu pentru medie. Cereți întotdeauna WCET (Worst-Case Execution Time), nu doar timp mediu măsurat.
  • „U ≤ U_LL(RMS) și U ≤ 1 (EDF) sunt condiții echivalente ca putere." Nu - U_LL e doar suficientă (conservatoare) pentru RMS; U ≤ 1 e necesară și suficientă pentru EDF, în modelul clasic. EDF poate schedula seturi pe care testul simplu RMS le respinge, deși ambele pot fi schedulabile prin RMS după o analiză mai fină. Nu comparați direct cele două praguri fără să precizați ce anume testează fiecare.
  • „Un task blocat într-un while(!condiție){} economisește complexitate față de folosirea unui semafor/mesaj." Așteptarea activă ține task-ul Ready/Running, consumând procesor inutil și putând bloca task-uri de prioritate egală sau mai mică - exact opusul intenției. Folosiți mecanismele de blocare oferite de RTOS (semafoare, cozi de mesaje, cu timeout) în loc de bucle de așteptare activă.

14Rezumat și glosar5 min

Corectitudinea temporală e la fel de importantă ca cea logică, iar garanțiile trebuie demonstrate pentru cazul cel mai nefavorabil, nu pentru medie. Un task se modelează prin (C, T, D, J), trece prin stările Running/Ready/Blocked/Suspended, iar comutarea de context are un cost real, măsurabil. Rate Monotonic Scheduling oferă priorități fixe simple, cu un test de schedulabilitate conservator (limita Liu-Layland, ~69,3% pentru multe task-uri); Earliest Deadline First oferă priorități dinamice, cu testul optim U ≤ 1, dar cu un comportament mai puțin predictibil la suprasarcină. Alegerea între ele e, ca mereu în acest domeniu, un compromis între simplitate/predictibilitate și utilizare maximă teoretică.

WCET
Worst-Case Execution Time - timpul de execuție în cazul cel mai nefavorabil.
Jitter
variația latenței între activări succesive ale aceleiași activități.
TCB
Task Control Block - structura care păstrează contextul unui task.
Hiperperioadă (H)
cmmmc al perioadelor - intervalul după care activările se repetă.
RMS
Rate Monotonic Scheduling - priorități fixe, invers proporționale cu perioada.
EDF
Earliest Deadline First - prioritate dinamică, după deadline-ul absolut.
Limita Liu-Layland
U_LL(n) = n(2^(1/n)-1) - test suficient pentru RMS.

15Întrebări de verificare6 min

  1. Care este diferența dintre corectitudinea logică și cea temporală a unui sistem?
  2. Enumerați componentele latenței end-to-end a unui lanț senzor-decizie-actuator.
  3. Care sunt cele patru stări principale ale unui task și tranzițiile dintre ele?
  4. De ce așteptarea activă (busy-waiting) e nerecomandată într-un task RTOS?
  5. Care este condiția de schedulabilitate suficientă (Liu-Layland) pentru RMS cu 4 task-uri?
  6. Ce înseamnă "priorități dinamice" în contextul EDF?
  7. De ce EDF poate utiliza teoretic 100% din procesor, spre deosebire de RMS?

16Direcții de aprofundare2 min

Cursul următor continuă direct pe acest fir: cum se sincronizează task-urile care partajează resurse (semafoare, mutex-uri), ce este inversiunea de prioritate și cum arată, la nivel de kernel, un RTOS real precum FreeRTOS sau Zephyr.

Toate conceptele din acest curs - stări de task, comutare de context, RMS, EDF - devin cod real, care rulează pe hardware, în Laboratorul 03, unde configurați un RTOS pe un ceas open-source cu PineTime și InfiniTime.