概述
前言
正在根据韦东山老师的视频和代码来学习写linux驱动,记录笔记在这里,方便复习与查阅
概述
异步通知机制能让驱动主动通知应用程序做某些事,而不需要应用程序不断查询驱动的状态来决定做什么事
如果想要要实现异步通知的功能
驱动程序需要做的事有:
- 新建一个信号并注册它
- 发送信号通知应用程序
应用程序需要做的事有:
- 收到信号后需要执行的函数
- 把这个函数与驱动程序的信号关联起来
疑问
- 应用程序的进程ID是不固定的,驱动如何知道要发送信号给谁?
解答疑问
- 应用程序需要执行某个函数调用驱动的fasync_helper函数
- fasync_helper会关联 应用程序进程 与 驱动程序的信号
- 之后,应用程序执行kill_fasync就能向应用程序进程发送信号
- 应用程序进程会根据信号类型,来执行对应注册的函数
参考资料http://blog.chinaunix.net/uid-20498191-id-1704861.html
知识点扩展
- kill_fasync 、fasync_helper
- signal、SIGIO
- fcntl
- getpid()
signal、SIGIO
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
这个博文写的非常好,可以看一看:
https://blog.csdn.net/weibo1230123/article/details/81505152
getpid()
获取当前pid
fcntl
fcntl函数的作用是改变已打开的文件性质
参考资料:https://www.cnblogs.com/zxc2man/p/7649240.html
个人理解下面几行代码可以 :
1、关联当前信号与进程ID
2、 给文件增加异步通知的文件状态标识
fcntl(fd, F_SETOWN, getpid());
Oflags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, Oflags | FASYNC);
fasync_helper
哪个进程调用了fasync_helper,kill_fasync就向哪个进程发信号
int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
kill_fasync用法
button_async通过fasync_helper关联到了应用程序上,kill_fasync根据这个就知道向谁发送数据了
kill_fasync (&button_async, SIGIO, POLL_IN);
贴上相关代码
在驱动程序中
//定义一个fasync_struct 类
static struct fasync_struct *button_async;
//调用这个函数发送信号通知应用程序
kill_fasync (&button_async, SIGIO, POLL_IN);
//fasync_helper作用就是初始化fasync,包括分配内存和设置属性
static int fifth_drv_fasync (int fd, struct file *filp, int on)
{
printk("driver: fifth_drv_fasyncn");
return fasync_helper (fd, filp, on, &button_async);
}
//通过file_operations 关联fifth_drv_fasync函数
static struct file_operations sencod_drv_fops = {
.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
.open = fifth_drv_open,
.read = fifth_drv_read,
.release = fifth_drv_close,
.poll = fifth_drv_poll,
.fasync = fifth_drv_fasync,
};
在应用程序中
void my_signal_fun(int signum)
{
unsigned char key_val;
read(fd, &key_val, 1);
printf("key_val: 0x%xn", key_val);
}
signal(SIGIO, my_signal_fun);
fd = open("/dev/buttons", O_RDWR);
if (fd < 0)
{
printf("can't open!n");
}
fcntl(fd, F_SETOWN, getpid());
Oflags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, Oflags | FASYNC);
最后
以上就是舒适鸵鸟为你收集整理的linux驱动学习笔记 异步通知前言概述疑问解答疑问知识点扩展贴上相关代码的全部内容,希望文章能够帮你解决linux驱动学习笔记 异步通知前言概述疑问解答疑问知识点扩展贴上相关代码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复