1.按鍵的裝置驅動
在嵌入式系統中,按鍵的硬體原理比較簡單,通過乙個上拉電阻將處理器的外部中斷(或 gpio)引腳拉高,電阻的另一端連線按鈕並接地即可實現。如圖 12.1 所示,當按鈕被按下時,eint10、ein13、eint14、eint15 上將產生低電平,這個低電平將中斷 cpu(圖中的 cpu 為 s3c2410),cpu 可以依據中斷判斷按鍵被按下。
//按鍵緩衝區大小
typedef
unsigned
char key_ret;
//裝置結構體:
typedef
struct
key_dev;
static
struct timer_list key_timer[key_num]
;//4 個按鍵去抖定時器
在按鍵裝置驅動中,可用乙個結構體記錄每個按鍵所對應的中斷/gpio 引腳及鍵值
static
struct key_info
key_info_tab[4]
=,,,,};
按鍵裝置驅動檔案操作結構體主要實現了開啟、釋放和讀函式,因為按鍵只是乙個輸入裝置,所以不存在寫函式
static
struct file_operations s3c2410_key_fops =
;
按鍵裝置作為一種字元裝置,在其模組載入和解除安裝函式中分別包含了裝置號申請和釋放、cdev 的新增和刪除行為,在模組載入函式中,還需申請中斷、初始化定時器和等待佇列等,模組解除安裝函式完成相反的行為
模組載入函式
static
int __init s3c2410_key_init
(void
)
模組解除安裝函式
static
void __exit s3c2410_key_exit
(void
)
按鍵裝置驅動的中斷申請函式
/*申請系統中斷,中斷方式為下降沿觸發*/
static
intrequest_irqs
(void)}
return0;
}
中斷釋放函式
/*釋放中斷*/
static
void
free_irqs
(void
)}
在鍵被按下後,將發生中斷,在中斷處理程式中,應該關閉中斷進入查詢模式,延遲 20ms 以實現去抖動這個中斷處理過程只包含頂半部,無底半部。
static
void
s3c2410_eint_key
(int irq,
void
*dev_id,
struct pt_regs *reg)
在定時器處理程式中,查詢按鍵是否仍然被按下,如果是被按下的狀態,則將該按鍵記錄入緩衝區。同時啟動新的定時器延遲,延遲乙個相對於去抖更長的時間(如100ms),每次定時器到期後,查詢按鍵是否仍然處於按下狀態,如果是,則重新啟用新的 100ms 延遲;若查詢到已經沒有按下,則認定鍵已抬起,這個時候應該開啟對應按鍵的中斷,等待新的按鍵。每次記錄新的鍵值時,應喚醒等待佇列。
定時器處理函式
static
void
key_timer_handler
(unsigned
long data)
else
}else
//鍵已抬起
按鍵裝置驅動的讀函式主要提供對按鍵裝置結構體中緩衝區的讀並複製到使用者空間。當keydev.head ! = keydev.tail 時,意味著緩衝區有資料,使用 copy_to_user()拷貝到使用者空間,否則,根據使用者空間是阻塞讀還是非阻塞讀,分為如下兩種情況。
l 若採用非阻塞讀,則因為沒有按鍵快取,直接返回- eagain;
l 若採用阻塞讀,則在 keydev.wq 等待佇列上睡眠,直到有按鍵被記錄入緩衝區後被喚醒。
驅動讀函式
static ssize_t s3c2410_key_read
(struct file *filp,
char
*buf, ssize_t count,loff_t*ppos)
else
interruptible_sleep_on(&
(keydev.wq));
//使用者採用阻塞方式讀取,呼叫該函式使程序睡眠
goto retry;
}return0;
}
在裝置驅動的開啟函式中,keyevent 被賦值為 keyevent_raw,這個函式完成記錄鍵值, 並使用 wait_up_interrupt(&(keydev.wq))語句喚醒 s3c2410_key_read()第 17 行所期待的等待佇列。而 keyread()函式則直接從按鍵緩衝區中讀取鍵值。 裝置驅動例項 字元裝置驅動
在整個linux裝置驅動學習中,字元裝置驅動較為基礎。通過對它的學習,對裝置驅動進一步加深了解 cdev 結構體struct cdev 講下比較重要的成員變數 dev t dev 定義了32位的裝置號,其中12位是主裝置號,20位是從裝置號。獲取主裝置號 major dev t dev 獲取從裝置號...
Linux 驅動篇 字元驅動裝置01(框架篇)
定義乙個file operations結構體型別的變數 並填充owner函式 open函式 write函式 static int drvledopen struct inode inode,struct file file static ssize t drvledwrite struct file...
Linux驅動開發之字元裝置驅動例項
1 驅動標頭檔案mem dev.h ifndef memdev h define memdev h ifndef memdev major define memdev major 238 預設的mem的主裝置號 endif ifndef memdev nr devs define memdev nr...