fasync driver demo

Linux系统中的fasync用于设备驱动程序与用户空间之间的异步通信。它允许设备驱动程序通知用户空间的进程,当设备状态发生变化时,通过发送SIGIO信号来告知进程。

具体来说,设备驱动程序可以调用fasync_helper()函数来注册一个或多个进程,当设备状态发生变化时,内核会自动发送SIGIO信号给这些进程。而用户空间进程可以通过调用fcntl()函数,并设置F_SETOWN标志来接收SIGIO信号。一旦接收到SIGIO信号,进程就可以执行相应的处理操作,如读取设备数据或进行其他操作。

通过使用fasync,设备驱动程序可以避免阻塞用户进程,可以实现非阻塞I/O操作,提高系统的响应性能。

下面实现的是打开设备文件并启用异步通知功能,然后进入一个无限循环中,等待接收SIGIO信号的触发。当设备发生变化时,设备驱动程序会发送SIGIO信号给这个用户空间程序,触发fasync_handler函数的执行,从而可以进行相应的处理操作。

#include<sys/types.h>
#include<unistd.h>
#include<fcntl.h>
#include<linux/rtc.h>
#include<linux/ioctl.h>
#include<stdio.h>
#include<stdlib.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>int fd;
void fasync_handler(int num)
{printf("fasync_handler entering\n");
}void main()
{int i=2;char data[256];int oflags=0;int retval;signal(SIGIO, fasync_handler);fd=open("/dev/fcn",O_RDWR);if(fd==-1){perror("error open\n");exit(-1);}printf("open /dev/fcn successfully\n");//使能了异步的通知到当前进程fcntl(fd, F_SETOWN, getpid());oflags=fcntl(fd, F_GETFL);fcntl(fd, F_SETFL, oflags | FASYNC);while(1);close(fd);
}

demo.c ​​​​​​​

  1. 下面代码定义了一个名为simple_dev的结构体,用于表示设备的相关信息。在模块加载时,通过register_chrdev_region()函数请求一个主设备号。

  2. 创建并初始化一个simple_dev结构体,然后通过cdev_init()函数对其进行初始化。

  3. 调用cdev_add()函数将字符设备添加到系统中。定义了简单的设备操作函数,包括打开设备(simple_open)、关闭设备(simple_release)和异步通知(simple_fasync)。

  4. 初始化一个定时器simple_timer,当时间到达时,会调用simple_timer_handler函数。

  5. 在simple_open函数中,将定时器添加到内核定时器列表中,并启动定时器。

  6. 在simple_fasync函数中,通过fasync_helper函数将当前进程添加到异步通知队列fasync_queue中。

  7. 在simple_release函数中,调用simple_fasync函数取消异步通知。

  8. 模块卸载时,通过cdev_del()函数删除字符设备,释放相关资源。


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/cdev.h>
#include <linux/version.h>
#include <linux/vmalloc.h>
#include <linux/ctype.h>
#include <linux/pagemap.h>
#include <linux/delay.h>#include <asm/io.h>
#include <asm/irq.h>
#include <asm/signal.h>
#include <asm/uaccess.h>#include "demo.h"MODULE_AUTHOR("fgj");
MODULE_LICENSE("Dual BSD/GPL");struct simple_dev *simple_devices;
static unsigned char simple_inc=0;
static struct timer_list simple_timer;
static struct fasync_struct *fasync_queue=NULL;static void simple_timer_handler( unsigned long data)
{printk("simple_timer_handler...\n");if (fasync_queue){//POLL_IN可读,POLL_OUT为可写kill_fasync(&fasync_queue, SIGIO, POLL_IN);printk("kill_fasync...\n");}return ;
}int simple_open(struct inode *inode, struct file *filp)
{struct simple_dev *dev;dev = container_of(inode->i_cdev, struct simple_dev, cdev);filp->private_data = dev;simple_timer.function = &simple_timer_handler;simple_timer.expires = jiffies + 2*HZ;add_timer (&simple_timer);printk("add_timer...\n");return 0;
}static int simple_fasync(int fd, struct file * filp, int mode) 
{int retval;printk("simple_fasync...\n");retval=fasync_helper(fd,filp,mode,&fasync_queue);if(retval<0)return retval;return 0;
}int simple_release(struct inode *inode, struct file *filp)
{simple_fasync(-1, filp, 0);return 0;
}struct file_operations simple_fops = {.owner =    THIS_MODULE,.open =     simple_open,.release=   simple_release,.fasync=    simple_fasync,};/*******************************************************MODULE ROUTINE
*******************************************************/
void simple_cleanup_module(void)
{dev_t devno = MKDEV(simple_MAJOR, simple_MINOR);if (simple_devices) {cdev_del(&simple_devices->cdev);kfree(simple_devices);}unregister_chrdev_region(devno,1);
}int simple_init_module(void)
{int result;dev_t dev = 0;dev = MKDEV(simple_MAJOR, simple_MINOR);result = register_chrdev_region(dev, 1, "DEMO");if (result < 0) {printk(KERN_WARNING "DEMO: can't get major %d\n", simple_MAJOR);return result;}simple_devices = kmalloc(sizeof(struct simple_dev), GFP_KERNEL);if (!simple_devices){result = -ENOMEM;goto fail;}memset(simple_devices, 0, sizeof(struct simple_dev));cdev_init(&simple_devices->cdev, &simple_fops);simple_devices->cdev.owner = THIS_MODULE;simple_devices->cdev.ops = &simple_fops;result = cdev_add (&simple_devices->cdev, dev, 1);if(result){printk(KERN_NOTICE "Error %d adding DEMO\n", result);goto fail;}init_timer(&simple_timer);return 0;fail:simple_cleanup_module();return result;
}module_init(simple_init_module);
module_exit(simple_cleanup_module);

demo.h

#ifndef _simple_H_
#define _simple_H_#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later *//********************************************************* Macros to help debugging********************************************************/
#undef PDEBUG             /* undef it, just in case */
#ifdef simple_DEBUG
#ifdef __KERNEL__
#    define PDEBUG(fmt, args...) printk( KERN_DEBUG "DEMO: " fmt, ## args)
#else//usr space
#    define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
#endif
#else
#  define PDEBUG(fmt, args...) /* not debugging: nothing */
#endif#undef PDEBUGG
#define PDEBUGG(fmt, args...) /* nothing: it's a placeholder *///设备号
#define simple_MAJOR 226
#define simple_MINOR 0
#define COMMAND_LEDON 1
#define COMMAND_LEDOFF 2//设备结构
struct simple_dev 
{struct cdev cdev;	  /* Char device structure		*/
};//函数申明
ssize_t simple_read(struct file *filp, char __user *buf, size_t count,loff_t *f_pos);
ssize_t simple_write(struct file *filp, const char __user *buf, size_t count,loff_t *f_pos);
loff_t  simple_llseek(struct file *filp, loff_t off, int whence);
int     simple_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg);#endif /* _simple_H_ */

上述代码的实现了一个简单的字符设备驱动程序,并使用定时器实现了异步通知功能,通过调用fasync_helper函数将进程添加到异步通知队列中,当定时器时间到达时,会发送SIGIO信号给进程,以实现类似中断的功能。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/9070.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

静态 链接

1、空间与地址的分配 现在的链接器空间分配的策略基本上都采用 “相似段合并” 的方式。通过将所有相同类型的 section 合并到一起&#xff0c;例如将所有输入目标文件的 .text 合并&#xff08;按顺序合并&#xff09;到输出文件的 .text 节中&#xff1b;然后&#xff0c;链接…

第111天:免杀对抗-JavaASM汇编CS调用内联CMSF源码特征修改Jar打包

知识点 #知识点&#xff1a; 1、ASM-CS-单汇编&内联C 2、JAVA-MSF-源码修改&打包#章节点&#xff1a; 编译代码面-ShellCode-混淆 编译代码面-编辑执行器-编写 编译代码面-分离加载器-编写 程序文件面-特征码定位-修改 程序文件面-加壳花指令-资源 代码加载面-Dll反射…

自动驾驶技术架构

自动驾驶技术架构 自动驾驶技术架构 自动驾驶关键技术 自动驾驶汽车技术架构较为复杂&#xff0c;涉及了多领域的交叉互容&#xff0c;例如汽车、交通、通信等&#xff0c;基于自动驾驶相关的软硬件、辅助开发工具、行业标准等各方面关键问题&#xff0c;自动驾驶汽车关键技术…

CB(CBScript)如何实现两个关键字相加?

下载地址:CBScript 为自己的软件增加脚本编写功能并自定义API 如示例代码: [TestMethod()]public void Script_Args_DataTable_Select(){string script "COLACOLB";DataTable table new DataTable();table.Columns.Add("COLA");table.Columns.Add("…

深度学习(二)

目录 一、神经网络 整体架构: 架构细节: 神经元个数的影响: 神经网络过拟合解决: 卷积网络 整体架构: 卷积层 边缘填充 特征尺寸计算 池化层 特征图变化 递归神经网络 一、神经网络 整体架构: 图中分别为输入层、隐层1、隐层2、输出层 通过输入层输入某数值&#xf…

机器学习之线性判别分析(Linear Discriminant Analysis)

1 线性判别分析介绍 1.1 什么是线性判别分析 线性判别分析&#xff08;Linear Discriminant Analysis&#xff0c;简称LDA&#xff09;是一种经典的监督学习算法&#xff0c;也称"Fisher 判别分析"。LDA在模式识别领域&#xff08;比如人脸识别&#xff0c;舰艇识别…

3.2.20:DTP与Datepicker实现日期的输入

【分享成果&#xff0c;随喜正能量】人生艰难自不必去回避&#xff0c;人生艰难说多了也是白说&#xff0c;为什么&#xff0c;解决不了问题&#xff0c;说了也还是那么难。。 我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高…

【电子设计大赛】2023 年全国大学生电子设计竞赛 仪器和主要元器件清单

2023 年全国大学生电子设计竞赛仪器设备和主要元器件及器材清单 [本科组] 1. 仪器设备清单 直流稳压电源&#xff08;具有恒流/恒压模式自动切换功能&#xff0c;0~30V/3A&#xff0c;双路&#xff09; 数字示波器&#xff08;100MHz&#xff0c; 双通道&#xff09; 函数发…

每日一题——多数元素

多数元素 题目链接 方法一&#xff1a;暴力解法 直接利用两层循环&#xff0c;外层循环用来枚举数组的每一个元素&#xff0c;内层循环用来计算每个元素出现的次数&#xff0c;这样就可以求出多数元素了。 显然&#xff0c;这个方法的时间复杂度为O(N^2)&#xff0c;效率太低…

关于项目,会问我什么?

作者&#xff1a;阿秀 校招八股文学习网站&#xff1a;https://interviewguide.cn 这是阿秀的第「288」篇原创 小伙伴们大家好&#xff0c;我是阿秀。 在校招求职这块&#xff0c;简历上比较重要的点就是教育背景、实习经历、项目经验三块&#xff0c;其中教育背景都到了秋招这…

C++初阶之一篇文章让你掌握string类(了解和使用)

string类及其模拟实现 1.我们为什么要学习string类2. 标准库中的string类2.1 string类的实例化标准2.2 了解string 3.string类的常用接口说明3.1 string类对象的常见构造3.2 string类对象的容量操作3.3 string类对象的元素访问3.4 string类对象的Iterators&#xff08;迭代器&a…

CVPR2023新作:3D视频物体检测

Title: 3D Video Object Detection With Learnable Object-Centric Global Optimization Affiliation: 中国科学院自动化研究所 (Institute of Automation, Chinese Academy of Sciences)&#xff0c;中国科学院大学人工智能学院 (School of Artificial Intelligence, Univers…

网络安全合规与标准的主要发展方向

网络安全合规就是避免违反网络安全有关的法律、法规、规章、合同义务以及任何安全要求&#xff0c;标准在网络安全合规工作中扮演着重要的角色。 一、标准在网络安全合规体系中的地位作用 网络安全合规体系包括网络安全有关的法律、法规、规章、其他规范性文件、及合同义务等…

详细解析黑马微信小程序视频--【思维导图知识范围】

语言视频选择收录专辑链接C张雪峰推荐选择了计算机专业之后-在大学期间卷起来-【大学生活篇】JAVA黑马B站视频JAVA部分的知识范围、学习步骤详解JAVAWEB黑马B站视频JAVAWEB部分的知识范围、学习步骤详解SpringBootSpringBoot知识范围-学习步骤【JSB系列之000】微信小程序详细解…

《深度解析Docker与微服务架构:构建灵活可扩展的现代应用》

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

通过 API 远程管理 Jenkins

目录 前言&#xff1a; 背景介绍 Jenkins Remote API 的简介 Jenkins Remote API 的调用 Read More ... 前言&#xff1a; Jenkins 是一种开源的持续集成工具&#xff0c;可以帮助我们更加方便地进行软件开发和测试工作。通过 API 远程管理 Jenkins 可以帮助我们更加方便…

在家下载论文使用哪些论文下载工具比较好

在家下载论文如果不借助论文下载工具是非常艰难的事情&#xff0c;因为很多查找下载论文的数据库都是需要账号权限才可使用的。 例如&#xff0c;我们查找中文论文常用的知网、万方等数据库以及众多国外论文数据库。 在家下载知网、万方数据库论文可用下面的方法&#xff1a;…

SpringCloudAlibaba微服务实战系列(三)Sentinel1.8.0+流控

SpringCloudAlibaba–Sentinel Sentinel被称为分布式系统的流量防卫兵&#xff0c;是阿里开源流量框架&#xff0c;从服务限流、降级、熔断等多个纬度保护服务。Sentinel同时提供了简洁易用的控制台&#xff0c;可以看到接入应用的秒级数据&#xff0c;并可以在控制台设置一些…

【Java】微服务负载均衡算法实现

前言 本篇实现一下分布式中负载均衡的实现策略&#xff0c;以及负载均衡算法是如何实现的。 什么是负载均衡&#xff1f; Java负载均衡是指在多台服务器之间分配负载&#xff0c;以提高服务器的性能和可用性。它通过将请求分发到多台服务器来减少单个服务器的压力&#xff0…

Guitar Pro8吉他谱制作软件好不好用?

吉他谱是学习和演奏吉他的重要工具之一&#xff0c;对于吉他爱好者而言&#xff0c;掌握一款优秀的吉他谱制作软件是必不可少的。随着科技的进步&#xff0c;现在有许多吉他谱制作软件可供选择。下面我们就来看吉他谱制作软件哪个好&#xff0c;以及怎么制作吉他谱子吧&#xf…