首先,在做這個實驗之前有三件事是要明確的:
1. linux下的中斷實驗不需要像裸機實驗一樣要自己寫取消屏蔽,清除中斷標志位的操作,系統會自動幫你完成;
2.中斷號的申請我使用的是gpio_to_irq()這個宏,它會幫我們自動分配中斷號,返回值為中斷號;
3. 在每個板子配套來的內核代碼大部分都是已經包含了按鍵中斷驅動,如果想另自己寫的按鍵中斷驅動不與內核本身帶的發生中斷號上的沖突,應先找到內核代碼下的arch/arm/mach-s5pv210/mach-mini210.c中的gpio_bottons中的對按鍵初始化的代碼注釋掉(其他板子也類似),如下代碼所示:
static struct gpio_keys_button gpio_buttons[] = { /*{ .gpio = S5PV210_GPH2(0), .code = 158, .desc = "BACK", .active_low = 1, .wakeup = 0, }, { .gpio = S5PV210_GPH2(1), .code = 102, .desc = "HOME", .active_low = 1, .wakeup = 1, }, { .gpio = S5PV210_GPH2(2), .code = 139, .desc = "MENU", .active_low = 1, .wakeup = 0, }, { .gpio = S5PV210_GPH2(3), .code = 232, .desc = "DPAD_CENTER", .active_low = 1, .wakeup = 0, }, { .gpio = S5PV210_GPH3(0), .code = 105, .desc = "DPAD_LEFT", .active_low = 1, .wakeup = 0, }, { .gpio = S5PV210_GPH3(1), .code = 108, .desc = "DPAD_DOWN", .active_low = 1, .wakeup = 0, }, { .gpio = S5PV210_GPH3(2), .code = 103, .desc = "DPAD_UP", .active_low = 1, .wakeup = 0, }, { .gpio = S5PV210_GPH3(3), .code = 106, .desc = "DPAD_RIGHT", .active_low = 1, .wakeup = 0, }, { .gpio = S5PV210_GPH1(7), .code = 102, .desc = "HOME", .active_low = 1, .wakeup = 1, }*/};
#include <linux/module.h>#include <linux/init.h>#include <linux/miscdevice.h>#include <linux/interrupt.h>#include <linux/fs.h>#include <linux/io.h>#include <mach/gpio.h> #include <mach/regs-gpio.h> #include <linux/irq.h>#define GPH2CON 0xe0200c40irqreturn_t key_irq(int irq, void * dev_id){ //1. 檢測是否發生了按鍵中斷 //2. 清除已經發生的按鍵中斷 //3. 打印按鍵值 PRintk("key down!/n"); return 0;}int key_open (struct inode *inode, struct file *filp){ return 0;}void key_hw_init(){ //unsigned int data; unsigned int *gpio_config; gpio_config = ioremap(GPH2CON,4); //data = readl(gpio_config); //data &= ~0b1111; //data |= 0b1111; writel(0x0000000f,gpio_config);}struct file_Operations key_fops ={ .open = key_open,};struct miscdevice key_miscdevice ={ /*MISC_DYNAMIC_MINOR代表動態分配次設備號,即由系統自動分配*/ .minor = MISC_DYNAMIC_MINOR, .name = "key_miscdev", .fops = &key_fops,};static int key_init(){ /*注冊混雜設備*/ misc_register(&key_miscdevice); /*申請中斷,如果內核中已有按鍵中斷驅動,則需要把arch/arm/mach-s5pv210/mach-mini210.c文件的gpio_buttons定義的相關按鍵去掉, 不然板子上的按鍵中斷就已經被占用,不能注冊中斷*/ /*注意:中斷號這個參數應該用gpio_to_irq(S5PV210_GPH2(0)),假如用了IRQ_EINT16_31則按鍵驅動不會工作*/ request_irq(gpio_to_irq(S5PV210_GPH2(0)), key_irq, IRQF_TRIGGER_FALLING, "key_miscdev", 0); request_irq(gpio_to_irq(S5PV210_GPH2(1)), key_irq, IRQF_TRIGGER_FALLING, "key_miscdev", 0); request_irq(gpio_to_irq(S5PV210_GPH2(2)), key_irq, IRQF_TRIGGER_FALLING, "key_miscdev", 0); request_irq(gpio_to_irq(S5PV210_GPH2(3)), key_irq, IRQF_TRIGGER_FALLING, "key_miscdev", 0); return 0; }static void key_exit(){ /*注銷設備*/ misc_deregister(&key_miscdevice);}MODULE_LICENSE("GPL");module_init(key_init);module_exit(key_exit);
新聞熱點
疑難解答