Linux学习——异步通知机制

之前使用的中断+poll机制都是应用程序主动去调用read函数,有另外一种方法就是当按键按下时驱动触发应用程序取读取键值,该方法叫做异步通知。

进程之间要发信号需要明确:

①注册一个信号处理函数(在应用程序里)

②哪个进程发信号(驱动程序)

③哪个进程接收信号(应用程序,应用程序要告诉驱动程序PID即应用程序的进程号)

④怎么发送信号(驱动程序里使用)

1.代码

2.用到的库函数

a.驱动程序里:

1、kill_fasync(struct fasync_struct **fp, int sig, int band)原型

void kill_fasync(struct fasync_struct **fp, int sig, int band)
{
	/* First a quick test without locking: usually
	 * the list is empty.
	 */
	if (*fp) {
		read_lock(&fasync_lock);
		/* reread *fp after obtaining the lock */
		__kill_fasync(*fp, sig, band);
		read_unlock(&fasync_lock);
	}
}

使用;

kill_fasync(&button_async_queue, SIGIO, POLL_IN);

SIGIO:代表可以对IO口进行读写操作,还可以有其他值,在asm-arm/signal.h文件里定义其他值

POLL_IN:代表有数据已读取

2.定义全局变量:

static struct fasync_struct *button_async_queue;

3.对上面定义的结构体进行初始化:

static int fifth_drv_fasync(int fd, struct file *filp, int on)
{
	return fasync_helper(fd, filp, on, &button_async_queue);
}

/* fasync_helper会进行初始化 */ 

之后在file_operations多定义一个成员函数 例:.fasync     =  fifth_drv_fasync

4.在中断服务程序里调用kill_fasync( )函数 

b.应用程序里:

1.信号注册函数signal( ):将用户写的处理函数注册到内核里面

signal(SIGIO, signal_fun);

SIGIO:同上
signal_fun:自己写的处理函数

2.决定发给谁,如何调用

/* 得到进程号之后告诉内核应该发给哪个进程 */
fcntl(fd, F_SETOWN, getpid());

/* 标志位预改变 */
oflags = fcntl(fd, F_GETFL);

/* 改变tasync标记,最终会调用到驱动程序的
 * fasync > fasync_helper:初始化/释放fasync_struct 
 */
fcntl(fd, F_SETFL, oflags | FASYNC);
/* “fcntl(fd, F_SETFL, Oflags | FASYNC);”接口被调用时,     
 * 在函数中的“fasync_helper()”就会被调用
 */

3.信号处理函数

void signal_fun(int signum)
{
	unsigned char key_val;
	read(fd, &key_val, 1);
	printf("key_val:0x%x\n", key_val);
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值