1. 程式人生 > >linux裝置驅動 按鍵幾種寫法總結

linux裝置驅動 按鍵幾種寫法總結

對於基礎按鍵的驅動,有如下幾種寫法:

(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子系統