First we should include the header file <linux/interrupt.h>
To deal with interrupts we use two functions:
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int irq, void *dev_id),
unsigned long flags,
const char *dev_name,
void *dev_id);
void free_irq(unsigned int irq, void *dev_id);
The first function will return 0 if it succeed, or a negative value for fail.
- irq: it's the IRQ number
- handler: is the function that the kernel will call to deal with the requested IRQ
- flags: SA_INTERRUPT for fast interrupt handler, SA_SHIRQ for shared interrupt handler, IRQF_DISABLED flag specifies that this interrupt handler has to be treated as a fast handler, so the kernel has to disable interrupts while invoking the handler, IRQF_TRIGGER_RISING announces a rising-edge interrupt, IRQF_TRIGGER_HIGH for level-sensitive interrupt
- dev_name: this string will be visible form /proc/interrupts
- dev_id: if the interrupt is not shared, it can be set to NULL
int init_module()
{
/*
* Since the keyboard handler won't co-exist with another handler,
* such as us, we have to disable it (free its IRQ) before we do
* anything. Since we don't know where it is, there's no way to
* reinstate it later - so the computer will have to be rebooted
* when we're done.
*/
free_irq(1, NULL);
/*
* Request IRQ 1, the keyboard IRQ, to go to our irq_handler.
* SA_SHIRQ means we're willing to have othe handlers on this IRQ.
* SA_INTERRUPT can be used to make the handler into a fast interrupt.
*/
return request_irq(1, /* The number of the keyboard IRQ on PCs */
irq_handler, /* our handler */
SA_SHIRQ,
"keyboard_irq_handler",
(void *)(irq_handler));
}
void cleanup_module()
{
/*
* This is only here for completeness. It's totally irrelevant, since
* we don't have a way to restore the normal keyboard interrupt so the
* computer is completely useless and has to be rebooted.
*/
free_irq(1, NULL);
}
/*
* This function services keyboard interrupts. It reads the relevant
* information from the keyboard.
*/
irqreturn_t irq_handler(int irq, void *dev_id)
{
unsigned char scancode;
unsigned char status;
/*
* Read keyboard status
*/
status = inb(0x64);
scancode = inb(0x60);
printk(KERN_INFO "Scan Code %x %s.\n",
(int)*((char *)scancode) & 0x7F,* This function services keyboard interrupts. It reads the relevant
* information from the keyboard.
*/
irqreturn_t irq_handler(int irq, void *dev_id)
{
unsigned char scancode;
unsigned char status;
/*
* Read keyboard status
*/
status = inb(0x64);
scancode = inb(0x60);
printk(KERN_INFO "Scan Code %x %s.\n",
*((char *)scancode) & 0x80 ? "Released" : "Pressed");
return IRQ_HANDLED;
}
Now to enable/disable interrupts, we use respectively enable_irq(unsigned int irq_number) and disable_irq(unisigned int irq_number).
No comments:
Post a Comment