按鍵驅動程式(非同步通知)

2021-09-07 12:13:04 字數 3614 閱讀 4807

此驅動程式之前的按鍵驅動程式(中斷方式)上加以優化。用到非同步通知。對於核心來講,既然使用者想得到的是按鍵後的狀態,那麼自然不必時時都要read狀態。當它檢測到中斷發生變主動通知使用者,使用者再來讀。這樣,使用者空間、核心就可以著手幹點其它的事情,而不必忙等按鍵按下或釋放。那麼就先從應用程式上面看。

怎麼設定相關聯到「非同步通知」呢?

flag = fcntl(fd, f_getfl);

fcntl(fd, f_setfl, flag|fasync);

這樣的兩句就可以將檔案描述符fd與非同步通知關聯,到時候將會接到相關通知。

怎麼知道通知道本程式呢?

fcntl(fd, f_setown, getpid());

將其與程序號關聯,這樣核心就知道要將通知發往本程序。

得到通知後該怎麼做呢?

sighandler_t signal(int signum, sighandler_t handler);

後面的handler是接到訊號後的處理函式,而對於一般的io操作,signum通常為sigio,這點在核心驅動中要保持一致。handler的定義為

typedef void (*sighandler_t)(int); 在這個函式體內就可以去read資料了。

詳細的驅動程式為:

[plain]view plain

copy

print?

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#define fifthdev mkdev(250, 0)  

struct cdev fifthdrv_cdev;  

static struct class *fifthdrv_class;  

struct button ;  

//static volatile int pressed = 0;  

static unsigned char key_val;  

struct fasync_struct *button_async;  

//declare_wait_queue_head(button_wqh);  

/* 六個按鍵的相關定義整合到結構體 */  

static struct button buttons[6] = ,  

,  ,  

,  ,  

,  };  

/* 中斷處理函式 */  

static irqreturn_t fifthdrv_intr(int irq, void *data)  

else   

//pressed = 1; //此處改變按下標誌,以使佇列不繼續睡眠  

//wake_up_interruptible(&button_wqh);  

kill_fasync(&button_async, sigio, poll_in);  

return irq_retval(irq_handled);  

}  static int fifthdrv_open(struct inode * inode, struct file * file)  

return 0;  

}  static ssize_t fifthdrv_read(struct file *file, char __user *user, size_t size,loff_t*o)  

/* 使用非同步通知,此處不必休眠 */  

//wait_event_interruptible(button_wqh, pressed);  

copy_to_user(user, &key_val, sz);  

/* 重新清除按下標誌 */  

//pressed = 0;  

return sz;  

}  static int fifthdrv_close(struct inode *inode, struct file *file)  

return 0;  

}  /*  

static unsigned int fifthdrv_poll(struct file *file, poll_table *wait)  

return res;  

}  */  

static int fifthdrv_fasync(int fd, struct file *filp, int on)  

static struct file_operations fifthdrv_ops = ;  

static int fifthdrv_init(void)  

fifthdrv_class = class_create(this_module, "fifthdrv_class");  

if (is_err(fifthdrv_class))   

device_create(fifthdrv_class, null, devt, null, "buttons");  

cdev_init(&fifthdrv_cdev, &fifthdrv_ops);  

ret = cdev_add(&fifthdrv_cdev, devt, 1);  

if (ret 

goto fail_cdev;  

return 0;  

fail_cdev:  

class_unregister(fifthdrv_class);  

device_destroy(fifthdrv_class, devt);  

cdev_del(&fifthdrv_cdev);  

fail:  

unregister_chrdev_region(devt, 1);  

return 0;  

}  static void fifthdrv_exit(void)  

module_init(fifthdrv_init);  

module_exit(fifthdrv_exit);  

module_license("gpl");  

應用程式為:

#include 

#include 

#include 

#include 

#include 

int fd;

void signal_f(int signum)

int main(int argc, char *ar**) 

signal(sigio, signal_f);

fcntl(fd, f_setown, getpid());

flag = fcntl(fd, f_getfl);

fcntl(fd, f_setfl, flag|fasync);

while (1)

return 0;}

執行狀態:

本文**:

字元裝置驅動程式 非同步通知

1.各種讀取按鍵值的方式比較 查詢 耗cpu資源 中斷 在應用程式中的read函式一直會休眠,直到有中斷發生。poll 在一段時間內跟中斷相同,但是超時之後read函式會返回。三種共同點 應用程式主動去讀取按鍵的狀態。2.驅動程式主動去提醒應用的方式 非同步通知 實現方式 signal 舉例 kil...

基於非同步通知機制的按鍵驅動

按下按鍵是驅動程式通知應用程式 應用程式裡面要註冊訊號處理函式 驅動程式給應用程式發訊號 發給誰,這就要應用程式告訴驅動pid了 怎麼發,是驅動裡面呼叫kill fasync 為了使裝置支援非同步通知機制,驅動程式涉及以下3項工作 1.支援f setown命令,能在這個控制命令處理中設定filp f...

中斷 按鍵中斷驅動程式

中斷處理 1 外設的處理速度一般慢於 cpu。2 cpu不能一直等待外部事件,所以裝置必須有一種方法來通知 cpu它的工作進度,這個方法就是中斷,外設與 cpu資訊互動的機制,提高 cpu利用率。處理之外還有查詢,但是查詢會一直占有 cpu資源,導致 cpu低利用率,好處是實現簡單。linux系統中...