当前位置: 首页 > news >正文

Linux驱动开发——(八)Linux异步通知

目录

一、异步通知简介

二、信号处理

2.1 驱动程序中的处理

2.1.1 fasync_struct结构体

2.1.2 fasync操作函数

2.1.3 kill_fasync函数

2.2 应用程序中的处理

三、驱动代码


一、异步通知简介

异步通知的核心就是信号。信号类似于硬件上使用的中断,只不过信号是软件层次上的,算是在软件层次上对中断的一种模拟。

驱动可以通过主动向应用程序发送信号的方式来报告自己可以访问,应用程序获取到信号以后就可以从驱动设备中读取或者写入数据。整个过程就相当于应用程序收到了驱动发送过来了的一个“中断“,然后应用程序去响应这个”中断“。在整个处理过程中应用程序并没有去查询驱动设备是否可以访问,一切都是由驱动设备自己告诉给应用程序的。arch/xtensa/include/uapi/asm/signal.h文件中定义了Linux所支持的所有信号:

#define SIGHUP 1 /* 终端挂起或控制进程终止 */ 
#define SIGINT 2 /* 终端中断(Ctrl+C组合键) */ 
#define SIGQUIT 3 /* 终端退出(Ctrl+\组合键) */ 
#define SIGILL 4 /* 非法指令 */ 
#define SIGTRAP 5 /* debug使用,有断点指令产生 */ 
#define SIGABRT 6 /* 由abort(3)发出的退出指令 */ 
#define SIGIOT 6 /* IOT指令 */ 
#define SIGBUS 7 /* 总线错误 */ 
#define SIGFPE 8 /* 浮点运算错误 */ 
#define SIGKILL 9 /* 杀死、终止进程 */ 
#define SIGUSR1 10 /* 用户自定义信号1 */ 
#define SIGSEGV 11 /* 段违例(无效的内存段) */ 
#define SIGUSR2 12 /* 用户自定义信号2 */ 
#define SIGPIPE 13 /* 向非读管道写入数据 */ 
#define SIGALRM 14 /* 闹钟 */ 
#define SIGTERM 15 /* 软件终止 */ 
#define SIGSTKFLT 16 /* 栈异常 */ 
#define SIGCHLD 17 /* 子进程结束 */ 
#define SIGCONT 18 /* 进程继续 */ 
#define SIGSTOP 19 /* 停止进程的执行,只是暂停 */	
#define SIGTSTP 20 /* 停止进程的运行(Ctrl+Z组合键) */ 
#define SIGTTIN 21 /* 后台进程需要从终端读取数据 */ 
#define SIGTTOU 22 /* 后台进程需要向终端写数据 */ 
#define SIGURG 23 /* 有"紧急"数据 */ 
#define SIGXCPU 24 /* 超过CPU资源限制 */ 
#define SIGXFSZ 25 /* 文件大小超额 */ 
#define SIGVTALRM 26 /* 虚拟时钟信号 */ 
#define SIGPROF 27 /* 时钟信号描述 */ 
#define SIGWINCH 28 /* 窗口大小改变 */ 
#define SIGIO 29 /* 可以进行输入/输出操作 */ 
#define SIGPOLL SIGIO 
#define SIGPWR 30 /* 断点重启 */ 
#define SIGSYS 31 /* 非法的系统调用 */ 
#define SIGUNUSED 31 /* 未使用信号 */ 

在这些信号中,除了 SIGKILL(9)和 SIGSTOP(19)这两个信号不能被忽略外,其他的信号都可以忽略。驱动程序可以通过向应用程序发送不同的信号以实现不同的功能。


二、信号处理

2.1 驱动程序中的处理

2.1.1 fasync_struct结构体

首先要定义一个fasync_struct结构体指针变量:

struct fasync_struct { spinlock_t fa_lock; int magic; int fa_fd; struct fasync_struct *fa_next; struct file *fa_file; struct rcu_head fa_rcu; 
};
2.1.2 fasync操作函数

然后在设备驱动中实现file_operations操作集中的fasync操作函数

int (*fasync) (int fd, struct file *filp, int on)

fasync函数里一般通过调用fasync_helper函数以初始化前面定义的fasync_struct结构体指针

int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)

fasync_helper函数的前三个参数即fasync函数的三个参数,第四个参数是要初始化的fasync_struct结构体指针变量。 在关闭驱动文件的时候需要在file_operations操作集中的release操作函数中释放fasync_struct,fasync_struct的释放函数同样是fasync_helper

所以驱动中有关fasync操作函数的模板代码大致如下:

struct xxx_dev { ...... struct fasync_struct *async_queue; /* 异步相关结构体 */ 
}; static int xxx_fasync(int fd, struct file *filp, int on) 
{ struct xxx_dev *dev = (xxx_dev)filp->private_data; if (fasync_helper(fd, filp, on, &dev->async_queue) < 0) return -EIO; return 0; 
} static struct file_operations xxx_ops = { ...... .fasync = xxx_fasync, ...... 
};static int xxx_release(struct inode *inode, struct file *filp) 
{ return xxx_fasync(-1, filp, 0); /* 删除异步通知 */ 
}
2.1.3 kill_fasync函数

当设备可以访问的时候,kill_fasync函数负责发送指定的信号,相当于产生“中断”:

void kill_fasync(struct fasync_struct **fp, int sig, int band)

fp:要操作的fasync_struct。
sig:要发送的信号。
band:可读时设置为POLL_IN,可写时设置为POLL_OUT。
返回值:无。

2.2 应用程序中的处理

应用程序应根据驱动程序所使用的信号来设置相应信号的处理函数,应用程序使用signal函数来设置信号的处理函数。然后使用fcntl(fd, F_SETOWN, getpid())将本应用程序的进程号告诉给内核以开启异步通知:

flags = fcntl(fd, F_GETFL); /* 获取当前的进程状态 */
fcntl(fd, F_SETFL, flags | FASYNC); /* 开启当前进程异步通知功能 */

重点是通过fcntl函数设置进程状态为FASYNC——驱动程序中的fasync操作函数会因此而执行。


三、驱动代码

以Linux驱动开发——(六)按键中断实验的驱动代码为模板修改。

添加头文件和相关变量:

#include <linux/fcntl.h>struct fasync_struct *async_queue;

在定时器服务函数里添加:

if(atomic_read(&dev->releasekey)) {  if(dev->async_queue) kill_fasync(&dev->async_queue, SIGIO, POLL_IN); 
}

添加fasync操作函数:

static int imx6uirq_fasync(int fd, struct file *filp, int on) { struct imx6uirq_dev *dev = (struct imx6uirq_dev *) filp->private_data; return fasync_helper(fd, filp, on, &dev->async_queue); 
}static struct file_operations imx6uirq_fops = { .fasync = imx6uirq_fasync, 
};

完善release操作函数:

static int imx6uirq_release(struct inode *inode, struct file *filp){return imx6uirq_fasync(-1, filp, 0);
}static struct file_operations imx6uirq_fops = {  .release = imx6uirq_release, 
};

相关文章:

Linux驱动开发——(八)Linux异步通知

目录 一、异步通知简介 二、信号处理 2.1 驱动程序中的处理 2.1.1 fasync_struct结构体 2.1.2 fasync操作函数 2.1.3 kill_fasync函数 2.2 应用程序中的处理 三、驱动代码 一、异步通知简介 异步通知的核心就是信号。信号类似于硬件上使用的中断&#xff0c;只不过信号…...

Docker知识点汇总表格总结

Docker容器给我的一个很直观的感受就是将项目以及中间件安装变得比较简单直接&#xff0c;运行维护起来也更方便。之前做的一些微服务项目也是用docker来部署&#xff0c;现在很多开源的项目也流行使用docker来部署&#xff0c;简化了很多手动安装和配置的步骤&#xff0c;将项…...

Golang中实现调用Windows API向指定目标发送ARP请求

简介 Go库中很多实现的arp都是支持osx/linux/bsd之类的&#xff0c; 但几乎没有支持windows的&#xff0c; 也试了一些方式&#xff0c; 目前还是选用调用windows的API&#xff0c; 记录一下这一次windows的API的调用经验。 实现 代码 package main/* #cgo CFLAGS: -I. #cgo …...

这是一个简单的照明材料网站,后续还会更新

1、首页效果图 代码 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>爱德照明网站首页</title><style>/*外部样式*/charset "utf-8";*{margin: 0;padding: 0;box-sizing: border-box;}a{text-dec…...

【设计模式】之模板方法模式

系列文章目录 【设计模式】之策略模式 【设计模式】之责任链模式 文章目录 系列文章目录 前言 一、什么是模板方法模式 定义 角色 二、为什么要使用模板方法模式 优点 缺点 三、案例 普通案例 模拟Servlet过程案例 总结 前言 今天给大家介绍23种设计模式中的模板方法模式&a…...

【系统架构师】-选择题(十一)

1、紧耦合多机系统一般通过&#xff08;共享内存&#xff09;实现多机间的通信。对称多处理器结构&#xff08;SMP&#xff09;属于&#xff08; 紧耦合&#xff09;系统。 松耦合多机系统又称间接耦合系统,—般是通过通道或通信线路实现计算机间的互连。 2、采用微内核的OS结构…...

前端开发攻略---介绍HTML中的<dialog>标签,浏览器的原生弹框。

1、演示 2、介绍 <dialog> 标签用于定义对话框&#xff0c;即一个独立的窗口&#xff0c;通常用来显示对话框、提示框、确认框等弹出式内容。在对话框中&#xff0c;可以包含文本、表单元素、按钮等内容&#xff0c;用户可以和这些内容进行交互。 3、兼容性 4、示例代码 …...

让外贸业绩翻倍的销售话术分享

业绩翻三倍的话术&#xff0c;今后无论你遇到挑剔、犹豫、理智的顾客&#xff0c;都能轻松搞定。点赞存起来慢慢看&#xff0c;以免找不到。 与客户有效沟通技巧5的20句金句 业绩翻 3 倍&#xff0c;今后无论你遇到挑剔、犹豫、理智的顾客&#xff0c;都能轻松搞定。点赞存起来…...

观测与预测差值自动变化系统噪声Q的自适应UKF(AUKF_Q)MATLAB编写

简述 基于三维模型的UKF&#xff0c;设计一段时间的输入状态误差较大&#xff0c;此时通过对比预测的状态值与观测值的残差&#xff0c;在相应的情况下自适应扩大系统方差Q&#xff0c;构成自适应无迹卡尔曼滤波&#xff08;AUKF&#xff09;&#xff0c;与传统的UKF相比&…...

虚拟数据中心

创建数据中心和连接宿主机 DRS:收集群集内所有主机和虚拟机的资源使用情况信息&#xff0c;并根据特定的运行状况给出建议或迁移虚拟机HA:如果一台主机出现故障&#xff0c;则该主机上运行的所有虚拟机都将立即在同一群集的其他主机上重新启动EVC:增强型vMotionVirtual SAN:集中…...

解决Blender导出FBX文件到Unity坐标轴错误的问题

发现Blender的模型导入到Unity里面有问题,简单研究了下发现是坐标系不同,Unity使用的是左手坐标系,Blender使用的是右手坐标系 。 下面直接将如何解决 首先忽略Blender的右手坐标系以及Z轴朝上的事&#xff0c;依照unity坐标系情况修改模型物体的旋转&#xff0c;以Blender猴…...

基于微信小程序的校园二手闲置物品交易平台的设计与实现

基于微信小程序的校园二手闲置物品交易平台的设计与实现 “Design and Implementation of a Campus Second-Hand Marketplace Platform based on WeChat Mini Program” 完整下载链接:基于微信小程序的校园二手闲置物品交易平台的设计与实现 文章目录 基于微信小程序的校园二…...

java中多线程的3种实现方法

1.继承Thread类 优点&#xff1a;代码简单&#xff0c;可以直接使用Thread类里面的方法。 缺点&#xff1a;扩张性较差&#xff0c;应为在java中&#xff0c;一个类只能继承一个父类。 2.实现Runnable接口 3.实现Callable接口 2和3的优缺点是一样的 优点&#xff1a;扩展性强&…...

【Docker】docker compose服务编排

docker compose 简介 Dockerfile模板文件可以定义一个单独的应用容器&#xff0c;如果需要定义多个容器就需要服务编排。 docker swarm&#xff08;管理跨节点&#xff09; Dockerfile可以让用户管理一个单独的应用容器&#xff1b;而Compose则允许用户在一个模板&#xff08…...

elementui的el-select+el-tree+el-input实现可搜索的下拉树组件

部分实现代码如下 <template> <div><el-selectv-model"item.TableName"placeholder"请选择":disabled"!item.disabled"visible-change"handleVisible"ref"TableName"><el-input placeholder"请输…...

微信公众号排名 SEO的5个策略

随着微信公众号在社交媒体领域的持续发展和普及&#xff0c;如何提升公众号的搜索排名&#xff0c;成为许多运营者关注的焦点。公众号排名SEO&#xff0c;即针对微信公众号进行搜索引擎优化&#xff0c;旨在提高公众号在搜索结果中的曝光率和点击率。下面&#xff0c;我们将深入…...

python烟花代码

在Python中&#xff0c;可以使用多种方式来模拟烟花效果&#xff0c;其中一种常见的方法是使用turtle图形库来绘制。以下是一个简单的示例&#xff0c;展示了如何使用turtle来创建一个烟花效果的动画&#xff1a; import turtle import random# 设置屏幕和背景 screen turtle…...

Python高级编程

描述 集合&#xff0c;列表生成式&#xff0c;生成器&#xff0c;迭代器&#xff0c;切片 Python 中的集合类型是一种无序、不重复的数据容器&#xff0c;用于存储可哈希&#xff08;hashable&#xff09;的元素。Python 提供了两种内置的集合类型&#xff1a;set 和 frozens…...

leetCode75. 颜色分类

leetCode75. 颜色分类 题目思路 代码 class Solution { public:void sortColors(vector<int>& nums) {for(int i 0, j 0, k nums.size() - 1; i < k;){if(nums[i] 0) swap(nums[i],nums[j]);else if(nums[i] 2) swap(nums[i],nums[k--]);else if(nums[i] …...

选择器、pxcook软件、盒子模型

结构伪类选择器 定义&#xff1a;根据结构的元素关系来查找元素。 <title>Document</title><style>li:first-child{color:aqua ;}li:last-child{color: aqua;}li:nth-child(3){color: aqua;}</style> </head> <body><ul><li>…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...