One: Kernel interrupt
The watchdog interrupt in the Linux kernel is similar to that of the previous bare board, and before writing the driver, it is necessary to cut out the Watch dog module that comes with the kernel, or else the error will occur; device Drivers/ Watchdog Timer support/s3c2410 watchdo
In the kernel, we handle an interrupt and must first register an interrupt number, and the function to register the interrupt is:
the int Long flags, 133 Const Char void *dev)134 {135 return request_ THREADED_IRQ (IRQ, Handler, NULL, flags, name, dev); 136 }
The IRQ is the hardware interrupt number to be requested .
Handler is an interrupt handler that is registered with the system and is a callback function that is called by the system when the interrupt occurs, and the dev parameter is passed to it.
Flags is the attribute of the interrupt processing, if irqf_disabled is set, the interrupt handler is a fast handler, the fast handler is called to block all interrupts, the slow handler is not masked, and if irqf_shared is set, it means that multiple devices share interrupts. If the irqf_sample_random is set, the system entropy contributes to the system to obtain a random number of benefits.
Name set break name , is usually name of the device driver you can see this name in the cat/proc/interrupts.
Dev is used when sharing is interrupted and is typically set to this setting device structure or null for the
REQUEST_IRQ () returns 0 for success, returns-inval to indicate that the break number is invalid or the handler pointer is null, and returns-EBUSY that the interrupt is already occupied and cannot be shared .
See if the interrupt has been registered successfully on the Development Board via cat/proc/interrupts:
The following code implementation is the key (Key1) control Dog,dog control Lights, the first time the button press the Light Flash, again press the light off
1#include <linux/init.h>2#include <linux/module.h>3#include <linux/io.h>4#include <linux/irq.h>5#include <linux/interrupt.h>6#include <linux/clk.h>7#include <linux/gpio.h>8 9Module_license ("GPL");TenModule_author ("Bunfly"); One AIrqreturn_t DO_IRQ (intIrqvoid*data); - voidled_on (); - voidLed_off (); the voidwt_on (); - voidWt_off (); - -UnsignedLongGpio_virt; +UnsignedLong*gpm4con, *Gpm4dat; -UnsignedLongWt_virt; +UnsignedLong*wtcon, *wtdat, *wtcnt, *Wtclrint; A structCLK *WTCLK; at intET_IRQ =0; - - intBunfly_init () - { - intRET =0; -ET_IRQ = Gpio_to_irq (EXYNOS4_GPX3 (2));//exint () Get External interrupt number inret = REQUEST_IRQ (ET_IRQ, DO_IRQ, irq_type_edge_falling,"Key 1",2222);//Register button Interrupt - if(Ret <0) {//Interrupt Number//processing Functions toPrintk"REQUEST_IRQ error\n"); + return 1; - } the *WTCLK = Clk_get (NULL,"watchdog");//set the clock frequency $ clk_enable (WTCLK);Panax Notoginsengret = REQUEST_IRQ (IRQ_WDT, DO_IRQ, irqf_shared,"Wangcai",2222);//Register watchdog interrupt - if(Ret <0) { thePrintk"request_irq\n"); + return 1; A } theGpio_virt = Ioremap (0x11000000, sz_4k);//Physical address of the led to the virtual address +Gpm4con = Gpio_virt +0x02e0; -Gpm4dat = Gpio_virt +0x02e4; $ $Wt_virt = Ioremap (0x10060000, sz_4k);//Physical Address of dog to virtual address -Wtcon = Wt_virt +0x00; -Wtdat = Wt_virt +0x04; thewtcnt = Wt_virt +0x08; -Wtclrint = Wt_virt +0x0c;Wuyi the - return 0; Wu } - About voidbunfly_exit () $ { -Printk"This is bunfly_exit\n"); - } - A Module_init (bunfly_init); + Module_exit (bunfly_exit); the -Irqreturn_t DO_IRQ (intIrqvoid*data) $ { the if(IRQ = = ET_IRQ) {//determine if the key is interrupted the Static intFlags =1; thePrintk"Key 1 down\n"); the if(flags) { - wt_on (); inFlags =0; the } the Else { About Wt_off (); the Led_off (); theFlags =1; the } + } - if(IRQ = = IRQ_WDT) {//determine if a dog is interrupted the*wtclrint =0;//Clear InterruptBayi Static intFlags =1; the if(flags) { the led_on (); -Flags =0; - } the Else { the Led_off (); theFlags =1; the } - } the the returnirq_handled;//Processing Complete the }94 the voidled_on () the { the*gpm4con &= ~0xFFFF; 98*gpm4con |=0x1111; About*gpm4dat =0x0; - }101 102 voidLed_off ()103 {104*gpm4con &= ~0xFFFF; the*gpm4con |=0x1111;106*gpm4dat =0xf;107 108 }109 the voidwt_on ()111 { the*wtdat =0x8000;113*wtcnt =0x8000; the*wtcon = (1<<2) | (0<<3) | (1<<5) | (168<<8); the } the 117 voidWt_off ()118 {119*wtcon =0; -}
Linux kernel interrupt watchdog