poll是乙個系統呼叫,其核心入口函式為sys_poll,sys_poll差點兒不做不論什麼處理直接呼叫do_sys_poll,do_sys_poll的執行過程能夠分為三個部分:
1,將使用者傳入的pollfd陣列複製到核心空間,由於拷貝操作和陣列長度相關。時間上這是乙個o(n)操作,這一步的**在do_sys_poll中包含從函式開始到呼叫do_poll前的部分。
2,查詢每乙個檔案描寫敘述符相應裝置的狀態,假設該裝置尚未就緒,則在該裝置的等待佇列中增加一項並繼續查詢下一裝置的狀態。
查詢全然部裝置後假設沒有乙個裝置就緒,這時則須要掛起當前程序等待。直到裝置就緒或者超時,掛起操作是通過呼叫schedule_timeout執行的。裝置就緒後程序被通知繼續執行,這時再次遍歷全部裝置,以查詢就緒裝置。這一步由於兩次遍歷全部裝置。時間複雜度也是o(n),這裡面不包含等待時間。相關**在do_poll函式中。
3,將獲得的資料傳送到使用者空間並執行釋放記憶體和剝離等待佇列等善後工作,向使用者空間拷貝資料與剝離等待佇列等操作的的時間複雜度相同是o(n),詳細**包含do_sys_poll函式中呼叫do_poll後到結束的部分。
static struct file_operations button_sdv_fops =
;
static unsigned int button_dev_poll(struct file *file, poll_table * wait)
常量
說明
pollin
普通或優先順序帶資料可讀
pollrdnorm
普通資料可讀
pollrdband
優先順序帶資料可讀
pollpri
高優先順序資料可讀
pollout
普通資料可寫
pollwrnorm
普通資料可寫
pollwrband
優先順序帶資料可寫
pollerr
錯誤發生
pollhup
發生掛起
pollnval
描寫敘述字不是乙個開啟的檔案
ret = poll(fds, 1, 3000);
poll函式原型:
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
當中:pollfd結構體為:
struct pollfd ;
fd是要查詢的裝置。events是期望獲得的事件,這裡我們將他設定為:pollin
fds定義乙個陣列,存放須要poll的全部裝置。poll操作會同一時候查詢這些裝置。
nfds為查詢的檔案數量
timeout為超時時間
#include #include #include #include #include #include #include #include #include #include #include #include //這個在/opt/embedsky/linux-2.6.30.4/arch/arm/mach-s3c2410/include/mach 路徑
#include #include module_license("dual bsd/gpl");
static struct class *buttondrv_class;
static struct class_devices *buttondrv_class_dev;
/* */
static declare_wait_queue_head(button_wait_q);
/*中斷事件標誌,中斷服務程式將他置1,read函式將他置0*/
static volatile int ev_press =0;
volatile unsigned long *gpfcon = null;
volatile unsigned long *gpfdat = null;
static unsigned keyval;
struct pin_desc;
/*按鍵按下時是:0x01 0x02 0x03 0x04*/
/*按鍵鬆開時是:0x81 0x82 0x83 0x84*/
struct pin_desc pins_desc[4] =, ,
, ,};/*
* 確定按鍵值
*/static irqreturn_t buttons_irq(int irq,void *dev_id)
else
ev_press =1;//中斷發生
wake_up_interruptible(&button_wait_q);
printk("button is pressed : %d \n",irq);
return irq_handled;
}static int button_dev_open(struct inode *inode ,struct file* file)
ssize_t button_dev_read(struct file *file,char __user *buf,size_t size,loff_t *ppos)
/*假設沒有按鍵動作發生 就休眠*/
wait_event_interruptible(button_wait_q,ev_press);
/*假設有按鍵動作發生,直接返回*/
copy_to_user(buf,&keyval,1);
ev_press = 0;
return 0;
}int button_dev_close(struct inode* inode ,struct file *file)
static unsigned int button_dev_poll(struct file *file, poll_table * wait)
static struct file_operations button_sdv_fops =
;int major;
static int button_dev_init(void)//入口函式
static void button_dev_exit(void)
module_init(button_dev_init);
module_exit(button_dev_exit);
#include #include #include #include #include int main(int argc, char **ar**)
fds[0].fd = fd;
fds[0].events = pollin;
while(1)
else
}return 0;
}
poll函式 Linux驅動基石之POLL機制
在前面引入中斷時,我們曾經舉過乙個例子 媽媽怎麼知道臥室裡小孩醒了?時不時進房間看一下 查詢方式 簡單,但是累 進去房間陪小孩一起睡覺,小孩醒了會吵醒她 休眠 喚醒 不累,但是媽媽幹不了活了 媽媽要幹很多活,但是可以陪小孩睡一會,定個鬧鐘 poll方式 要浪費點時間,但是可以繼續幹活。媽媽要麼是被小...
Linux驅動之poll機制
驅動程式 include 模組有關的 include 核心有關的 include 檔案系統有關的 include include include include include include linux中斷 include include include include copy to user ...
linux驅動編寫之poll機制
1.poll情景描述 以按鍵驅動為例進行說明,用阻塞的方式開啟按鍵驅動檔案 dev buttons,應用程式使用read 函式來讀取按鍵的鍵值。這樣做的效果是 如果有按鍵按下 了,呼叫該read 函式的程序,就成功讀取到資料,應用程式得到繼續執行 倘 若沒有按鍵按下,則要一直處於休眠狀態,等待這有按...