linux 驱动函数简介

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 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;
}


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 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);
	}
}












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值