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.
- 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
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
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.
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.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.
T_end-to-end = T_senzor + T_achiziție + T_comunicație + T_așteptare +
T_calcul + T_actuatorD_control = D_senzor + D_transfer + D_software + D_actuator + marjă.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ță.
„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ă:
τᵢ = (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.
| Termen | Semnificație |
|---|---|
| Determinism | garanția că sistemul respectă o limită temporală cunoscută, nu doar "de obicei" |
| Latență | timpul dintre un eveniment și reacția sistemului la el |
| Jitter | variația latenței între activări succesive ale aceleiași activități |
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:
- Kernel - miezul care gestionează task-urile, memoria și sincronizarea; oferă primitivele de bază (creare task, semafoare, cozi de mesaje, timere).
- Scheduler - decide care task rulează, la fiecare moment de decizie, pe baza politicii de planificare (subiectul central al acestui curs).
- Dispatcher - execută efectiv comutarea de context, aplicând decizia scheduler-ului: salvează contextul task-ului curent, restaurează contextul noului task, reia execuția.
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.
| Stare | Semnificație |
|---|---|
| Running | task-ul execută instrucțiuni pe procesor (cel mult unul, pe un singur nucleu) |
| Ready | pregătit să ruleze, dar procesorul e ocupat de alt task |
| Blocked | așteaptă un eveniment (mesaj, semafor, date, timer, resursă) |
| Suspended | exclus 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.
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.
U_switch = N_switch × C_switch / TUn 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.
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.
| Strategie | Principiu | Potrivită pentru |
|---|---|---|
| Planificare pe priorități (fixe) | task-ul Ready cu cea mai mare prioritate rulează | sisteme cu criticitate diferențiată clar |
| Round Robin | task-urile de aceeași prioritate rotesc, fiecare cu un time-slice fix | echitate î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ᵢ.
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
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.
U ≤ n(2^(1/n) - 1). Pentru n → ∞: U_LL → ln 2 ≈ 69,3%.| Număr task-uri | U_LL |
|---|---|
| 1 | 100,0% |
| 2 | 82,8% |
| 3 | 78,0% |
| 4 | 75,7% |
| 5 | 74,3% |
| ∞ | 69,3% |
τ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.
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.
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.
U ≤ 1.
EDF poate utiliza teoretic 100% din capacitatea procesorului pentru acest model - un
avantaj net față de limita ~69,3% a RMS.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ă.
15Întrebări de verificare6 min
- Care este diferența dintre corectitudinea logică și cea temporală a unui sistem?
- Enumerați componentele latenței end-to-end a unui lanț senzor-decizie-actuator.
- Care sunt cele patru stări principale ale unui task și tranzițiile dintre ele?
- De ce așteptarea activă (busy-waiting) e nerecomandată într-un task RTOS?
- Care este condiția de schedulabilitate suficientă (Liu-Layland) pentru RMS cu 4 task-uri?
- Ce înseamnă "priorități dinamice" în contextul EDF?
- 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.