https://blog.csdn.net/harmonycommunity/article/details/108796421?utm_medium=distribute.pc_feed.45562

本文介绍了Linux系统中驱动程序与应用程序通过异步通知进行通信的方式,特别是SIGIO信号的使用。应用程序需要注册SIGIO信号处理函数,打开设备节点,设置FASYNC标志,以便在驱动有IO事件时接收到通知。通过fcntl函数,APP可以将自己的PID告诉驱动,并启用异步通知功能。当驱动发出SIGIO信号时,APP将执行预设的信号处理函数,处理IO事件。
摘要由CSDN通过智能技术生成
功能介绍
所谓同步,就是“你慢我等你”。
那么异步就是:你慢那你就自己玩,我做自己的事去了,有情况再通知我。
所谓异步通知,就是 APP 可以忙自己的事,当驱动程序用数据时它会主动给 APP 发信号,这会导致 APP执行信号处理函数。
仔细想想“发信号”,这只有 3 个字,却可以引发很多问题:
① 谁发:驱动程序发
② 发什么:信号
③ 发什么信号:SIGIO
④ 怎么发:内核里提供有函数
⑤ 发给谁:APP,APP 要把自己告诉驱动
⑥ APP 收到后做什么:执行信号处理函数
⑦ 信号处理函数和信号,之间怎么挂钩:APP 注册信号处理函数

小孩通知妈妈的事情有很多:饿了、渴了、想找人玩。
Linux 系统中也有很多信号,在 Linux 内核源文件 include\uapi\asm-generic\signal.h 中,有很多信号的宏定义:
在这里插入图片描述
驱动程序通知 APP 时,它会发出“SIGIO”这个信号,表示有“IO 事件”要处理。
就 APP 而言,你想处理 SIGIO 信息,那么需要提供信号处理函数,并且要跟 SIGIO 挂钩。这可以通过一个 signal 函数来“给某个信号注册处理函数”,用法如下:
在这里插入图片描述
除了注册 SIGIO 的处理函数,APP 还要做什么事?想想这几个问题:

① 内核里有那么多驱动,你想让哪一个驱动给你发 SIGIO 信号?
APP 要打开驱动程序的设备节点。

② 驱动程序怎么知道要发信号给你而不是别人?
APP 要把自己的进程 ID 告诉驱动程序。

③ APP 有时候想收到信号,有时候又不想收到信号:
应该可以把 APP 的意愿告诉驱动:设置 Flag 里面的 FASYNC 位为 1,使能“异步通知”。

应用编程
应用程序要做的事情有这几件:

① 编写信号处理函数:

static void sig_func(int sig)
{
int val;
read(fd, &val, 4);
printf(“get button : 0x%x\n”, val);
}

1
2
3
4
5
6

② 注册信号处理函数:

signal(SIGIO, sig_func);

1

③ 打开驱动:

fd = open(argv[1], O_RDWR);

1

④ 把进程 ID 告诉驱动:

fcntl(fd, F_SETOWN, getpid());

1

⑤ 使能驱动的 FASYNC 功能:

flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, flags | FASYNC);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值