Linux驅動開發-外部中斷的注冊使用(按鍵為例)

      網友投稿 723 2022-05-29

      1. 外部中斷介紹

      前面有篇文章使用雜項設備完成了按鍵驅動的編寫,實現了按鍵輪詢檢測,通過read函數向應用層傳遞按鍵值,這篇文章使用按鍵為例,介紹linux內核里中斷的注冊方法,使用中斷的方式檢測按鍵是否按下,中斷在單片機、設備驅動開發里使用的都非常多,可以更加實時的檢測到按鍵觸發的情況。

      Linux內核提供了中斷的注冊接口:

      (1)注冊中斷

      頭文件 include\linux\interrupt.h 定義文件 include\linux\interrupt.h 函數原型 int request_irq(unsigned int irq,/*做實參傳遞給中斷服務函數第1個參數*/ irq_handler_t handler, /*中斷服務函數指針*/ unsigned long flags, const char *name, void *dev_id); /*做實參傳遞給中斷服務函數第2個參數*/ 函數功能 向內核注冊一個中斷服務函數; 當發生中斷號為 irq 的中斷時候,會執行 handler 指針函數。 函數參數 irq:中斷編號(每個中斷源有惟一的編號)。 handler:中斷服務函數指針。 原型 typedef irqreturn_t (*irq_handler_t)(int, void *)。 flag:中斷的標志,用來描述本中斷的基本特征的。 有固定的值,由中斷源的特征決定; 比如外中斷有:上升沿,下降沿觸發中斷這類標志。 name:中斷名字, 注冊后會出現cat /proc/interrupts dev_id: 這個參數是傳遞給中斷服務函數。 對共享中斷來說, 這個參數一定有要; 當注銷共享中斷中的其中一個時, 用這個來標識要注銷哪一個。 對于有惟一入口的中斷,可以傳遞 NULL; 但是一般來說都會傳遞一個有意義指針,在中斷程序中使用, 以方便編程。 返回值 0 表示成功 -EINVAL (無效參數22)表示中斷號無效。 -EBUSY (設備或者資源忙16)表示中斷已經被占用。

      (2)注銷中斷

      void free_irq(unsigned int irq,void * dev_id) irq: 要注銷的中斷號 dev_id:其實就是注冊時候使用的dev參數,在共享中斷必不可少,不能傳遞NULL。 注意:為了防止在注銷時同時發生中斷,調用時候,先禁止中斷。

      (3)中斷開啟與關閉

      禁止中斷 void disable_irq_nosync(unsigned int irq); void disable_irq(unsigned int irq); 參數:irq,要禁止的中斷對應的編號。 注意:在中斷服務程序中不能使用 disable_irq 這個函數,否則內核崩潰,可以使用 disable_irq_nosync。 disable_irq:函數調用后,函數不會馬上返回,而等待中斷程序執行完成才返回,在中斷調用會導致死鎖。 disable_irq_nosync:調用后,函數馬上返回。 使能中斷 void enable_irq(unsigned int irq); 參數:irq,要使能的中斷對應的編號

      (4)獲取irq中斷號

      int gpio_to_irq(unsigned gpio);

      2. 外部中斷驅動編寫

      Linux驅動開發-外部中斷的注冊使用(按鍵為例)

      2.1 按鍵原理圖

      2.2 驅動示例代碼

      insmod 安裝驅動之后就直接注冊按鍵中斷,沒有注冊字符設備框架,當按鍵按下之后,直接在驅動層通過printk打印數據提示到終端。

      #include #include #include #include #include #include #include /*存放按鍵的信息*/ struct m_key_info { int gpio; char name[50]; int val; int irq; }; struct m_key_info key_info[]= { {EXYNOS4_GPX3(2),"key_irq_1",0x01}, {EXYNOS4_GPX3(3),"key_irq_2",0x02}, {EXYNOS4_GPX3(4),"key_irq_3",0x03}, {EXYNOS4_GPX3(5),"key_irq_4",0x04}, }; /* 中斷服務函數 */ static irqreturn_t key_irq_handler(int irq, void *dev) { struct m_key_info *p=(struct m_key_info*)dev; if(gpio_get_value(p->gpio)==0) //判斷按鍵是否按下 { printk("按鍵值:%#x\n",p->val); } else { printk("按鍵值:%#x\n",p->val|0x80); } return IRQ_HANDLED; } static int __init tiny4412_interrupt_drv_init(void) { int i; for(i=0;i

      2.3 makefile代碼

      KER_DRI=/home/wbyq/work/linux-3.5/linux-3.5 all: make -C $(KER_DRI) M=`pwd` modules cp *.ko /home/wbyq/work/rootfs/code -f make -C $(KER_DRI) M=`pwd` modules clean obj-m += interrupt_key.o

      Linux

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:華為云攜手50家SaaS伙伴,正式開啟“星光計劃”2021行動
      下一篇:C#宿舍管理系統數據表文檔分析含釋義
      相關文章
      亚洲精品亚洲人成在线观看| 亚洲国产一成久久精品国产成人综合 | 亚洲AV无码一区二区二三区入口| jizzjizz亚洲| 亚洲日本久久久午夜精品| 精品亚洲AV无码一区二区 | 香蕉视频亚洲一级| 久久亚洲精品11p| 国产成人综合亚洲一区| 亚洲AV日韩AV永久无码色欲| 久久综合亚洲色hezyo| 性色av极品无码专区亚洲 | 亚洲美女视频网址| 亚洲一级片在线播放| 国产精品亚洲专区在线观看 | 亚洲成AV人在线播放无码| 亚洲AV无码第一区二区三区| 亚洲爱情岛论坛永久| 亚洲视频中文字幕在线| 亚洲啪啪免费视频| 亚洲综合激情五月色一区| 亚洲成a∧人片在线观看无码| 国产精品无码亚洲精品2021| 亚洲成a人片在线观看老师| 亚洲综合最新无码专区| 国产亚洲精品一品区99热| 亚洲av永久无码精品漫画| 久久久久亚洲AV无码专区首JN | 亚洲日韩在线观看| 亚洲韩国精品无码一区二区三区| 亚洲精品制服丝袜四区| 亚洲高清无在码在线电影不卡| 亚洲成a人片在线观| 亚洲中文字幕乱码一区| 亚洲欧美日韩中文无线码 | 亚洲精品黄色视频在线观看免费资源| 日日噜噜噜噜夜夜爽亚洲精品| 亚洲av最新在线网址| 亚洲熟妇无码久久精品| 国产亚洲福利在线视频| 国产亚洲视频在线观看网址|