1)在驅動中使用 DECLARE_WAIT_QUEUE_HEAD ;進程加入等待隊列
a.增加頭文件 #include <linux/sched.h>
b.定義以下變量
①.static DECLARE_WAIT_QUEUE_HEAD(gk_modules_wait_event);
②.static volatile int gk_modules_wait_event_flag = 0;
c.在函數A中調用以下函數,若 gk_modules_wait_event_flag = 0; 函數A進入休眠
①.wait_event_interruptible(gk_modules_wait_event, gk_modules_wait_event_flag);
d.在中斷函數B或其他函數B運行時;先置 gk_modules_wait_event_flag = 1; 再調用以下函數就能喚醒函數A
①.wake_up_interruptible(&gk_modules_wait_event);
2)在驅動中使用 poll 機制
備注: Poll機制會判斷fds中的文件是否可讀,如果可讀則會立即返回,
返回的值就是可讀fd的數量,如果不可讀,那麼就進程就會休眠timeout 這麼長的時間,
然後再來判斷是否有文件可讀,如果有,返回fd的數量,如果沒有,則返回0.
返回表示是否能對設備進行無阻塞可讀或可寫訪問的掩碼;
位掩碼:POLLRDNORM, POLLIN,POLLOUT,POLLWRNORM
設備可讀,通常返回:(POLLIN | POLLRDNORM)
設備可寫,通常返回:(POLLOUT | POLLWRNORM)
a.在驅動中定義以下函數;
若poll指向的函數返回當前可否讀寫的信息。
如果當前可讀寫,返回讀寫信息。
如果當前不可讀寫,則阻塞進程,並等待驅動程序喚醒,重新調用poll函數,或超時返回。
若gk_modules_wait_event_flag為1,則返回文件可讀,若為0則返回0,文件不可讀
static unsigned int gk_modules_dev_poll(struct file *file, poll_table *wait) { unsigned int mask = 0; poll_wait(file, &gk_modules_wait_event, wait); <span > </span>/*<span > </span>不會立即休眠<span > </span>*/ if (gk_modules_wait_event_flag) mask |= POLLIN | POLLRDNORM; return mask; }b.在驅動測試程序中包含#include <poll.h>
struct pollfd fds[1]; fds[0].fd = fd; fds[0].events = POLLIN; ret = poll(fds, 1, 10000); if (ret == 0) { printf("time out\n"); } else { /* 用戶程序 */ }3)在驅動中異步通知fasync
a.在驅動中定義以下函數,驅動需要知道信號量發給誰
#include <linux/poll.h>
static struct fasync_struct *gk_modules_async;
static int gk_modules_dev_fasync (int fd, struct file *filp, int on) { return fasync_helper (fd, filp, on, &gk_modules_async); }b.驅動中發送信號量
kill_fasync(&gk_modules_async,SIGIO,POLL_IN);c.應用程序中定義,當驅動中調用發送信號量函數時,my_signal_fun(),函數被調用
<span >#include <fcntl.h></span>
void my_signal_fun(void) { printf("call my_signal_fun\n"); } int main(int argc, char **argv) { int Oflags; fd = open("/dev/gk_modules", 2); /* 打開設備*/ signal(SIGIO, my_signal_fun); fcntl(fd, F_SETOWN, getpid()); Oflags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, Oflags | FASYNC); while(1){ sleep(2); } }