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 style="white-space:pre"> </span>/*<span style="white-space:pre"> </span>不会立即休眠<span style="white-space:pre"> </span>*/
if (gk_modules_wait_event_flag)
mask |= POLLIN | POLLRDNORM;
return mask;
}
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 style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">#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);
}
}