日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

(九)linux中断编程

發(fā)布時(shí)間:2025/3/8 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (九)linux中断编程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

        • (一)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)體

* struct irqaction - per interrupt action descriptor* @handler: interrupt handler function* @name: name of the device* @dev_id: cookie to identify the device-----------是否是一個(gè)共享中斷* @percpu_dev_id: cookie to identify the device* @next: pointer to the next irqaction for shared interrupts* @irq: interrupt number* @flags: flags (see IRQF_* above)* @thread_fn: interrupt handler function for threaded interrupts* @thread: thread pointer for threaded interrupts* @thread_flags: flags related to @thread* @thread_mask: bitmask for keeping track of @thread activity* @dir: pointer to the proc/irq/NN/name entry* @flags: flags (see IRQF_* above)*/ struct irqaction {irq_handler_t handler; //用戶(hù)注冊(cè)的中斷處理函數(shù) void *dev_id;//可以是用戶(hù)傳遞的參數(shù)或者用來(lái)區(qū)分共享中斷void __percpu *percpu_dev_id;struct irqaction *next; //irqaction結(jié)構(gòu)鏈,一個(gè)共享中斷可以有多個(gè)中斷處理函數(shù) irq_handler_t thread_fn;struct task_struct *thread;unsigned int irq; //中斷號(hào)unsigned int flags; //中斷標(biāo)識(shí)unsigned long thread_flags;unsigned long thread_mask;const char *name; //用戶(hù)注冊(cè)的中斷名字,cat/proc/interrupts時(shí)可以看到 struct proc_dir_entry *dir; } ____cacheline_internodealigned_in_smp;

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ò)程

  • 向內(nèi)核提出中斷申請(qǐng)
  • request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev)//dev ---若是獨(dú)占(共享)中斷--直接賦值為空(用來(lái)區(qū)分哪一個(gè)中斷占用服務(wù)函數(shù)) {return request_threaded_irq(irq, handler, NULL, flags, name, dev); } unsigned int irq:中斷號(hào)(線(xiàn))中斷線(xiàn)號(hào)是處理器生產(chǎn)廠(chǎng)商指定的,在內(nèi)核對(duì)應(yīng)的文件中有相應(yīng)聲明,在內(nèi)核的內(nèi)部有一個(gè)與架構(gòu)匹配的irqs.h的文件,該文件對(duì)中中斷線(xiàn)進(jìn)行了聲明硬件規(guī)定好的 irq_handler_t handler:中斷服務(wù)函數(shù) unsigned long flags:中斷標(biāo)志* IRQF_SHARED Interrupt is shared* IRQF_SAMPLE_ RANDOM The interrupt can be used for entropy* IRQF_TRIGGER_* Specify active edge(s) or level const char *name:設(shè)備名 void *dev:設(shè)備標(biāo)識(shí),只有在共享中斷中此參數(shù)此參數(shù)才有效,因?yàn)樗接兄袛嗖还蚕矸?wù)函數(shù),無(wú)需判斷是哪一個(gè)設(shè)備觸發(fā)的中斷 私有中斷中可有直接賦值NULL

    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)

    static inline int gpio_to_irq(unsigned int gpio) {return __gpio_to_irq(gpio); }

    參數(shù)為gpio口:
    在內(nèi)核中生產(chǎn)廠(chǎng)商提供了先關(guān)的gpio口的聲明,分別存放在指定架構(gòu)目錄下的gpio.h

    #define EXYNOS_GPIO_NEXT(__gpio) \((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)/* EXYNOS4 GPIO bank sizes */ 標(biāo)識(shí)每一組引腳的個(gè)數(shù),如#define EXYNOS4_GPIO_A0_NR (8)就表示 GPAO組一共有8個(gè)引腳 #define EXYNOS4_GPIO_A0_NR (8)
  • 釋放中斷 free_irq(unsigned int, void *)
  • void free_irq(unsigned int irq, void *dev_id)

    其他相關(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)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。