LAB3: Obrada prekida prema prioritetu


Zadatak

Prilagoditi prekidni podsustav tako da se prekidi obrađuju prema prioritetu – svakom prekidnom broju pridijeliti prioritet identičan prekidnom broju. Obzirom da će se koristiti simulirani prekidi s prekidnim brojevima 49-58, prekide s manjim brojevima obrađivati kao i do sada (uvijek ih prihvatiti i obraditi, neka imaju najveći prioritet).

Iznimno, da pojedini zahtjev ne čeka predugo, obraditi i zahtjeve nižeg prioriteta prije njihova reda ako ima takvih da su u redu predugo – u međuvremenu je obrađeno barem četiri druga zahtjeva (simuliranih) prije njih.

Koristiti sklopovske prekide da pored "svoje" operacije još simuliraju pojavu novih.

Moguća ideja

Postojećim prekidima (irq ≤ 48) dati velike prioritete (npr. irq+100) da se uvijek prihvate i obrade (oni se i ne preklapaju). Koristiti serijsku vezu kao izvor prekida (ili tipkovnicu). Svaki put kad se pročita neki znak (stisnuti broj), njega u upravljačkom programu postaviti i u dodatnu varijablu (npr. u funkciji uart_read pročitani znak staviti i u varijablu irq_prio, pretpostaviti da je broj: irq_prio = up->inbuff[up->inl] - '0'). Na kraju obrade prekida prije povratka u prekinuto, pogledati je li u toj varijabli ima nešto. Ako ima onda iz toga generirati prioritet novog zahtjeva i obrisati tu varijablu.
Navedeno je već ostvareno u primjerima koji ostvaruju vrlo sličan zadatak od 2024/2025.

Ideja prihvata prekida bi bila:

do_sada_započeto_simuliranih_prekida = 0 //brojač

dodaj_zahtjeve(irq_num)
{
	za sve ihndlr registrirane za irq_num
		zahtjev = kmalloc...
		zahtjev.handler = ihndlr
		zahtjev.prio = (irq_num ≤ 48? irq_num + 100; irq_num)
		zahtjev.u_obradi = laž
		zahtjev.brojac = do_sada_započeto_simuliranih_prekida
		...
		dodaj 'zahtjev' u 'listu zahtjeva uređenu prema prioritetu (zahtjev.prio)
}

funkcija_za_prihvat_prekida(irq_num)
{
	dodaj_zahtjeve(irq_num)

	prvi = prvi zahtjev iz 'liste zahtjeva' ili onaj koji predugo čeka
	dok je prvi != NULL i prvi.u_obradi == laž
	{
		prvi.u_obradi = istina

		ako je zahtjev.prio > 48
			do_sada_započeto_simuliranih_prekida++

		dozvoli prekidanje
		obradi 'prvi' (pozovi prvi.handler.ihandler(...))
		zabrani prekidanje


		makni 'prvi' iz liste

		//simulacija novih zahtjeva nakon obrade prekida serije
		ako je irq_prio > 0 { //postavlja se u obradi serije
			dodaj_zahtjeve(irq_prio + 49) //da budu 49-58 kad se stisne 0-9
			irq_prio = 0
		}
		prvi = prvi zahtjev iz liste zahtjeva ili onaj koji predugo čeka
	}
}
Varijablu irq_prio se može deklarirati u interrupts.c a prije njenog korištenja iz uart.c u funkciji uart_read samo ju označiti da postoji s extern int irq_prio;

Primjer programa koji ispituje rad prioritetnog prekidnog sustava je u datoteci interrupts.c.