Asistent

Osnove
mikroprocesorskih
sistemov


Ra�unalni�ko
na�rtovanje vezij II


Mikroprocesorji
v elektroniki
  Laboratorijske vaje
    Programiranje v zbirniku
Zbirni�ka funkcija
Zapis s plavajo�o vejico
Digitalna ura
Generator vlaka
impulzov

Gonilnik
prikazovalnika LCD

Gonilnik asinhronih
zaporednih vrat

Uporaba operacijskega
sistema v realnem �asu

English

Realizacija digitalne ure z operacijskim sistemom v realnem �asu

Besedilo vaje: V danem preprostem operacijskem sistemu, ki te�e v realnem �asu, sprogramirajte digitalno uro. Trenuten �as (ure:minute:sekunde) naj se izpisuje na prikazovalniku LCD. Za nastavljanje uporabite tipke T0 do T3. Pritisk na tipko T0 naj pove�a �tevilo ur, na tipko T1 pa �tevilo minut. Tipka T2 naj uro ustavi, medtem ko tipka T3 postavi �as ni ni� (00:00:00).

Razlaga: Program napi�ete v razvojnem okolju, ki te�e na osebnem ra�unalniku. Pripravljen delovni prostor (angl. workspace) z vsemi pripadajo�imi datotekami najdete tukaj. V njem se poleg nastavitev projekta nahajajo tudi datoteke s spremljajo�o izvorno kodo. Poleg �e znanih datotek, sta dodani �e datoteki rtos.c in pripadajo�a rtos.h, kjer se nahaja koda preprostega operacijskega sistema, ki te�e v realnem �asu.

Po kon�anem zagonu pristanemo v prazni funkciji start_up(), ki se nahaja v datoteki startup.c. Tu boste mikrokrmilnik inicializirali, kar naredite s klicem funkcije init(). Za njeno uporabo morate vklju�iti datoteko init.h. Nato boste s klicem funkcije sch_on() dvignili operacijski sistem, �emur bomo ve� besed namenili na koncu te razlage. Razlago delovanja in opis izvorne kode operacijskega sistema najdete v skripti.

Vajo bomo realizirali s pomo�jo opravil, ki jih bo ob vnaprej dolo�enih trenutkih klical mehanizem operacijskega sistema. Nalogo razdelimo na manj�e dele. Za izvedbo digitalne ure moramo izmeriti, oziroma dolo�iti trenuten �as, nato izmerjeno vrednost preoblikovati v primeren niz za prikaz in nazadnje pripravljen niz �e prikazati na prikazovalniku LCD. Pri dolo�anju trenutnega �asa upo�tevamo tudi pritisnjene tipke T0 do T3, ki slu�ijo nastavljanju ure. Glede na povedano lahko nalogo naredimo s tremi opravili, ki jih poimenujmo:

   - tim() ... opravilo za nastavljanje in merjenje, oziroma �tetje �asa,
- string() ... opravilo, ki vrednost �asa preoblikuje v niz za prikaz, in
- lcd_driver_1() ... opravilo, ki pripravljen niz prika�e na prikazovalniku LCD.

Opravilo tim() meri in nastavlja trenutni �as. �as izrazimo z globalno spremenljivko time, ki podaja �tevilo sekund. Primer: ob 08:14:59 je time = 8 * 60 * 60 + 14 * 60 + 59 = 29699. Katerokoli drugo opravilo, ali glavni program lahko v vsakem trenutku "pogleda", koliko je ura. Da bo ura to�na, mora biti opravilo tim() klicano v ekvidistantnih �asovnih intervalih, za kar poskrbi operacijski sistem. Ker na�e opravilo �teje sekunde, je najprimerneje, �e je klicano enkrat na sekundo. Algoritem opravila tim() podaja slika spodaj.

Ob vsakem klicu (enkrat na sekundo) se vrednost spremenljivke time pove�a za ena. Hkrati od�itamo stanje tipk T0 do T3, kar se ustrezno odrazi v vrednosti spremenljivke time. T0 pove�a �tevilo ur, oziroma pove�a time za 3600. Podobno T1 pove�a �tevilo minut, oziroma pove�a time za 60. Tipka T2 spremenljivko time zmanj�a za ena, kar pomeni, da se njena vrednost pravzaprav ne spremeni. �as stoji. Tipka T3 postavi time = 0. Opravilo tim() skrbi tudi za prehod opolno�i iz 23:59:59 (= 86399 sekund) na 00:00:00.

Naslednje opravilo string() prebere vrednost spremenljivke time in to pretvori v niz tipa "hh:mm:ss". Pravzaprav opravilo string() z dodajanjem presledkov pripravi 32-znakovni niz za prikaz na prikazovalniku LCD, na katerega ka�e globalni kazalec lcd_string. Opravili tim() in string() sta med seboj neodvisni. Prvo skrbi, da je v spremenljivki time vedno pravi �as, drugo pa ta podatek uporablja. Algoritem opravila string() je enostaven in ga prikazuje slika spodaj. �tevilo ur, minut in sekund dobimo iz spremenljivke time s celo�tevilskim deljenjem in z deljenjem po modulu.

Zadnje opravilo, oziroma funkcijo za izpis na prikazovalnik LCD, lcd_driver_1() �e poznamo iz laboratorijskih vaj pri predmetu Ra�unalni�ko na�rtovanje vezij II. Funkcijo sedaj uvrstimo med opravila. To pomeni, da je ne kli�emo ve� eksplicitno, ampak za to poskrbi operacijski sistem. Funkcija tako predstavlja gonilnik za prikazovalnik LCD, ki nenehno prikazuje trenutno vsebino niza, na katerega ka�e globalni kazalec lcd_string. Frekvenca osve�evanja prikazovalnika je podana s pogostnostjo klicanja funkcije lcd_driver_1(), kar dolo�imo z nastavitvami operacijskega sistema. �e ho�emo spremeniti vsebino na prikazovalniku LCD, moramo le spremeniti niz, na katerega ka�e kazalec lcd_string. To v na�i vaji po�ne opravilo string().

Ker smo vse postorili s pomo�jo opisanih treh opravil, je glavni program le prazna neskon�na zanka.

V na�em preprostem operacijskem sistemu so opravila funkcije, ki ne vzamejo nobenega argumenta in ni�esar ne vra�ajo. Da tak�na funkcija postane opravilo, jo moramo navesti v seznamu opravil sch_tab[], ki se nahaja v datoteki rtos_tasks.c. Ker se izvorna koda opravil ne nahaja v isti datoteki kot izvorna koda operacijskega sistema, potrebujemo za vsako opravilo �e tako imenovano deklaracijo extern, ki se nahaja v datoteki rtos_tasks.h. Za opisana tri opravila tim(), string() in lcd_driver_1() bi seznam opravil sch_tab[] v datoteki rtos_tasks.c s pripadajo�imi deklaracijami extern v datoteki rtos_tasks.h izgledal takole:

rtos_tasks.h:

 extern void tim();
 extern void string();
 extern void lcd_driver_1();

rtos_tasks.c:

 voidfuncptr sch_tab[] = {tim, string, lcd_driver_1};

Izvorno kodo opravil napi�ite v datoteki main.c.

Operacijski sistem dvignemo s klicem funkcije sch_on(), ki smo jo �e omenili. Za uporabo funkcije morate vklju�iti datoteko rtos.h. Deklaracija funkcije sch_on() je naslednja:

  void sch_on(unsigned int slice);

Iz argumenta slice se izra�unajo nastavitve �asovnika timer0, ki ga operacijski sistem izkori��a za merjenje �asa. Pomen argumenta je slede�:

   - slice ... dol�ina �asovne rezine mikrosekundah

S klicem funkcije sch_on() postane operacijski sistem aktiven in pri�ne s klicanjem opravil. Pogostnost klicev je podana z dol�ino �asovne rezine, ki smo jo dolo�ili z argumentom slice. V na�i vaji imamo zaenkrat tri opravila, pri �emer zahtevamo, da je opravilo tim() klicano to�no enkrat na sekundo. Temu primerno bi �asovna rezina morala biti enaka 1/3 sekunde, kar pa ni cela �tevilka (= 1000000/3us). Zato v seznam opravil sch_tab dodamo �e prazno opravilo void_task(), ki je prilo�eno v datoteki main.c. Sedaj imamo �tiri opravila, zato je dol�ina �asovne rezine enaka 1/4 sekunde (= 250000us).

In �e v razmislek. Kaj bi morali narediti, da bi dvopi�ja v nizu "hh:mm:ss" utripala na vsake pol sekunde?