|
Gonilnik asinhronih zaporednih vrat
Besedilo vaje: Napišite gonilnik za asinhrona zaporedna vrata uart1. Gonilnik naj z ostalo programsko opremo komunicira preko dveh cikličnih medpomnilnikov. V sprejemni medpomnilnik naj zapisuje sprejete znake. Iz oddajnega medpomnilnika pa naj jemlje znake za oddajo.
Razlaga: Opravilo 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. Po končanem zagonu pristanemo v prazni funkciji start_up(), ki se nahaja v datoteki startup.c. Tu mikrokrmilnik in asinhrona zaporedna vrata uart1 inicializirate, kar naredite s klicem funkcij init() in uart1_init(). Za uporabo obeh funkcij morate vključiti datoteki init.h in uart.h. Za preizkus gonilnika potrebujete še dve pomožni opravili, čemur se bomo podrobneje posvetili v nadaljevanju. Operacijski sistem dvignete s klicem funkcije sch_on(). Pri tem določite tudi dolžino časovne rezine. Vsa opravila seveda navedete v seznamu opravil sch_tab[] v datoteki rtos_tasks.c, s pripadajočimi extern deklaracijami v datoteki rtos_tasks.h. Ne pozabite dodati tudi prazno priviligirano opravilo. Izvorno kodo vseh opravili napišete v datoteki main.c. Razlago delovanja in opis izvorne kode operacijskega sistema najdete v skripti. Gonilnik za asinhrona zaporedna vrata uart1, poimenujmo ga uart(), je funkcija, ki z ostalo programsko opremo komunicira le preko dveh medpomnilnikov. Da gonilnik lahko zadovoljivo poskrbi za asinhrona zaporedna vrata uart1, ga je potrebno klicati dovolj pogosto. Oziroma gonilnik je tipično opravilo z določeno frekvenco klicanja. Vsi znaki, ki prispejo preko asinhronih zaporednih vrat uart1, se znajdejo v sprejemnem medpomnilniku, znaki iz oddajnega medpomnilnika pa so avtomatsko oddani. Gonilnik ob vsakem klicu preveri, ali je prispel nov znak in ga prepiše na zadnje mesto v sprejemnem medpomnilniku. Če je medpomnilnik poln, potem sprejeti znak zavrže. Nato pogleda še v oddajni medpomnilnik. Če se tam nahaja kakšen znak, ga odda. Algoritem gonilnika je enostaven in ga prikazuje slika spodaj.
Sprejemni in oddajni medpomnilnik sta globalna ciklična medpomnilnika tipa FIFO (angl. First In First Out). Vsak izmed njiju je globalno polje znakov, čemur sta dodana še indeksa prvega znaka in prvega prostega mesta v polju. Več o cikličnih medpomnilnikih tipa FIFO najdete v skripti. Za preizkus gonilnika napišemo še dve pomožni opravili, s katerima realiziramo izpis na prikazovalniku LCD in oddajo sprejetih znakov nazaj (echo). Za izpis na prikazovalniku LCD lahko uporabimo že poznan gonilnik lcd_driver_1(), ali pa gonilnik lcd_driver_2(), ki smo ga napisali v prejšnji vaji. Manjka nam le opravilo, ki skrbi za pretok sprejetih znakov nazaj v oddajo in v niz za prikaz na prikazovalniku LCD. Vsak znak iz sprejemnega medpomnilnika prepiše v oddajni medpomnilnik in hkrati tudi na ustrezno mesto v nizu, na katerega kaže globalni kazalec lcd_string. Algoritem pomožnega opravila prikazuje slika spodaj.
Glavni program je prazna neskončna zanka, saj pomožni opravili postorita vse potrebno. | |