- 论坛徽章:
- 0
|
KEY测试(中断)
前面已经用查询的方式做了一个按键的驱动,现在来看看用中断方式做的按键驱动,这个驱动没有处理按键抖动这些细节问题,主要目的是了解一下中断的相关问题,按键只是个接口而已,而好多书上在讲中断的时候虽然也是以按键为例,但过于关注按键显得很烦琐。不利于突出中断这个主题。
说到中断,一般都是讲在用以前只要申请一下用完释放就可以了,函数如下
int request_irq(unsigned int irq,
void (*handler)(int irq, void *dev_id,
struct pt_regs *regs), unsigned long irqflags,
const char * devname, void *dev_id);
void free_irq(unsigned int irq,void *dev_id);
同样的,对于9260来说也一样,由于按键是接在PIOB上,通过查看中断分配可以看出,PIOA PIOB PIOC 分别对应中断号为 2 3 4,但如果在9260EK上,在申请中断时你会发现,如果申请的中断号为2 3 4 之中的任意一个,都将返回 -22 ,但如果换成其他中断号例如5,就可以成功申请。这就意味着我们不能申请 2 3 4这3个中断,在网上也可以看到不少用9260的朋友也都碰到了这个问题。
先看返回-22,意味着这个中断已经被占用,但用CAT看的话有没有任何关于这3个中断的信息。没办法,只有先翻翻源代码看看了,在arch/arm/match-at91rm9200/at91sam9260.c中发现了这么一段
void __init at91sam9260_init_interrupts(unsigned int priority[NR_AIC_IRQS])
{
if (!priority)
priority = at91sam9260_default_irq_priority;
/* Initialize the AIC interrupt controller */
at91_aic_init(priority);
/* Enable GPIO interrupts */
at91_gpio_irq_setup();
}
void __init at91_gpio_irq_setup(void)
{
unsigned pioc, pin;
for (pioc = 0, pin = PIN_BASE;
pioc
pioc++) {
void __iomem *controller;
unsigned id = gpio[pioc].id;
unsigned i;
clk_enable(gpio[pioc].clock); /* enable PIO controller's clock */
controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset;
__raw_writel(~0, controller + PIO_IDR);
set_irq_data(id, (void *) pin);
set_irq_chip_data(id, controller);
for (i = 0; i
/*
* Can use the "simple" and not "edge" handler since it's
* shorter, and the AIC handles interupts sanely.
*/
set_irq_chip(pin, &gpio_irqchip);
set_irq_handler(pin, handle_simple_irq);
set_irq_flags(pin, IRQF_VALID);
}
set_irq_chained_handler(id, gpio_irq_handler);
}
pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks);
}
void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
{
BUG_ON(nr_banks > MAX_GPIO_BANKS);
gpio = data;
gpio_banks = nr_banks;
}
void __init at91sam9260_initialize(unsigned long main_clock)
{
/* Map peripherals */
iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc));
if (cpu_is_at91sam9xe())
at91sam9xe_initialize();
else
iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc));
at91_arch_reset = at91sam9260_reset;
at91_extern_irq = (1
| (1
/* Init clock subsystem */
at91_clock_init(main_clock);
/* Register the processor-specific clocks */
at91sam9260_register_clocks();
/* Register GPIO subsystem */
at91_gpio_init(at91sam9260_gpio, 3);
}
可以看出,确实 2 3 4中断已经被初始化过了,继续看又发现了下面这段注释
/* Several AIC controller irqs are dispatched through this GPIO handler.
* To use any AT91_PIN_* as an externally triggered IRQ, first call
* at91_set_gpio_input() then maybe enable its glitch filter.
* Then just request_irq() with the pin ID; it works like any ARM IRQ
* handler, though it always triggers on rising and falling edges.
*
* Alternatively, certain pins may be used directly as IRQ0..IRQ6 after
* configuring them with at91_set_a_periph() or at91_set_b_periph().
* IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering.
*/
注册中断号时直接用AT91_PIN_PIOB1 一试,成功了,在用#cat /proc/initerrupts 一看,中断号为 65,再试一下AT91_PIN_PIOC1为 97,可以看出,PIOA的32个IO对应的中断号为32-63 ,PIOB和PIOC对应的依次为64-127。运行一下试试,一切正常。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/68643/showart_1085547.html |
|