(tutorial) Exemple Java Real Time [628059]

5. Studiu de caz
5.1. Laborator 1 – Introducerea in Java Real Time
5.1.1. Scopul laboratorului
Scopul acestui laborator consta in familiarizarea cu limbajul de programare Java si mediul de
dezvoltare asociat, Eclipse.
5.1.2. Introducere
Java este un limbaj de programare orientat pe obiect, de nivel inalt si unul dintre cele mai
populare limbaje de programare in uz. Este folosit, in special, pentru aplicatiile Android, fiind
preferat si pentru dezvoltare Internet of Things. Fiind un limbaj orientat pe obiect, acesta ofera
suport pentru majoritatea conceptelor programarii orientate pe obiecte (de exemplu: constuc-
tori, destructori, mostenire(un singur parinte), etc)
Java imprumuta o parte mare din sintaxa de la limbajele C si C++, avand insa un model al
obiectelor foarte mult simplificat, facandu-l mult mai usor de folosit. Spre deosebire de C,unde
codul sursa este compilat in cod masina, codul sursa al unei aplicatii Java este compilat intr-o
forma binara generica numita bytecode ce poate fi rulat pe orice platforma ce suporta masina
virtuala Java ( Java Virtual M achine – JVM ), indiferent de arhitectura computerului, nefi-
ind necesara recompilarea pentru fiecare platforma. Implementarea JVM este numita Java
Runtime Environment( JRE ) sau mediu de rulare Java, ce contine un set de biblioteci si alte
utilitare necesare construirii unei aplicatii Java. Acesta poate fi distribuit separat sau impreuna
cu un pachet de dezvoltare Java, Java Development Kit ( JDK .
In acest laborator vom folosi JamaicaVM ca implementare a unui JDK. JamaicaVM im-
plementeaza Specificatia Java pentru Timp Real ( Real Time Specification for Java – R TSJ ) si
un colector de spatiu liber ( Garbage collector – GC ) deterministic. Cum alocarea si dealocarea
memoriei fac parte din principalele cauze ale erorilor ce pot aparea in timpul rularii unei apli-
catii, GC elibereaza automat memoria ocupata de variabilele nefolosite.
19

Capitolul 5. Studiu de caz
Specificatia Java pentru Timp-Real imbunatateste Specificatia Java in sase moduri:
1. Adauga fire de executie de timp real. Planificarea firelor de executie de timp real este mult
mai bine definita decat cea a firelor de executie Java standard.
2. Adauga tool-uri si mecanisme ce ajuta programatorii sa scrie cod Java fara a avea nevoie
de colectarea de spatiu liber.
3. Adauga clasa AsyncEventHandler si un mecanism ce asociaza evenimentele asincrone
cu ce se intampla in afara JVM .
4. Adauga un mecanism ce permite programatorului sa controleze unde vor fi alocate obiectele
in memorie.
5. Adauga un mecanism ce permite programatorului sa acceseze memoria la anumite adrese.
De asemena, este important de stiut ca R TSJ lasa anumite lucruri neschimbate. Progra-
mele Java standard pot sa ruleze pe o implementare a R TSJ. Mai mult, acestea pot chiar sa
ruleze cat timp JVM executa un cod de timp real.
5.1.3. Mediul integrat de dezvoltare Eclipse
Eclipse este un mediu integrat de dezvoltare ( Integrated Development Environment ( IDE )
folosit in programarea informatica, in special folosit pentru a dezvolta aplicatii Java, deoarece
simplifica acest proces prin furnizarea unei interfete grafice usor de folosit si a unor actiuni
predefinite.
Observatie: Pentru instalarea si configurarea pachetului Eclipse precum si a modulelor
JRE si JDK se va consulta tutorialul de instalare!
Creare proiect nou – Java in timp real
Pentru ca JamaicaVM sa mearga este necesar ca executabilul aicasLicenseProvider sa ruleze in
terminal si nu trebuie oprit pana cand utilizarea JamaicaVM nu se incheie. In Figura. 5.1 este
prezentat un exemplu de rulare a executabilui aicasLicenseProvider . La un moment dat, acesta
va cere o cheie pentru a putea fi activat, Figura. 5.2 . Aceasta cheie va fi primita pe mail dupa
ce va fi completat un formular de pe site-ul https://www.aicas.com/ .
Important: este necesara o conexiune la internet!
Pentru a crea un proiect Java nou, se vor urmarii urmatorii pasi: File -> New -> Java
Project si va aparea fereastra din Figura. 5.3 .
Se va alege un nume pentru proiect si versiunea JRE-ului ce va fi folosita pentru rularea
aplicatiei. Pentru a putea folosi JamaicaVM trebuie ales JRE-ul jamaica-8.1-1 , ca in Figura. 5.3 .
Dupa care se va apasa pe Finish , proiectul salvandu-se, astfel, in W orkspace . Acesta este folder-
ul ce trebuie specificat atunci cand Eclipse este pornit.
20

Capitolul 5. Studiu de caz
Figura 5.1. :Rularea licentei aicas
Figura 5.2. :Cheie de activare
Pentru a putea rula aplicatia, este necesara crearea unei clase, ca in Figura. 5.4 . Dupa aceasta,
va aparea o fereastra unde se va alege numele clasei, dupa care se va apasa butonul de Finish si
clasa va fi creata.
Orice aplicatie Java trebuie sa aiba o clasa principala. Aceasta este cea care va fi executata
prima data.
Pentru a se verifica daca configurarea este functionala se poate adauga urmatorul program.
Daca ruleaza, inseamna ca pasii au fost indepliniti. Daca apar erori se reiau pasii din tutorialul
de instalare.
importjavax.realtime.*;
publicclassHelloRT {
publicstaticvoidmain(String [] args){
//Initializarea unuinoufirdeexecutie detimpreal
RealtimeThread rt= newRealtimeThread(){
//Adaugare functionalitate
publicvoidrun() {
System.out.println( "HelloRealTimeWorld!!");
21

Capitolul 5. Studiu de caz
Figura 5.3. :Creearea unui nou proiect Java
}
};
//Pornire firdeexecutie detimpreal
rt.start();
}
}
Executie si Debug
Eclipse IDE ofera doua butoane pentru rularea si depanarea unei aplicatii, Figura. 5.5 . Astfel,
daca se doreste ,de exemplu specificarea parametrilor de intrare, cele doua butoane ofera optiuni
in acest sens.
Pentru setarea unui breakpoint se apasa click dreapta in stanga liniei dorite si apoi T oggle
Breakpoint sau dublu-click in acelasi loc.
22

Capitolul 5. Studiu de caz
Figura 5.4. :Creearea unei clase
In timpul rularii aplicatiei, prin View-ul Console se poate interactiona cu aceasta. De exemplu
in Figura. 5.6 , aplicatia cere un integer , de la tastatura se da un numar, iar acesta apare in
Console , se apasa Enter si, astfel, datele de intrare au fost introduse.
Figura 5.5. :Butoanele de rulare si depanare
Pentru depanare, se apasa butonul de Debug din Figura. 5.5 . Eclipse va intreba daca se
doreste schimbarea in perspectiva de Debug . Se va apasa Y es . Dupa aceea, Eclipse va schimba
23

Capitolul 5. Studiu de caz
Figura 5.6. :Interactionarea cu aplicatia prin View-ul Console
perspectiva in cea din Figura. 5.7 . Aici apar mai multe View-uri: Console , cel pentru codul
sursa, Debug ,Breakpoints ,V ariables .
Figura 5.7. :Perspectiva de Debug
5.1.4. Citirea si Scrierea
Pentru citire se foloseste stream-ul System.in . Acesta permite citirea informatiilor de la tasta-
tura. In schimb pentru scriere, se foloseste System.out .
In continuare va fi prezentat un exemplu de citire al unui integer folosind un fir de executie
de timp real.
importjavax.realtime.*;
importjava.util.*;
publicclassCitireRT {
publicstaticvoidmain(String [] args){
RealtimeThread rt = newRealtimeThread(){
publicvoidrun() {
System.out.println( "Insertintnumber:");
intx = 1;
Scanner scanner = newScanner(System.in);
x = scanner.nextInt();
System.out.println( "Thenumberis:");
System.out.println(x);
}
};
if(!rt.getScheduler().isFeasible())
System.out.println( "Reading andPrinting intisnotfeasible ");
else
24

Capitolul 5. Studiu de caz
rt.start();
}
}
In Figura. 5.6 se poate observa rezultatul citirii si scrierii.
5.1.5. T ablouri si matrici
Un tablou unidimensional este o colectie de elemente de acelasi tip (numit tipul de baza al ta-
bloului), ce ocupa un spatiu continuu de memorie.
Pentru declararea unui tablou unidimensional se foloseste notatia: tip []nume; . Numerota-
rea elementelor unui tablou incepe de la 0. Pentru crearea propriu-zisa a tabloului se foloseste
notatia nume = new tip[numar-elem] .
Pentru declararea unui tablou multi-dimensional se foloseste notatia: tip [][][]…[]nume; .
In exemplul urmator este prezentata citirea unui tablou bi-dimensional (matrice) in care se
foloseste un fir de executie de timp real.
importjavax.realtime.*;
importjava.util.*;
publicclassCitireRT2 {
intx;
private voidReadInt()
{
System.out.println( "Insertintnumber:");
Scanner scanner = newScanner(System.in);
x = scanner.nextInt();
}
publicintGetInt()
{
ReadInt();
returnx;
}
}
//altaclasa
importjavax.realtime.*;
importjava.util.*;
publicclassMatrice {
publicstaticvoidmain(String [] args){
RealtimeThread realTime = newRealtimeThread(){
publicvoidrun() {
System.out.println( "Insertintnumberforcolumns:");
intx;
Scanner scanner = newScanner(System.in);
25

Capitolul 5. Studiu de caz
x = scanner.nextInt();
System.out.println( "Insertintnumberforrows:");
inty;
y = scanner.nextInt();
int[][]a = newint[x][y];
for(inti=0;i<x;i++)
{
for(intj=0;j<y;j++)
{
CitireRT2 citire = newCitireRT2();
a[i][j] = citire.GetInt();
}
}
System.out.println( "Thenumberis:");
for(inti=0;i<x;i++)
{
for(intj=0;j<y;j++)
{
System.out.print( "");
System.out.print(a[i][j]);
}
System.out.println();
}
}
};
if(!realTime.getScheduler().isFeasible())
System.out.println( "Reading andPrinting intisnotfeasible ");
else
realTime.start();
}
}
In Figura. 5.8 se poate observa rezultatul citirii, iar in Figura. 5.9 cel al scrierii.
Figura 5.8. :Citirea de la tastatura a unei matrici
26

Capitolul 5. Studiu de caz
Figura 5.9. :Scrierea in terminal al rezultatului
5.1.6. Bibliografie
• Dragoicea M., Sisteme in timp real. Dezvoltare pe baza de model, Editura Universitara,
Bucuresti, Romania, 370 pag, ISBN 978-973-749-924-0, 2010
• Peter C. Dibble, Real Time Java Platform Programming, Sun Microsystems Press, 352
pag, 2002
• Peter C. Dibble, Real Time Java Platform Programming: Second Edition, 2008
• James J. Hunt, Realtime and Embedded Specification for Java, V ersion 2.0, Switchback
Railway Edition, 2017
• https://www.aicas.com
5.2. Laborator 2 – Fire de executie de timp real
5.2.1. Scopul laboratorului
Scopul acestui laborator este prezentarea conceptului si modul de utilizare al unui fir de executie
de timp real (realtime thread).
5.2.2. Introducere
In mod normal, Java ofera o clasa Thread pentru modelul sau de tasking. T ask-urile pot fi
rulate simultan prin crearea de fire de executie multiple, dar acestea nu ofera o semantica de
programare in timp real. Pentru aceasta, Specificatia Java pentru Timp Real (R TSJ) ofera clasa
RealtimeThread .
Clasa RealtimeThread prevede crearea de fire de executie de timp real, acestea sunt mai
bine definite decat java.lang.Thread si ,de asemenea, crearea de fire de executie de timp real
fara nicio dependenta de heap .
Clasa RealtimeThread mosteneste java.lang.Thread . Obiectele ReleaseParameters ,Sche-
dulingParameters si MemoryParameters ce pot fi transmise constructorului Realtime-
Thread furnizeaza configuratia temporala si procesoare a firului de executie ce trebuie comu-
nicata la planificator ( scheduler ) – un modul ce gestioneaza executia task-urilor si detecteaza
ratarile deadline-urilor si monitorizarea costurilor..
27

Capitolul 5. Studiu de caz
A vand in vedere ca RealtimeThread mosteneste java.lang.Thread , firele de executie de timp
real pot fi folosite ori de cate ori un fir de executie este necesar, dar multe din caracteristicile
R TSJ sunt disponibile doar pentru firele de executie de timp real:
• Firele de executie de timp real au o gama mai larga de prioritati (pe langa cele 10 ale
firelor de executie Java standard)
• Memorie scoped
• Planificare periodica
T oate firele de executie de timp real au prioritati mai mari decat cele standard, astfel firele de
executie de timp real vor fi planificate inaintea celor standard.
5.2.3. Clasa RealtimeThread
T oate firele de executie de timp real sunt lansate in executie utilizand clasa RealtimeThread .
Mai jos este descris procesul de mostenire, regasim interfetele pe care aceasta le implementeaza,
precum si sublcasele cunoscute.
Mostenire :java.lang.Object -> java.lang.Thread -> RealtimeThread .
Interfete :javax.realtime.Schedulable ,javax.realtime.Runnable .
Sublcase :NoHeapRealtimeThreads
Clasa RealtimeThread mosteneste clasa Thread si adauga accesul la serviciile de timp real..
Crearea unui fir de executie de timp real
Exista doua moduri de a crea un RealtimeThread .
• Se creeaza o clasa noua ce mosteneste clasa RealtimeThread si se supradefineste ( Over-
ride ) metoda run() .
• Se creeaza o instanta a clasei RealtimeThread folosind unul dintre constructori cu un
parametru logic . Metoda run() a obiectului Runnable implementeaza logica firului de
executie.
In continuare este prezentat clasicul program Hel lo world folosind un fir de executie de
timp real:
importjavax.realtime.*;
publicclassHelloRT {
publicstaticvoidmain(String [] args){
//Initializarea unuinoufirdeexecutie detimpreal
RealtimeThread rt= newRealtimeThread(){
//Adaugare functionalitate
publicvoidrun() {
28

Capitolul 5. Studiu de caz
System.out.println( "HelloRealTimeWorld!!");
}
};
//Pornire firdeexecutie detimpreal
rt.start();
}
}
Constructori
Mai jos sunt enumerati constructorii clasei RealtimeThread :
publicRealtimeThread(SchedulingParameters scheduling,
ReleaseParameters release,
MemoryParameters memory,
MemoryArea area,
ConfigurationParameters config,
TimeDipsatcher dispatcher,
RealtimeThreadGroup group, //sauProcessingGroupParameters
Runnable logic)
Se creaza un fir de executie in timp real cu caracteristici date si cu Runnable specificat.
Daca parametrul group al noului fir de exectutie creat nu este setat, acesta este mostenit din
task-ul parinte. In timpul executiei constructorului, firul de executie nou creat este asociat cu
planificatorul in efect.
Acest constructor este echivalent cu RealtimeThread(scheduling, release, memory, area, config,
dispatcher, group, logic) . In cazul in care unul dintre parametrii nu este definit, in constructorul
echivalent, parametrul este nul l .
publicRealtimeThread()
Daca niciun parametru nu este definit, acestia vor lua valorile implicite, iar constructorul va fi
echivalent cu RealtimeThread(null, null, null, null, null, null, null, null) . Pentru valorile
nul l ale parametrilor, se creaza un fir cu urmatoarele valori:
• SchedulingParameters -NORM PRIORITY
• ReleaseParameters – Nu exista acesti parametrii. Firul de executie nu este periodic,
astfel nu se poate evalua daca firul de executie este eligibil pentru planificare.
• MemoryParameters – Alocarea memoriei nu este restrictionata
• MemoryArea – Memoria va fi alocata in heap
• RealtimeThreadGroup /ProcessingGroupParameters – firul de executie nu face parte
din niciun grup de fire.
• Runnable – metoda run() a obiectului.
29

Capitolul 5. Studiu de caz
Metode
publicstaticjavax.realtime.RealtimeThread currentRealtimeThread()
throwsClassCastException
Metoda returneaza o referinta catre instanta actuala a RealtimeThread .
publicstaticjava.realtime.RealtimeThread currentSchedulable()
throwsClassCastException
Metoda returneaza o referinta catre instanta actuala a Schedulable .
publicvoidstart()
throwsIllegalRealtimeStateException
Metoda este utilizata pentru lansarea in executie a unui nou fir de executie creat si se utilizeaza
o singura data in ciclul de viata al unui fir. Aceasta metoda apeleaza metoda run() .
publicstaticvoidsleep(HighResolutionTime time)
throwsInterruptedException,
ClassCastException,
IllegalRealtimeArgumentException
Aceasta este o metoda sleep() controlata de un ceas generalizat. A vand in vedere ca timpul
este exprimat ca fiind HighResolutionTime , metoda are un cronometru cu o acuratete foarte
mare, de ordinul nanosecundelor. Timpul de sleep , poate fi relativ sau absolut. Daca este
relativ, atunci firul de executie ce apeleaza metoda este blocat pentru o perioada de timp ce este
data de parametrul time , fiind masurat de clock (o implementare a clasei Clock ). Atunci cand
timpul este absolut, firul de executie ce apeleaza functia este blocat pana cand valoarea indicata
este atinsa de clock . Cand valoarea indicata este mai mica sau egala decat cea a clock -ului,
atunci functia returneaza imediat.
Parametru time reprezinta perioada de timp pe care firul trebuie sa o ”doarma” sau momentul
la care sa se ”trezeasca” .
publicstaticvoidsuspend(HighResolutionTime time)
throwsClassCastException,
IllegalRealtimeArgumentException
Diferenta dintre aceasta metoda si metoda sleep(HighResolutionTime time) este ca aceasta
nu poate fi intrerupta.
publicfinalvoidawaken()
30

Capitolul 5. Studiu de caz
F olosind infrastructura clasei Clock , metoda forteaza fuctia sleep sa returneze.
publicjavax.realtime.Scheduler getScheduler()
Metoda returneaza o referinta la obiectul Scheduler .
publicjavax.realtime.RealtimeThread setScheduler(Scheduler scheduler,
SchedulingParameters scheduling,
ReleaseParameters release,
MemoryParameters memory)
Metoda returneaza referinta this . Cu exceptia parametrului scheduler , ceilalti parametrii pot
finull .
publicvoidrelease()
Metoda genereaza o eliberare a acestui RealtimeThread .
publicstaticboolean waitForNextRelease()
throwsIllegalRealtimeStateException,
ClassCastException
Provoaca o intarziere firului de timp real curent pana la urmatoarea eliberare (vezi release() .
Cata vreme firul de executie nu isi rateaza deadline-ul, fiecare apel la aceasta functie blocheaza
firul pana la urmatoarea eliberare.
publicfinalvoidfire()
F olosind infrastructura clasei Clock , metoda forteaza fuctia waitF orNextRelease sa retur-
neze.
De asemenea, exista si metode mostenite din clasele java.lang.Thread sijava.lang.Object si
interfata java.lang.Runnable .
publicvoidrun()
Este principala metoda a acestei clase. Interfata Runnable declara metoda o singura data, iar
clasa T read o implementeaza. Metoda trebuie sa contina toate activitatile pe care firul trebuie
sa le execute.
publicvoidsetPriority( intnewPriority)
31

Capitolul 5. Studiu de caz
F unctia schimba prioritatea firului de executie.
publicvoidjoin()
Metoda se utilizeaza pentru legarea firelor de executie. Daca metoda nu are parametrii, atunci
se asteapta terminarea firului (indeferent de timp) pentru ca celalalt fir sa poata utiliza date din
primul, dar daca se pune un parametru, join(long milis) , atunci se asteapta atat cat indica
parametrul (in milisecunde).
Starile unui fir de executie
Un fir de executie poate exista doar intr-una din starile urmatoare: new, runnable, running,
blocked, suspeded, suspendedblocked, dead . La aparitia unor evenimente variate, acestea
trec de la o stare la alta.
• Starea new
RealtimeThread rt = newRealtimetThread();
Firul de executie de timp real intra in starea new .
• Starea Runnable
rt.start();
Firul de executie de timp real intra in starea runnable , acesta fiind alocat unei cozi
round-robin , organizata de JVM .
• Starea Running Un fir de executie de timp real este in starea running atunci cand se
executa. La apelul functiei yield() , acesta este trece in starea runnable .
• Starea Suspended
rt.suspend();
Un fir de executie de timp real poate trece in starea suspended , doar daca se afla intr-
un din starile running sau runnable . Pentru a trece din starea suspended in starea
runnable , se apeleaza metoda rt.resume() .
In continuare este prezentata trecerea intre stari a unui fir de executie in functie de metoda
apelata, Figura. 5.10 .
Urmatorul exemplu, arata un fir de executie de timp real ce are specificati toti parametrii,
mai putin ProcessingGroupParameters .
importjavax.realtime.*;
publicclassConstructor {
publicstaticvoidmain(String [] args){
32

Capitolul 5. Studiu de caz
Figura 5.10. :Diagrama de trecere intre stari ale firelor de executie
SchedulingParameters scheduling = newPriorityParameters(
PriorityScheduler.getMinPriority( null) + 14);
ReleaseParameters release =
newAperiodicParameters( null,null,null,null);
MemoryParameters memory =
newMemoryParameters(MemoryParameters.NO_MAX, //Heap
0); //Immortal memory
MemoryArea area = HeapMemory.instance();
ProcessingGroupParameters group = null;
Runnable logic = newRT();//clasatrebuie creata
RealtimeThread rt= newRealtimeThread(scheduling,
release,
memory,
area, group,
logic);
rt.start();
try{
rt.join();
}catch(Exception e){};
}
}
5.2.4. Bibliografie
• Dragoicea M., Sisteme in timp real. Dezvoltare pe baza de model, Editura Universitara,
Bucuresti, Romania, 370 pag, ISBN 978-973-749-924-0, 2010
• Peter C. Dibble, Real Time Java Platform Programming, Sun Microsystems Press, 352
pag, 2002
33

Capitolul 5. Studiu de caz
• Peter C. Dibble, Real Time Java Platform Programming: Second Edition, 2008
• James J. Hunt, Realtime and Embedded Specification for Java, V ersion 2.0, Switchback
Railway Edition, 2017
5.3. Laborator 3 – Fire de executie de timp real,
Planificare/Scheduling si Sincronizare
5.3.1. Scopul laboratorului
Scopul acestui laborator este prezentarea conceptului si modul de utilizare al unui fir de executie
de timp real (realtime thread). De asemenea, in acest laborator se vor prezenta firele de executie
periodice.
Planificarea firelor de executie este o parte cheie ce diferentiaza o implementare Java stan-
dard de o implementare Java de timp real. A vand in vedere ca implementarile Java standard
se bazeaza pe un tip de planificare, o implementare Java de timp real trebuie sa furnizeze un
planificator de timp real. Pentru un planificator de timp real, cel mai important lucru este sa
asigure ca task-urile critice se vor termina la timp.
Planificatorul necesar R TSJ este preemptiv cu prioritati fixe (cel putin 28 de nivele unice pe
langa cele 10 predefinite). Este reprezentat de clasa FirstInFirstOutScheduler , o subclasa a
PriorityScheduler , si este numit planificator de baza . Acesta ruleaza fiecare fir de executie
pana la completare, cat timp un fir de executie cu prioritate mai mare nu devine eligibil pentru
rulare. Intr-un astfel de caz, firul de executie curent este preemptat de cel cu prioritate mai mare.
Interfata Schedulable include clasele RealtimeThread si AsyncBaseEventHandler , pre-
cum si subclasele acestora.
Planificatorul are multe caracteristici ce sunt placute de catre programatorii de timp real:
• Sunt cel putin 28 de prioritati. R TSJ necesita cel putin 28 de prioritati, dar foloseste toti
cei 32 de biti ai unui integer pentru a reprezenta prioritatile.
• T ask-urile cu prioritati mai mari vor rula intotdeauna inaintea celor cu prioritati mai mici.
• Lacatele ( Lock ) aplicate firelor de executie de timp real folosesc intotdeauna mecanismul
de evitare a inversiarii de prioritate.
Unul dintre punctele forte ale limbajului Java este suportul pentru multi-threading. Aceasta
necesita sincronizare. R TSJ ofera clase aditionale ce gestioneaza sincronizarea. Clasa Moni-
torControl este definita ca o superclasa pentru toti algoritmii de control al eligibilitatii de
executie. Doua dintre subclasele clasei MonitorControl sunt considerate ca cele mai comune
mecanisme pentru evitarea inversiunii prioritatii: PriorityInheritance (protocolul priority
inheritance sau protocolul de mostenire de prioritate) si PriorityCeilingEmulation ( proto-
colul priority ceiling emulation sau protocolul de plafonare de prioritate).
Protocolul priority inheritance , este comportamentul implicit pentru toate obiectele synchro-
nized . Daca un fir de executie f 1detine un lacat, iar alt fir de executie cu prioritate mai mare,
f2, incearca sa il dobandeasca, prioritatea lui f 1este ridicata la cea a lui f 2, cat timp f 1detine
lacatul. Figura. 5.11 .
34

Capitolul 5. Studiu de caz
Figura 5.11. :priority inheritance
In cazul protocolului priority ceiling emulation , plafonul trebuie sa fie setat la o prioritate cel
putin la fel de mare cu cea mai mare prioritate dintre cele ale firelor de executie ce incearca sa
acceseze o resursa, de preferat ar fi sa fie chiar mai mare. Aceasta strategie face analiza sa fie
mai usoara, avand in vedere ca orice fir de executie ce acceseaza o resursa va rula fara sa fie
preemptat, pana ce va elibera resursa respectiva. Figura. 5.12 .
Figura 5.12. :priority ceiling emulation
In urmatorul exemplu, se modifica protocolul de marire a prioritatii pentru un obiect.
importjavax.realtime.*;
publicclassppp1 {
staticPriorityCeilingEmulation pce =
PriorityCeilingEmulation.instance(
PriorityScheduler.getMaxPriority( null) – 5);
publicsynchronized intfoo(){
return1;
}
publicstaticvoidmain(String [] args){
pce1 obj = newppp1();
//SetPCEprotocol forjustoneobject
MonitorControl.setMonitorControl(obj, pce);
35

Capitolul 5. Studiu de caz
System.out.println(obj.foo());
}
}
In urmatorul exemplu, se modifica protocolul implicit de marire a prioritatii.
importjavax.realtime.*;
publicclassppp2 {
staticPriorityCeilingEmulation pce =
PriorityCeilingEmulation.instance(
PriorityScheduler.getMaxPriority( null) – 6);
publicstaticvoidmain(String [] args){
MonitorControl.setMonitorControl(pce);
}
}
Utilizarea unui plafon global de prioritate poate fi adecvata pentru o aplicatie ce foloseste sin-
cronizarea rar. In programele Java multi-thread nu se foloseste protocolul deoarece, firele de
executie vor rula la prioritate maxima o perioada mare de timp.
Firele de executie pot sa isi schimbe propria prioritate, sau sa schimbe prioritatea altor fire
de executie.
In exemplul urmator se va schimba prioritatea unui fir de executie, modificand prioritatea obiec-
tului PriorityParameters .
importjavax.realtime.*;
publicclassSchimbarep implements Runnable {
publicvoidrun() {
RealtimeThread rt = RealtimeThread.currentRealtimeThread();
intPi;
PriorityParameters priority;
priority = (PriorityParameters)rt.getSchedulingParameters();
Pi =priority.getPriority();
System.out.println( "Initial priority ="+ Pi);
priority.setPriority(Pi+1);
System.out.println( "Newpriority ="+ priority.getPriority());
}
}
Daca programatorul alege sa refoloseasca obiectul PriorityParameters pentru mai multe fire
de executie, modificarea prioritatii acelui obiect, va modifica la randul ei, toate firele de executie
ce folosesc obiectul respectiv. Daca este facuta intentionat, acest lucru poate deveni un avantaj.
5.3.2. Fire de executie periodice
Chiar daca planificatorul implicit este preemptiv cu prioritate-fixata, R TSJ include servicii de
planificare periodica in planificatorul bazat pe prioritati implicit.
Firele de executie periodice au o structura standard. Majoritatea caracteristicilor de scheduling
ale unui fir periodic sunt trecute constructorului prin ReleaseParameters sau se pot face in
RealtimeThread .
36

Capitolul 5. Studiu de caz
5.3.3. Clasa PeriodicParameters
Clasa PeriodicParameters mosteneste clasa ReleaseParameters .
publicclassPeriodicParameters extends ReleaseParameters {
publicPeriodicParameters ( HighResolutionTime start,
RelativeTime period, RelativeTime cost ,
RelativeTime deadline ,
RelativeTime blockingTerm ,
AsyncEventHandler overrunHandler ,
AsyncEventHandler missHandler );
publicRelativeTime getPeriod ();
publicvoidsetPeriod ( RelativeTime period );
//functii deset()siget()
}
publicclassPeriodic extends RealtimeThread {
publicPeriodic(PeriodicParameters per) {
//cod
}
publicboolean run() {
boolean deadlineImplinit = true;
while(deadlineImplinit) {
//codcetrebuie rulatlafiecare perioada
deadlineImplinit = waitForNextPeriod();
}
}
PeriodicParameters folosesc valori HighResolutionTime pentru perioade si timpul de in-
ceput. Dat fiind acest fapt, valorile au o acuratete foarte mare, de ordinul nanosecundelor.
In continuare va fi prezentat programul Hel lo W orld! , dar folosind fire de executie periodice.
importjavax.realtime.*;
publicclassPeriodicHello extends RealtimeThread {
PeriodicHello(PeriodicParameters periodic){
super(null, periodic);
}
publicvoidrun(){
for(inti = 0; i < 100; ++i){
System.out.println( "HelloRealTimeworld!!");
waitForNextPeriod();
}
}
publicstaticvoidmain(String [] args){
PeriodicParameters periodic = newPeriodicParameters( newRelativeTime(1000, 0));
PeriodicHello rt = newPeriodicHello ( periodic);
rt.start();
try{
rt.join();
}catch(InterruptedException e){
}
}
}
37

Capitolul 5. Studiu de caz
5.3.4. Bibliografie
• Dragoicea M., Sisteme in timp real. Dezvoltare pe baza de model, Editura Universitara,
Bucuresti, Romania, 370 pag, ISBN 978-973-749-924-0, 2010
• Peter C. Dibble, Real Time Java Platform Programming, Sun Microsystems Press, 352
pag, 2002
• Peter C. Dibble, Real Time Java Platform Programming: Second Edition, 2008
• James J. Hunt, Realtime and Embedded Specification for Java, V ersion 2.0, Switchback
Railway Edition, 2017
5.4. Laborator 4 – Timpul
5.4.1. Scopul laboratorului
Scopul acestui laborator este introducerea claselor si metodelor ce permit utilizarea timpului in
aplicatii.
5.4.2. Clasa HighResolutionTime
Sistemele in timp real trebuie sa fie capabile sa manipuleze atat perioade faorte scurte de timp,
cat si perioade foarte lungi. De asemenea, trebuie sa se faca o distinctie intre timp relativ si
timp absolut. Simpla folosire a unei primitive cu o valoare integrala, precum int sau long , nu
ofera aria necesara. In schimb valorile primitivelor float sau double nu ofera precizia necesara.
Astfel, R TSJ, ofera clasa HighResolutionTime cu subclasele acesteia AbsoluteTime siRe-
lativeTime .
Instante ale clasei HighResolutionTime nu pot fi create, deoarece aceasta exista doar pentru
ca celelalte doua clase sa aiba o clasa-parinte comuna. O instanta a clasei RelativeTime in-
capsuleaza un punct in timp care este relativ fata de o alta valoare absoluta de timp, ce poate
fi folosita pentru a descrie o perioada de timp.
Clase
Clasa AbsoluteTime este un obiect ce reprezinta un punct specifica in timp reprezentat in
milisecunde si nanosecunde fixat de Chronograph . V aloarea implicita este ”January 1, 1970,
00:00:00 GMT” si este numita Epoca . Aceasta reprezentare o fost proiectata in ideea de a fi
compatibila cu reprezentarea Java standard a unui timp absolut data de clasa java.util.Date .
publicAbsoluteTime( longmilis,intnanos,
Chronograph chronograph)
throwsIllegalRealtimeArgumentException
38

Capitolul 5. Studiu de caz
Constructorul creaza un obiect AbsoluteTime . V aloarea instantei AbsolutTime este data
de parametrul milis plus parametrul nanos . Asocierea cu cronograful este dat de parametrul
cronograph . Cand acesta este null , asocierea este facuta cu ceasul de timp real implicit.
• milis – V aloarea dorita a componentei in milisecunde a referintei this . V aloarea actuala
este rezultatul normalizarii parametrului.
• nanos – V aloarea dorita a componentei in nanosecunde a referintei this . V aloarea actuala
este rezultatul normalizarii parametrului.
• chronograph – Ofera referinta de timp pentru obiectul nou construit. Daca argumentul
este null , se ca folosi ceasul de timp real.
Clasa RelativeTime este un obiect ce reprezinta un interval de timp de:
milisecunde
103+nanosecunde
109
In general este folosita pentru a reprezenta un timp relativ fata de momentul actual.
publicAbsoluteTime( longmilis,intnanos,
Chronograph chronograph)
throwsIllegalRealtimeArgumentException
Metode
publicjavax.realtime.AbsoluteTime
absolute(Chronograph chronograph)
Converteste timpul referintei this intr-un timp absolut, folosind instanta data a Chronograph
ce determina timpul curent, atunci cand este necesar. Daca Chronograph este null se va
utiliza ceasul de timp real.
publicjavax.realtime.RelativeTime
relative(Chronograph chronograph)
Converteste timpul referintei this intr-un timp relativ, folosind instanta data a Chronograph
ce determina timpul curent, atunci cand este necesar. Daca Chronograph este null se va
utiliza ceasul de timp real.
publicjavax.realtime.RelativeTime //sauAbsoluteTime
add(longmilis,intnanos)
throwsArithmeticException
39

Capitolul 5. Studiu de caz
Creaza un obiect RelativeTime sau AbsoluteTime ce reprezinta rezultatul normalizat al
adunarii valorilor milis sinanos la cele din this .
In cazul functiei substract() , se scad valorile.
publicjavax.realtime.RelativeTime
scale(intfactor)
F unctia multiplica perioada relativa de timp de factor ori.
publicjavax.lang.Strin
toStrin()
F unctia returneaza un obiect String ce reprezinta timpul dat de referinta this . Sirul de caractere
va fi formatat dupa cum urmeaza ”(4512 ms, 892000 ns)” .
Concluzii
Timpul este esenta sistemelor de timp real si o metode ce exprima timpul absolut cu o precizie
sub ordinul milisecundelor este o cerinta minima necesara.
Clasa java.util.Data standard foloseste milisecundele ca unitate de baza pentru a putea oferi
o arie suficienta pentru diferite aplicatii. Programarea in timp real are nevoie de mai mult,
nanosecundele sunt indeajuns pentru majoritatea scopurilor, dar chiar si un ceas de timp real
de 64 de biti bazat pe nanosecunde ar putea avea o arie insuficienta in anumite situatii. In
acest sens a fost ales un format compus din 64 de biti pentru milisecunde si 32 de biti pentru
nanosecunde.
5.4.3. Clocks and Timers
Pentru a putea rationa in legatura cu notiunea de timp, R TSJ are nevoie nu doar sa fie capabila
sa exprime timpul si sa faca calcule cu acesta, dar trebui sa fie capabila si sa determine timpul
curent si sa permita anumitor actiuni sa fie efectuate cand un anumit punct in timp a fost
atins. In acest sens, R TSJ, defineste o interfata si patru clase: Chronograph ,Clock ,Timer ,
PeriodicaTimer siOneShotTimer .
Un cronograf este folosit pentru a masura timpul, in timp ce un ceas nu numai ca masoara
timpul, dar este capabil si sa reactioneze la trecerea lui (poate declansa evenimente). Cel putin
o instanta a clasei Clock , ce implementeaza interfata Chronograph , este furnizata de R TSJ .
Aceasta este ceasul de timp real al sistemului. Exista doar un astfel de ceas intr-un sistem.
Clasele Timer ofera un mod de a executa codul la punct special in timp sau repetat intr-
un interval dat. Clasa Timer este o clasa abstracta si doar subclasele acesteia pot fi instantiate.
Instantele claselor OneShotTimer siPeriodicTimer pot fi create si replanificate specificand
timpul de start initial. Acesta poate fi AbsoluteTime sau RelativeTime .
40

Capitolul 5. Studiu de caz
Atasand un AsyncBaseEventHandler unui Timer , programul poate provoca eliberarea ruti-
nei de tratare a evenimentelor la un moment dat sau dupa o perioada de timp data. O instanta
a clasei OneShotTimer descrie un eveniment care urmeaza sa fie declansat cel putin o data.
Poate fi folosit ca sursa pentru time-out-uri sau cronometre de supraveghere. O instanta a clasei
PeriodicTimer fires un schedule periodic. Perioada unui PeriodicTimer este intotdeauna
specificata ca fiind de tipul RelativeTime .
In Figura. 5.13 sunt prezentate starile unui Timer .
Figura 5.13. :Starile unui Timer
Interfete
publicinterface AsyncTimable
Un tip comun pentru clasele Timer siRealtimeThread ce arata ca aceste clase pot fi asociate
cu Clock si eliberate de evenimente de timp ale acelui ceas.
In continuare este prezentata metoda fire() .
publicvoidfire()
41

Capitolul 5. Studiu de caz
F unctia este apelata de dipsatcher -ul asociat referintei this ce indica faptul ca un eveniment de
timp a aparut.
publicinterface Chronograph
Este o interfata pentru toate dispozitivele ce suporta masuratori de timp de mare acuratete.
In continuare va fi prezentata metoda getTime() .
publicjavax.realtime.AbsoluteTime
getTime()
F unctia determina timpul curent.
publicinterface Timable
Este o interfata pentru toate clasele ce folosesc Clock pentru cronometrare.
Clase
Clasa abstracta Clock .
Un ceas marcheaza trecerea timpului. Conceptul de ”acum” poate fi dterminat de metoda
Clock.getTime() . A se nota ca toate implementarile clasei Clock folosesc reprezentari ale
timpului derivate din clasa HighResolutionTime . Acesta este exprimata in milisecunde si
nanosecunde.
Constructorul clasei este: public Clock() .
In continuare vor fi prezentae cateva metode ale acestei clase.
publicstaticjavax.realtime.Clock
getRealtimeClock()
In orice moment, este cel putin un obiect ceas disponibil. ceasul de timp real al sistemului.
F unctia returneaza doar o instanta a Clock -ului implicit.
publicstaticvoid
setRealtimeClock(Clock clock)
Seteaza ceasul de timp real implicit al sisitemului.
42

Capitolul 5. Studiu de caz
publicfinaljavax.realtime.AbsoluteTime
getTime()
F unctia deterima timpul curent.
Clasa OneShotTimer
publicOneShotTimer(HighResolutionTime time,
TimeDispatcher dipatcher)
throws
IllegalRealtimeArgumentException,
UnsupportedRealtimeOperationException,
IllegalAssignmentError
Constructoul creaza o instanta a clasei OneShotTimer , bazat pe un clock dat ce va executa
metoda fire() conform parametrului time dat.
Clasa PeriodicTimer
publicPeriodicTimer(HighResolutionTime start,
RealtiveTimer interval,
TimeDispatcher dipatcher)
throws
IllegalRealtimeArgumentException,
UnsupportedRealtimeOperationException,
IllegalAssignmentError
Constructorul creaza un cronometru ce isi executa metoda fire() periodic.
Parametrul start semnifica timpul la care primul interval incepe. Parametrul interval semnifica
perioada cronometrului, daca acesta este null sau zero comportamentul va fi cel al OneShot-
Timer .
Concluzii
Ceasurile difera prin monotonicitate, sincronizare, acuratete, stabilitate, precizie etc.
Majoritatea sistemelor au un ceas de bord, ce este prevazut ca fiind ceasul implicit al siste-
mului de operare. Acest ceas poate fi folosit ca fiind ceasul implicit pentru R TSJ, dar acesta
nu este destul de stabil sau de precis pentru anumite aplicatii. De aceea, R TSJ furnizeaza un
al doilea ceas, un ceas de timp real, bazat pe un ceas sursa extern ce poate oferi acuratetea si
stabilitatea dorita.
5.4.4. Bibliografie
• Dragoicea M., Sisteme in timp real. Dezvoltare pe baza de model, Editura Universitara,
Bucuresti, Romania, 370 pag, ISBN 978-973-749-924-0, 2010
• Peter C. Dibble, Real Time Java Platform Programming, Sun Microsystems Press, 352
pag, 2002
• Peter C. Dibble, Real Time Java Platform Programming: Second Edition, 2008
43

Capitolul 5. Studiu de caz
• James J. Hunt, Realtime and Embedded Specification for Java, V ersion 2.0, Switchback
Railway Edition, 2017
5.5. Laborator 5 – Evenimente Asincrone
5.5.1. Scopul laboratorului
Scopul acestui laborator este introducerea conceptului de eveniment asincron si introducerea
claselor si metodelor ce permit utilizarea in aplicatii a acestuia.
5.5.2. Evenimente asincrone
R TSJ ofera un mecanism ce leaga executia unui program logic de aparitia evenimentelor interne
si externe. O aplicatie poate defini un task ce este executat de fiecare data ce este apelata
metoda fire() a unui eveniment. In acest sens, R TSJ ofera doua clase AsyncBaseEvent (AE)
siAsyncBaseEventHandler (AEH), impreuna cu subclasele acestora. Un AE este un obiect
folosit cu scopul de a directiona aparita evenimentelor catre rutina de tratare a evenimentelor
asincrone. O aparitie a unui eveniment poate fi initiata de mecanismul intern al implementarii
R TSJ prin apelarea functiei fire() a AE sau prin input extern (de exemplu, un ceas, o intreru-
pere, un semnal). In Figura. 5.14 este prezentat un eveniment asincron, iar in Figura. 5.15 , un
eveniment sincron pentru comparatie.
Figura 5.14. :Eveniment Asincron
Figura 5.15. :Eveniment Sincron
44

Capitolul 5. Studiu de caz
5.5.3. Interfete
Interfata ActiveEvent este ce care defineste sistemul de evenimente ative. Clasele ce imple-
menteaza aceasta interfata sunt folosite sa conecteze evenimentele ce au loc in afara JVM cu
activitatile R TSJ. Cand un astfel de eveniment are loc, se executa o anumita secventa de cod din
JVM. Aceasta secventa anunta interfata ca a avut loc evenimentul apeland metoda trigger() .
Metode
publicboolean isActive()
F unctia determina daca un eveniment a inceput, dar nu sa sfarsit inca. Returneaza true cand
evenimentul este activ si false in caz contrar.
publicvoidstart()
throwsIllegalRealtimeStaeException
F unctia porneste un eveniment ce este activ.
publicvoidstop()
throwsIllegalRealtimeStaeException
F unctia opreste un eveniment ce este activ.
5.5.4. Clase
Clasa AsyncBaseEvent este clasa de baza pentru toate evenimentele asincrone, cu privire la
codul ce ruleaza in acel moment si nu la timpul extern. Aceasta clasa uneste AsyncEvent cu
AsyncLongEvent siAsyncObjectEvent .
In continuare vor fi prezentate cateva metode ale clasei:
publicboolean isRunning()
F unctia determina daca un eveniment este activat sau dezactivat. Returneaza true atunci cand
este activat si false in caz contrar.
publicboolean handledBy(AsyncBaseEventHandler handler)
F unctia determina daca un handler dat ca parametru este asociat referintei this . Daca este,
functia returneaza true , daca nu este asociat sau cand handler este null , functia returneaza
false .
45

Capitolul 5. Studiu de caz
publicvoidenable() //sidisable()
F unctiile schimba starea unui eveniment, astfel handler -ii asociati sunt eliberati, respectiv sariti
la momentul apelarii metodei fire() .
publicvoidaddHandler(AsyncBaseEventHandler handler) //setHandler (),removeHandler ()
F unctia adauga un handler la setul de handler -i asociati evenimentului ( adauga un handler si ii
sterge pe restul / sterge toti handler -ii). O instanta a AsyncBaseEvent poate avea mai multi
handler -i asociati.
Clasa AsyncEventHandler – obiectele acestei clase se conecteaza cu unul sau mai multe obiecte
ale clasei AsyncEvent prin intermerdiul metodelor addHandler() sau setHandler() . Me-
toda fire() a clasei AsyncEvent , atunci cand este activata, elibereaza evenimentele asincrone
asociate unei instante a AsyncEvent . Daca nu sunt handler -i atasati, functia nu face nimic.
O rutina de tratare a evenimentelor asincrone are cinci faze.
• JRE-ul porneste obiectul schedulable in care handler -ul va rula.
• Rutina de tratare a evenimentelor asincrone se pregateste sa trateze un eveniment.
• Rutina de tratare a evenimentelor asincrone trateaza evenimentul.
• Rutina de tratare a evenimentelor asincrone aisncron proceseaza curatarea.
• JRE-ul opreste obiectul schedulable .
Infrastructura clasei AsyncEventHandler verifica de cate ori metoda fire() a fost ape-
lata ( fireCount ). Daca numarul este mai mare decat zero, atunci contorul este incrementat de
fiecare data cand functia este apelata. Daca contorul este zero, atunci contorul este incrementat
sievent handler -ul este pornit.
Constructorul clasei AsyncEventHandler :
public
AsyncEventHandler(SchedulingParameters scheduling,
ReleaseParameters release,
MemoryParameters memory,
MemoryArea area,
ReleaseRunner runner,
Runnable logic)
In continuare vor fi prezentate cateva metode ale acestei clase:
publicvoidhandleAsyncEvent()
Aceasta metoda mentine logica ce trebuie executata atunci cand este apelata metoda fire() a
unui AsyncEvent asociat handler -ului. Cat timp fireCount -ul este mai mare decat zero, aceasta
46

Capitolul 5. Studiu de caz
metoda va fi invocata periodic.
publicfinalvoidrun()
Aceasta functie este folosita doar de catre infrastructura, nu va fi niciodata apelata de aplicatie.
protected intgetPendingFireCount()
F unctia returneaza valoarea detinuta de fireCount .
protected intgetAndDecrementPendingFireCount()
F unctia decrementeaza valoarea detinuta de fireCount cu 1. F unctia returneaza valoarea deti-
nuta de fireCount inainte de decrementare.
In continuare este prezentat un exemplu de event handling asincron pentru un semnal UNIX.
importjavax.realtime.*;
classSigHandler extends AsyncEventHandler {
publicvoidhandleAsyncEvent() {
intpending = getPendingFireCount();
do{
if(pending > 1)
System.out.println( "Semnal."+ pending + "inasteptare ");
else
System.out.println( "Semnal");
}while((pending = getAndDecrementPendingFireCount()) > 0);
}
}
Clasa SigHandler este o subclasa a AsyncEventHandler .
5.5.5. Bibliografie
• Dragoicea M., Sisteme in timp real. Dezvoltare pe baza de model, Editura Universitara,
Bucuresti, Romania, 370 pag, ISBN 978-973-749-924-0, 2010
• Peter C. Dibble, Real Time Java Platform Programming, Sun Microsystems Press, 352
pag, 2002
• Peter C. Dibble, Real Time Java Platform Programming: Second Edition, 2008
• James J. Hunt, Realtime and Embedded Specification for Java, V ersion 2.0, Switchback
Railway Edition, 2017
47

Similar Posts