(九)linux中断编程
目錄
- (一)linux中斷的介紹
- (二)內(nèi)核中斷的操作過(guò)程
- (三)實(shí)例代碼
(一)linux中斷的介紹
linux內(nèi)核中的中斷通過(guò)中斷子系統(tǒng)來(lái)管理。linux系統(tǒng)中有專(zhuān)門(mén)的中斷子系統(tǒng),原理很復(fù)雜,驅(qū)動(dòng)開(kāi)發(fā)者不需要知道具體細(xì)節(jié),只需要知道如何應(yīng)用該子系統(tǒng)提供的api來(lái)編寫(xiě)中斷驅(qū)動(dòng)代碼即可
在linux內(nèi)核中,文件大多以功能命名,內(nèi)核中提供了一個(gè)interrupt.h的文件用來(lái)進(jìn)行中斷先關(guān)接口及數(shù)據(jù)結(jié)構(gòu)的聲明,內(nèi)核使用struct irqaction結(jié)構(gòu)體描述一個(gè)中斷,編寫(xiě)中斷程序終極目標(biāo)就是實(shí)現(xiàn)這個(gè)結(jié)構(gòu)體
flags :
IRQF_DISABLED:私有中斷,即一個(gè)中斷請(qǐng)求對(duì)應(yīng)一個(gè)中斷服務(wù)函數(shù) IRQF_SHARED:共享中斷,多個(gè)中斷請(qǐng)求對(duì)應(yīng)一個(gè)中斷服務(wù)函數(shù)(二)內(nèi)核中斷的操作過(guò)程
cpu給中斷的一個(gè)編號(hào),一個(gè)IRQ number是一個(gè)虛擬的interrupt ID,和硬件無(wú)關(guān).
查找中斷線(xiàn)比較費(fèi)時(shí),所以?xún)?nèi)核中提供了一個(gè)操作接口來(lái)獲取指定引腳的中中斷號(hào)
參數(shù)為gpio口:
在內(nèi)核中生產(chǎn)廠(chǎng)商提供了先關(guān)的gpio口的聲明,分別存放在指定架構(gòu)目錄下的gpio.h
其他相關(guān)函數(shù):
void disable_irq(unsigned int irq);//失能void enable_irq(unsigned int irq);//使能 int gpio_get_value(unsigned int gpio);// 獲取設(shè)備gpio口的值: void gpio_set_value(unsigned int gpio, int value);//設(shè)置設(shè)備的gpio的值(三)實(shí)例代碼
#include <linux/interrupt.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/gpio.h>irqreturn_t key1_handler(int irq, void *dev) {int value=gpio_get_value(EXYNOS4_GPX3(2));printk("key1 value is %d\n",value);return IRQ_HANDLED; } irqreturn_t key2_handler(int irq, void *dev) {int value=gpio_get_value(EXYNOS4_GPX3(3));printk("key2 value is %d\n",value);return IRQ_HANDLED; } irqreturn_t key3_handler(int irq, void *dev) {int value=gpio_get_value(EXYNOS4_GPX3(4));printk("key3 value is %d\n",value);return IRQ_HANDLED; } irqreturn_t key4_handler(int irq, void *dev) {int value=gpio_get_value(EXYNOS4_GPX3(5));printk("key4 value is %d\n",value);return IRQ_HANDLED; }static int __init handler_module_init(void) {int ret=0;unsigned long flags=IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_DISABLED;unsigned int irq=gpio_to_irq(EXYNOS4_GPX3(2)); //獲取K1的irqret=request_irq(irq,key1_handler,flags, "key0", NULL);irq=gpio_to_irq(EXYNOS4_GPX3(3)); //獲取K1的irqret=request_irq(irq,key2_handler,flags, "key0", NULL);irq=gpio_to_irq(EXYNOS4_GPX3(4)); //獲取K1的irqret=request_irq(irq,key3_handler,flags, "key0", NULL);irq=gpio_to_irq(EXYNOS4_GPX3(5)); //獲取K1的irqret=request_irq(irq,key4_handler,flags, "key0", NULL);return 0; } static void __exit handler_module_cleanup(void) {unsigned int irq=gpio_to_irq(EXYNOS4_GPX3(2)); //獲取K1的irqfree_irq(irq, NULL);irq=gpio_to_irq(EXYNOS4_GPX3(3)); //獲取K2的irqfree_irq(irq, NULL);irq=gpio_to_irq(EXYNOS4_GPX3(4)); //獲取K3的irqfree_irq(irq, NULL);irq=gpio_to_irq(EXYNOS4_GPX3(5)); //獲取K4的irqfree_irq(irq, NULL); } module_init(handler_module_init); module_exit(handler_module_cleanup); MODULE_LICENSE("GPL");Makefile
CFLAG=-C TARGET=cdev #APP=cdev_app KERNEL=/driver/linux-3.5 obj-m +=$(TARGET).o all:make $(CFLAG) $(KERNEL) M=$(PWD) #arm-linux-gcc -o $(APP) $(APP).c clean:make $(CFLAG) $(KERNEL) M=$(PWD) clean #rm $(APP)本文章僅供學(xué)習(xí)交流用禁止用作商業(yè)用途,文中內(nèi)容來(lái)水枂編輯,如需轉(zhuǎn)載請(qǐng)告知,謝謝合作
微信公眾號(hào):zhjj0729
微博:文藝to青年
總結(jié)
以上是生活随笔為你收集整理的(九)linux中断编程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2014 网选 广州赛区 hdu 502
- 下一篇: (三)linux之根文件系统的制作