int request_irq(unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id)
使用:将中断号irq与中断处理函数handler对应
参数:
irq:指定要分配的中断号(参考芯片手册)。
注意,不管是单独占有中断请求线的中断,还是共享中断请求线的每个中断,都有一个对应的中断号。所以,调用该函数不需要考虑是哪种中断(是否共享寄存器),你想哪种中断响应,你就填对应的中断号。
handler: 中断处理函数指针
irqflags: 中断处理标记,待会介绍:
devname:该字符串将显示在/proc/irq和/pro/interrupt中。
dev_id: ID 号
返回值:成功返回0,失败返回非0
2) 中断处理标志irqflags
/*linux-2.6.29/include/linux/interrupt.h*/
#define IRQF_TRIGGER_NONE 0x00000000
#define IRQF_TRIGGER_RISING 0x00000001 //上升沿触发中断
#define IRQF_TRIGGER_FALLING 0x00000002 //下降沿触发中断
#define IRQF_TRIGGER_HIGH 0x00000004 //高电平触发中断
#define IRQF_TRIGGER_LOW 0x00000008 //低电平触发中断
#define IRQF_TRIGGER_MASK (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
#define IRQF_TRIGGER_PROBE 0x00000010
SA_INTERRUPT:这个标志表明该中断处理程序是一个快速中断处理程序。过去,linux系统会区分快速我慢速中断,但现在这个标志只有这样的效果:当响应这个中断时,禁止所有的中断,是该中断处理函数不会被其他中断打断,迅速执行。
SA_SAMPLE_RANDOM:这个标志表明产生的中断会对内核的entropy pool有贡献。Entropy pool负责产生随机数。
SA_SHIRQ:这个标志表明多个中断处理程序可以共享一个中断号, 在ARM下SA_SHIRQ相当于标志IRQF_SHARED;设置此位可以实现多个驱动共享一个中断
共享中断:
有时候会有这样的情况,如果开发板上按键的中断已经被另外的驱动程序注册中断了,而我现在又想再注册一次这个中断,这就出现了一个中断号不止对应一个中断函数的情况。注意,这里与硬件上的共享中断不一样,这里是指,当一个中断信号来了,基于操作系统,一个中断的到来可以调用多个中断处理程序,与硬件无关。
代码:
/*******************************************存放按键信息结构体*******************************************/
/* 定义结构体类型,由它把按钮中断的信息综合起来 */
struct button_irq_desc
{
int irq; /* 按键对应的中断号 */
int pin; /* 按键所对应的 GPIO 端口 */
int number; /* 键值,传递给应用层 */
char *name; /* 按键名称 */
};
/* 结构体实体定义 */
static struct button_irq_desc button_irqs[] =
{
{HI3520D_IRQ_GPIO0, HI35XX_GPIO_PORT0*10+HI35XX_GPIO_PIN6, 1, "test-key1"},
{HI3520D_IRQ_GPIO0, HI35XX_GPIO_PORT0*10+HI35XX_GPIO_PIN7, 2, "test-key2"},
};
/* 存放按键的值 copy_to_user(buff, &key, min(sizeof(key),count)中调用 */
static char key[2] = {0, 0};
/*******************************************存放按键信息结构体*******************************************/
request_irq(button_irqs[0].irq, button_dev_irq_interrupt, IRQF_SHARED, button_irqs[0].name, (void *)&button_irqs);
2、释放中断处理函数
void free_irq(unsigned int irq, void *dev_id)
代码:
free_irq(button_irqs[0].irq, (void *)&button_irqs);
3、中断处理函数声明如下
static irqreturn_t button_dev_irq_interrupt(int irq, void *dev_id)
第一个参数irq,这是调用中断处理函数时传给它的中断号,对于新版本的内核,这个参数已经用处不大,一般只用于打印。
第二个参数dev_id, 这个参数与request_irq()的参数dev_id一致
返回值,中断处理函数的返回值有三个:
/*linux-2.6.29/include/linux/interrupt..h*/
#define IRQ_NONE (0) //如果产生的中断并不会执行该中断处理函数时返回该值
#define IRQ_HANDLED (1) //中断处理函数正确调用会返回
#define IRQ_RETVAL(x) ((x) != 0) //指定返回的数值,如果非0,返回IRQ_HADLER,否则
#difndef IRQ_NONE //返回IRQ_NONE。