linux裝置驅動 按鍵幾種寫法總結
阿新 • • 發佈:2018-11-05
對於基礎按鍵的驅動,有如下幾種寫法:
(1)查詢
所謂查詢方法,主要描述應用程式會在while(1)裡面一直read,如果沒有資料會導致阻塞,佔用CPU;這種方法是最差的。
(2)中斷
中斷配合休眠會避免查詢法佔用CPU的缺點。
應用程式和查詢法沒有什麼區別, 但是驅動裡面的read函式會呼叫wait_event_interruptible, 直到按鍵產生中斷並在中斷裡面喚醒,此時read會把資料返回給使用者程式。
(3)poll
poll機制和上面中斷方式差不多, 在應用程式裡面基本結構是:
while(1) { ret= poll(fds, 1, 5000); if(ret == 0) { printf("time out .\n"); } else { read(fd, &key_vals, 1); ... } }
應用程式呼叫poll, 對於驅動程式裡面的file_operations->poll, file_operations->poll裡面首先呼叫poll_wait, 而poll_wait不會立即導致休眠。
驅動程式相對於中斷方式來說,file_operations需要實現poll函式,如下:
static unsigned int buttons_poll (struct file *file, struct poll_table_struct *wait) { unsigned int mask = 0; poll_wait(file, &buttons_waitq, wait); // 不會立即休眠 if (press_event) mask |= POLLIN | POLLRDNORM; return mask; }
(4)非同步通知
上面三種對於應用程式來說,本質上都是查詢,因為都在while(1)裡面實現read按鍵值。非同步通知指驅動程式主動通知應用程式。
應用程式裡面:
signal(SIGIO, my_signal_handler); void my_signal_handler(int sigid) { ... }
fcntl(fd, F_SETOWN, getpid());
Oflags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, Oflags | FASYNC);
對應驅動程式裡面需要實現file_operation->fasync
static int buttons_fasync (int fd, struct file *filp, int on) { return fasync_helper (fd, filp, on, &buttons_async); // 註冊 }
相關中斷裡面傳送訊號
kill_fasync (&buttons_async, SIGIO, POLL_IN);
(5)input子系統