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

字符设备驱动程序之异步通知

异步通知:

     驱动程序的所谓异步通知,就是说并不是应用程序来对驱动程序操作的,而是驱动程序查询到有事件发生或者有数据发生变化的时候通知应用程序。角色发生了变化,应用程序由主动改为被动执行。

比如按键驱动:

1、有不断进行查询引脚状态的,CPU资源消耗非常的打;

2、有中断操作的,发生按键事件后采取执行相关事件处理函数,需要应用程序不断执行read函数,使得不能去干其它事情;

3、poll机制,改善了中断方式操作,在应用程序上当没有事件发生时,会跳去read函数继续执行其它的任务,知道有事件发生才返回;

4、异步通知,也即我们本次讲的,让驱动程序自己告诉我们事件发生,我们采取执行。

为了使设备支持异步通知机制,驱动程序中涉及以下3项工作:
1. 支持F_SETOWN命令,能在这个控制命令处理中设置filp->f_owner为对应进程ID。
不过此项工作已由内核完成,设备驱动无须处理。
2. 支持F_SETFL命令的处理,每当FASYNC标志改变时,驱动程序中的fasync()函数将得以执行。
驱动中应该实现fasync()函数。

3. 在设备资源可获得时,调用kill_fasync()函数激发相应的信号


应用程序:
fcntl(fd, F_SETOWN, getpid()); // 告诉内核,发给谁

Oflags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, Oflags | FASYNC); // 改变fasync标记,最终会调用到驱动的faync > fasync_helper:初始化/释放fasync_struct

相关参考代码如下:

fifth_drv.c


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>


/* fifthdrvtest
*/
int fd;

/* 驱动程序发送信号后,应用程序接收到信号做相应处理 读取硬件数据 */
void my_signal_fun(int signum)
{
unsigned char key_val;
read(fd, &key_val, 1);
printf("key_val: 0x%x\n", key_val);
}

int main(int argc, char **argv)
{
unsigned char key_val;
int ret;
int Oflags;

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);


while (1)
{
sleep(1000);
}

return 0;
}

 

Makefile

KERN_DIR = /work/system/linux-2.6.22.6

all:
    make -C $(KERN_DIR) M=`pwd` modules 

clean:
    make -C $(KERN_DIR) M=`pwd` modules clean
    rm -rf modules.order

obj-m    += fifth_drv.o

 

fifthdrvtest.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>


/* fifthdrvtest 
  */
int fd;

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

int main(int argc, char **argv)
{
    unsigned char key_val;
    int ret;
    int Oflags;

    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);


    while (1)
    {
        sleep(1000);
    }
    
    return 0;
}

 

转载于:https://www.cnblogs.com/yihujiu/p/6404682.html

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • HTTP 错误 403.9 - 禁止访问:连接的用户过多
  • 如何使用flex皮肤
  • 查看进程占用的文件和文件数目
  • 动态创建DataGrid 列
  • Vue.js基础入门
  • 在 Tree 中查找节点
  • jQery使网页在显示器上居中显示适用于任何分辨率
  • 动态显示/隐藏 DataGrid 的列
  • Plugin with id 'com.github.dcendents.android-maven' not found
  • Flex构建WebService应用
  • Python 接口测试(五)
  • url中文乱码解决大全
  • warning: unable to bind to property '' on class '' (class is not an IEventDispatcher)
  • Nim游戏
  • Linux下ifort的安装记录
  • avalon2.2的VM生成过程
  • C学习-枚举(九)
  • Java 23种设计模式 之单例模式 7种实现方式
  • java取消线程实例
  • jdbc就是这么简单
  • node 版本过低
  • PV统计优化设计
  • python docx文档转html页面
  • Spring Cloud中负载均衡器概览
  • vuex 笔记整理
  • 测试如何在敏捷团队中工作?
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 飞驰在Mesos的涡轮引擎上
  • 来,膜拜下android roadmap,强大的执行力
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 前端面试题总结
  • 试着探索高并发下的系统架构面貌
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 通过npm或yarn自动生成vue组件
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • AI算硅基生命吗,为什么?
  • FaaS 的简单实践
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 数据可视化之下发图实践
  • 说说我为什么看好Spring Cloud Alibaba
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​linux启动进程的方式
  • # C++之functional库用法整理
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • $(this) 和 this 关键字在 jQuery 中有何不同?
  • $NOIp2018$劝退记
  • (1)bark-ml
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (3)(3.5) 遥测无线电区域条例
  • (6)设计一个TimeMap
  • (function(){})()的分步解析
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell