📄 isr_task.c
字号:
/* isr_task.c Shows how to set up an interrupt service routine. This example uses the parallel port interrupt. To generate interrupts, short pin 10 of the parallel port connector to ground (pins 18-25). The ISR increments a cumulative interrupt count, and writes this to a FIFO that is read and printed on the user process side. */#include <linux/kernel.h>#include <linux/module.h>#include <linux/version.h>#include <linux/sched.h>#include <asm/io.h>#include "rtai.h"#include "rtai_sched.h"#include "rtai_fifos.h"#include "isr_common.h" /* FIFO_NUM, FIFO_INTS *//* THIS SOFTWARE WAS PRODUCED BY EMPLOYEES OF THE U.S. GOVERNMENT AS PART OF THEIR OFFICIAL DUTIES AND IS IN THE PUBLIC DOMAIN. When linked into the Linux kernel the resulting work is GPL. You are free to use this work under other licenses if you wish.*/#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0)MODULE_LICENSE("GPL");#endifstatic int interrupts = 0; /* how many interrupts we've serviced */#define FIFO_INTS 1000 /* how many integers to queue */#define PARPORT_BASE_ADDRESS 0x378#define PARPORT_IRQ 7static void disable_parport_int(void){ /* clear bit 4 of the parallel port control register, two bytes up from the base address */ outb(inb(PARPORT_BASE_ADDRESS+2) & ~0x10, PARPORT_BASE_ADDRESS+2);}static void enable_parport_int(void){ /* set bit 4 of the parallel port control register, two bytes up from the base address */ outb(inb(PARPORT_BASE_ADDRESS+2) | 0x10, PARPORT_BASE_ADDRESS+2);}/* This simple ISR just increments the cumulative count of interrupts serviced so far, and write this integer to the fifo. The interrupt source is not periodic, since they are generated by a person touching two wires together, and they can be quite bursty as the wires are brought close together. We need to disable the physical source of interrupts while we are manipulating the fifo, otherwise the fifo code will be re-entered and cause problems. */static void isr_code(void){ /* turn off physical interrupts while we're servicing this one, so we don't re-enter this code */ disable_parport_int(); /* now we do our work */ interrupts++; rtf_put(0, &interrupts, sizeof(interrupts)); /* and re-enable physical interrupts */ enable_parport_int(); return;}int init_module(void){ int retval; /* Create a single fifo back to the user process, into which our ISR will put the cumulative interrupt count. */ retval = rtf_create(FIFO_NUM, FIFO_INTS * sizeof(int)); if (retval) { printk("could not create RT-FIFO 0\n"); return retval; } rtf_reset(0); /* Connect our ISR to the parallel port interrupt. */ rt_free_global_irq(PARPORT_IRQ); retval = rt_request_global_irq(PARPORT_IRQ, isr_code); if (retval) { if (retval == -EINVAL) { /* irq is not a valid IRQ number or handler is null */ printk("invalid IRQ\n"); } else if (retval == -EBUSY) { /* already a handler */ printk("IRQ already assigned by RTAI\n"); } return retval; } rt_startup_irq(PARPORT_IRQ); /* Enable parallel port interrupts at the hardware level. */ enable_parport_int(); return 0;}void cleanup_module(void){ /* Disable parallel port interrupts at the hardware level. */ disable_parport_int(); /* Disconnect our ISR. */ rt_shutdown_irq(PARPORT_IRQ); rt_free_global_irq(PARPORT_IRQ); rtf_destroy(0); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -