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)在驅動中異步通知fasynca.在驅動中定義以下函數,驅動需要知道信號量發給誰
#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);
}
}