按鍵的裝置驅動程式流程

2021-06-05 23:42:33 字數 3113 閱讀 7010

按鍵的裝置驅動

1.按鍵的硬體原理

在嵌入式系統中,通過乙個上拉電阻將處理器的外部中斷引腳拉高,電阻的另一端連線按鈕並接地即可實現。

當按鈕被按下時,eint10、ein13、eint14、eint15 上將產生低電平,這個低電平將中斷cpu,cpu可以依據中斷判斷按鍵被按下。

僅僅依據中斷被產生就認定有一次按鍵行為是很不準確的,所有按鍵、觸控螢幕等機械裝置都存在乙個固有的問題,那就是「抖動」,按鍵從最初接通到穩定接通要經過數毫秒,其間可能發

生多次「接通―斷開」的過程。如果不消除「抖動」的影響,一次按鍵可能被理解為多次按鍵。

消除按鍵抖動影響的方法是:在判斷有鍵按下後,進行軟體延時(如20ms,在延時過程中要遮蔽對應中斷),再判斷鍵盤狀態,如果仍處於按鍵按下狀態,則可以斷定該按鍵被按下。

2.按鍵驅動中的資料結構

裝置驅動中主要要設計的資料結構是裝置結構體,按鍵的裝置結構體中應包含乙個緩衝區,因為多次按鍵可能無法被及時處理,可以用該緩衝區快取按鍵。此外,在按鍵裝置結構體中,包含按鍵狀態標誌和乙個實現過程中要借助的等待佇列、cdev結構體。為了實現軟體延時,定時器也是必要的。

【按鍵驅動的裝置結構體、定時器】

1 #define max_key_buf 16 //按鍵緩衝區大小

2 typedef unsigned char key_ret;

3 //裝置結構體:

4 typedef struct

5 key_dev;

11 static struct timer_list key_timer[key_num];//4個按鍵去抖定時器

在按鍵裝置驅動中,可用乙個結構體記錄每個按鍵所對應的中斷/gpio 引腳及鍵值。

【按鍵硬體資源、鍵值資訊結構體】

1 static struct key_info

2 key_info_tab[4] =

7 ,,,,};

按鍵裝置驅動的檔案操作結構體,主要實現了開啟、釋放和讀函式,因為按鍵只是乙個輸入裝置,所以不存在寫函式。

【按鍵裝置驅動檔案操作結構體】

1 static struct file_operations s3c2410_key_fops =

2 ;

3.按鍵驅動的模組載入和解除安裝函式

按鍵裝置作為一種字元裝置,在其模組載入和解除安裝函式中分別包含了裝置號申請和釋放、cdev的新增和刪除行為,在模組載入函式中,還需申請中斷、初始化定時器和等待佇列等,模組解除安裝函式完成相反的行為。

【按鍵裝置驅動的模組載入函式】

1 static int __init s3c2410_key_init(void)  //程式入口

2 1 static void __exit s3c2410_key_exit(void)  //程式出口

2 【按鍵裝置驅動的中斷申請函式】

1 /*申請系統中斷,中斷方式為下降沿觸發*/

2 static int request_irqs(void)

3 16  }

17 return 0;

18 }

【按鍵裝置驅動的中斷釋放函式】

1 /*釋放中斷*/

2 static void free_irqs(void)

3 11 }

4.按鍵裝置驅動中斷、定時器處理程式

在鍵被按下後,將發生中斷,在中斷處理程式中,應該關閉中斷進入查詢模式,延遲20ms 以實現去抖動

【按鍵裝置驅動的中斷處理程式】

1 static void s3c2410_eint_key(int irq, void *dev_id, struct pt_regs*reg)

2 在定時器處理程式中,查詢按鍵是否仍然被按下,如果是被按下的狀態,則將該按鍵記錄入緩衝區。同時啟動新的定時器延遲,延遲乙個相對於去抖更長的時間(如100ms),每次定時器到期後,查詢按鍵是否仍然處於按下狀態,如果是,則重新啟用新的100ms 延遲;若查詢到已經沒有按下,則認定鍵已抬起,這個時候應該開啟對應按鍵的中斷,等待新的按鍵。每次記錄

新的鍵值時,應喚醒等待佇列。

【按鍵裝置驅動的定時器處理函式】

1 static void key_timer_handler(unsigned long data)

2 14  else

15  

19  }

20  else //鍵已抬起

21  

25 }

5.按鍵裝置驅動的開啟、釋放函式

按鍵裝置驅動的開啟和釋放函式比較簡單,主要是設定keydev.head、keydev.tail和按鍵事件函式指標keyevent 的值

【按鍵裝置驅動的開啟、釋放函式】

1 static int s3c2410_key_open(struct inode *inode, struct file *filp)2 7

8 static int s3c2410_key_release(struct inode *inode, struct file*filp)

96.按鍵裝置驅動讀函式

按鍵裝置驅動的讀函式主要提供對按鍵裝置結構體中緩衝區的讀並複製到使用者空間。當keydev.head ! = keydev.tail時,意味著緩衝區有資料,使用copy_to_user()拷貝到使用者空間,否則,根據使用者空間是阻塞讀還是非阻塞讀,分為如下兩種情況。

1若採用非阻塞讀,則因為沒有按鍵快取,直接返回- eagain;

2若採用阻塞讀,則在keydev.wq 等待佇列上睡眠,直到有按鍵被記錄入緩衝區後被喚醒。

【按鍵裝置驅動的讀函式】

1 static ssize_t s3c2410_key_read(struct file *filp, char *buf, ssize_t

count,loff_t*ppos)

3 10  else

11  

17  interruptible_sleep_on(&(keydev.wq));

18  //使用者採用阻塞方式讀取,呼叫該函式使程序睡眠

19  goto retry;

20  }

21  return 0;

22 }

USB裝置驅動程式載入流程

使用者插入usb裝置 usb匯流排 或者是pci匯流排,這個不太清楚,反正就是匯流排來著 識別到插入了usb裝置。匯流排和usb裝置進行通訊,獲取usb的硬體id 產品id,以及bcdversion。根據這些資訊組成裝置硬體id號 vid x pid x rev x。匯流排根據usb裝置的插槽位置,...

linux裝置驅動程式 字元裝置驅動程式

先留個 有一起學習驅動程式的加qq295699450 字元裝置驅動 這篇比較惱火。載入成功,但是讀不出來資料,有知道怎麼回事的,留個言,一起討論下 資料結構 struct scull mem struct scull dev dev 整個驅動程式 如下 include include include...

Linux裝置驅動程式 字元裝置驅動程式

1.檢視主裝置號,次裝置號 進入 dev目錄執行ls l,第四,五列分別為主次裝置號,10,180,1,5,這些是主裝置號,而60,63這些就是次裝置號 130 shell android dev ls l crw rw r system radio 10,60 1969 12 31 21 00 a...