榜首部分获取中止(舱位硬件中止)
一、中止的请求刊出:
1)中止的请求
int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long irqflags, const char *devname, void *dev_id)
2)中止的刊出
void free_irq(unsigned int irq, void *dev_id)
3)中止处理函数
static irqreturn_t irq_handle(int irq, void *dev__id);
参数:irq:一共中止号,这个参数还保存我们前史遗留问题,往后或许越来越没用了。我们第二个参数信息更强壮
dev__id:便是request_irq()中void *dev_id参数。
二、中止请求函数参数
int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long irqflags, const char *devname, void *dev_id)
1)参数:
irq:是要请求的硬件中止号。
handler:是向体系注册的中止处理函数,是一个回调函数,中止产生时,体系调用这个函数,dev_id参数将被传递给它。
irqflags:是中止处理的特点,
a)若设置了IRQF_DISABLED,则一共中止处理程序是快速处理程序,快速处理程序被调用时屏蔽一切中止,慢速处理程序不屏蔽;
b)若设置了 IRQF_SHARED,则一共多个设备同享中止;//在另一篇文章会说到
c)若设置了IRQF_SAMPLE_RANDOM,一共对体系熵有贡献,对体系获取随机数有优点。
Tip:(flag是能够经过或的方法一起运用的)
devname:设置中止称号,通常是设备驱动程序的称号 在cat /proc/interrupts中能够看到此称号。
dev_id:在中止同享时会用到,一般设置为这个设备的设备结构体或许不运用时为NULL。我们在同享中止中同一个中止线(或能够说同一个中止号)或许挂载好几个设备,当运用void free_irq(unsigned int irq, void *dev_id)时,依据irq和dev_id能够找到中止线为irq上的标识为dev_id的某个详细设备。dev_id也常常在不是同享中止中的驱动传递数据
2)回来值:
a)request_irq()回来0一共成功;
b)回来-EINVAL一共无效的参数,假如回来这个值,应该看看传递给request_irq()的参数是否正确;
c)回来-EBUSY一共中止现已被占用且不能同享;
d)回来ENOMEM一共内存不足。嵌入式体系我们内存资源有限,常常会产生这样的过错。
3)扩展—unsigned long irqflags值
在include\linux\interrupt.h中
/*
* These correspond to the IORESOURCE_IRQ_* defines in
* linux/ioport.h to select the interrupt line behaviour. When
* requesting an interrupt without specifying a IRQF_TRIGGER, the
* setting should be assumed to be “as already configured”, which
* may be as per machine or firmware initialisation.
*/
#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
/*
* These flags used only by the kernel as part of the
* irq handling routines.
*
* IRQF_DISABLED – keep irqs disabled when calling the action handler
* IRQF_SAMPLE_RANDOM – irq is used to feed the random generator
* IRQF_SHARED – allow sharing the irq among several devices
* IRQF_PROBE_SHARED – set by callers when they expect sharing mismatches to occur
* IRQF_TIMER – Flag to mark this interrupt as timer interrupt
* IRQF_PERCPU – Interrupt is per cpu
* IRQF_NOBALANCING – Flag to exclude this interrupt from irq balancing
* IRQF_IRQPOLL – Interrupt is used for polling (only the interrupt that is
* registered first in an shared interrupt is considered for
* performance reasons)
*/
#define IRQF_DISABLED 0x00000020
#define IRQF_SAMPLE_RANDOM 0x00000040
#define IRQF_SHARED 0x00000080
#define IRQF_PROBE_SHARED 0x00000100
#define IRQF_TIMER 0x00000200
#define IRQF_PERCPU 0x00000400
#define IRQF_NOBALANCING 0x00000800
#define IRQF_IRQPOLL 0x00001000
Tip:下面是老版别(2.4内核irqflags的值),不要在新版别运用。(2.6 内核及2.6以上内核都为新内核)
/*
* Migration helpers. Scheduled for removal in 9/2007
* Do not use for new code !//不要的新版别运用,2.6 内核及2.6以上内核都为新内核
*/
static inline
unsigned long __deprecated deprecated_irq_flag(unsigned long flag)
{
return flag;
}
#define SA_INTERRUPT deprecated_irq_flag(IRQF_DISABLED)
#define SA_SAMPLE_RANDOM deprecated_irq_flag(IRQF_SAMPLE_RANDOM)
#define SA_SHIRQ deprecated_irq_flag(IRQF_SHARED)
#define SA_PROBEIRQ deprecated_irq_flag(IRQF_PROBE_SHARED)
#define SA_PERCPU deprecated_irq_flag(IRQF_PERCPU)
#define SA_TRIGGER_LOW deprecated_irq_flag(IRQF_TRIGGER_LOW)
#define SA_TRIGGER_HIGH deprecated_irq_flag(IRQF_TRIGGER_HIGH)
#define SA_TRIGGER_FALLING deprecated_irq_flag(IRQF_TRIGGER_FALLING)
#define SA_TRIGGER_RISING deprecated_irq_flag(IRQF_TRIGGER_RISING)
#define SA_TRIGGER_MASK deprecated_irq_flag(IRQF_TRIGGER_MASK)
三、运用模板
运用过程:以外部中止为例
a)界说结构体,相当于界说(void *dev_id)中的(void *)
struct pin_desc{//声明一个引脚描绘的结构体pin_desc
unsigned int pin;//引脚值,参阅数据手册及板子电路原理图
unsigned int key_val;//值自已随意界说;看自己的项目需求
//……………….
};
b)实例化结构体,相当于(void *dev_id)中的 dev_id
struct pin_desc pins_desc[3] = {//实例化结构体,以jz2440按键为列
{S3C2410_GPF0, 0x01},//S3C2410_GPFn在内核中界说好了
{S3C2410_GPF2, 0x02},
{S3C2410_GPG3, 0x03},
};
c)界说中止处理函数
static irqreturn_t irq_handle(int irq, void *dev__id){
struct pin_desc *pindesc = (struct pin_desc *)dev__id;
//…………….
return IRQ_RETVAL(IRQ_HANDLED);//回来IRQ_HANDLED一共中止现已处理
}
d)请求中止
request_irq(IRQ_EINT0, irq_handle, IRQ_TYPE_EDGE_BOTH, “s2”, &pins_desc[0]);//IRQ_EINTn在内核中界说好了
request_irq(IRQ_EINT2, irq_handle, IRQ_TYPE_EDGE_BOTH, “s3”, &pins_desc[1]);
request_irq(IRQ_EINT11, irq_handle, IRQ_TYPE_EDGE_BOTH, “s4”, &pins_desc[2]);
e)开释内存
free_irq(IRQ_EINT0, &pins_desc[0]);
free_irq(IRQ_EINT2, &pins_desc[1]);
free_irq(IRQ_EINT11, &pins_desc[2]);
Tip:能够直接将IRQ_EINTn也在pins_desc界说,然后
int i = 0;
for(i = 0; i < 3; i++){
free_irq(pins_desc[i].irqnum, &pins_desc[i]);
}