Øvelse+6+-+Interrupts

=Generelle overvejelser= toc I init skal den ligge til sidst i koden, da de forskellige gpio først skal initialiseres. ?????????????????
 * Hvor skal request_irq ligges (init / open)?**
 * Hvor skal værdien af gpio’en læses (ISR / read)?**

Vi bruger **rmmod** og **insmod** til at fjerne eller tilføje et modul til kernen, disse er også brugt i tidligere opgaver.
 * dmesg**: Er en kommando der udskriver hvad der ligger i af kernen.
 * cat /proc/stat**: Skriver forskellig informationer omkring kernel aktivitet.
 * cat /proc/interrupts**: Viser hvilke IRQ(interrupt) linjer der bruges og hvilken device der bruger dem.

Følgende bibliotek skal inkluderes for at gøre brug af interrupt routiner. code format="c" code =Implementer Interrupt request/free= I Init-funktionen requester vi et interrupt code format="c" IRQ = gpio_to_irq(gpio[0].num); printk(KERN_ALERT "Interrupt, IRQ: %i\n", IRQ); code Der laves en global variabel IRQ, hvor vi lagre en værdi som fås af funktioen gpio_to_irc Dernæst skrives Interrupt med efterfølgende værdi!
 * 1) include 

I Exit-funktionen bliver interrupted løssluppet.(free_irq) Nedenstående funktionen er prototypen for free_irq. code format="c" void free_irq(unsigned int irq, void *dev_id); code Første argument fortæller, hvilket interrupt nummer der bliver requested. Andet argument er en pointer til "shared interrupts". Hvis dev_id ikke bliver shared. Kan dette sættes til NULL. Værdien som bliver returneret af funktionen er 0, hvis request på interrupted er en succes. Hvis en anden driver allerede har requested interrupted, returnere funktionen en nagativ fejlkode, typisk -EBUSY. code format="c" free_irq(IRQ, NULL); code Vi bruger den globale variabel IRQ og NULL som argumenter. NULL benytter vi da der ikke forekommer shared interrupts.

=**Implementer ISR**= Her bliver der oprettet en interrupt rutine, som skal udskrive "IRQ event"! Variablen "flag" er sat globalt til "0". I interruptrutinen sættes flaget til "1" og vente køen = wq som erklæres globalt vækkes fra reader-funktionen! For at tjekke om dette sker korrekt, laver vi en printf, som udskriver at Interrupt (IRQ=290) biver vækket. code format="c" irqreturn_t MyISR(int irq, void *dev_id, struct pt_regs *regs) {   printk(KERN_ALERT "MyISR Interrupt\n"); printk(KERN_DEBUG "process --> %i <-- awakening the readers...\n", IRQ); flag = 1; wake_up_interruptible(&wq); return IRQ_HANDLED; } code Funktionen request_irq er en funktion som returnere 0 eller -BUSY. Hvis funktionen returnere 0, er alt gået som planlagt. Hvis der sker en fejl, returnere funktionen -EBUSY, som er en fejlkode som ligger i  code format="c" // tilsidst i init requester vi request_irq(IRQ, MyISR, IRQF_TRIGGER_RISING, "GPIO_0", NULL); code Herefter fjernes det gamle modul fra kerne og det nye indsættes!

=**Implementer ”read”**= code format="c" printk(KERN_DEBUG "process --> %i <-- going to sleep\n", IRQ); wait_event_interruptible(wq, flag != 0); flag = 0; printk(KERN_DEBUG "awoken --> %i <--\n", IRQ); code I dette kodeudsnit bliver der udskrevet via en printk at interrupted falder i søvn. wait_event_interruptible funktionen vækker (wq=vente-køen) så snart falg er forskelligt fra 0, altså 1. Derefter sættes flag til 0 igen, da det er muligt der kan komme et ny interrupt. Til sidste benytter vi endnu en prinfk funktionen til at vise at reader-interrupt nu er blevet vækket.