首页 > 编程语言 >字符设备驱动程序之异步通知

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

时间:2023-02-23 09:56:22浏览次数:38  
标签:异步 驱动程序 val 字符 int fd key include

异步通知:

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

比如按键驱动:

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;
}
复制代码

标签:异步,驱动程序,val,字符,int,fd,key,include
From: https://www.cnblogs.com/kn-zheng/p/17146849.html

相关文章

  • T-SQL——将字符串转换为多列
    目录0.使用ParseName1.具体到拆分为两列2.具体到拆分的指定的列数志铭-2023年2月21日0.使用ParseName注意:ParseName最多只能拆分为四列ParseName只能针对.,所以若......
  • C#后缀表达式解析计算字符串公式
    当我们拿到一个字符串比如:20+31*(100+1)的时候用口算就能算出结果为3151,因为这是中缀表达式对于人类的思维很简单,但是对于计算机就比较复杂了。相对的后缀表达式适合计算机......
  • 代码随想录打卡第8天 | 反转字符串 反转字符串II 替换空格 翻转字符串里的单词 左旋
    反转字符串 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组s的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用O(1)的......
  • Java 截取字符串 split 方法与 substring 方法简单比较
    Java截取字符串split方法与substring方法简单比较文章目录​​Java截取字符串`split`方法与`substring`方法简单比较​​​​0、结论​​​​1、截取目标​​​​......
  • 转义字符
    1.什么是转义字符?就是反斜杠+想要实现转义功能的首字母2.为什么要转义字符?当字符串中包含反斜杠、单引号和双引号等有特殊用途的字符时,必须使用反斜杠对这些字符进行......
  • go zip 字符串压缩
    import("bytes""compress/zlib""fmt""io/ioutil")/*@Time:2021/9/1317:09@Author:iokde.com*/funcmain(){str:="iokde.com"fmt.Println("origininfo......
  • 【算法训练营day56】LeetCode583. 两个字符串的删除工作 LeetCode72. 编辑距离
    LeetCode583.两个字符串的删除工作题目链接:583.两个字符串的删除工作独上高楼,望尽天涯路突然感觉有那么一点开窍了,可以照猫画虎了。classSolution{public:in......
  • Unity下简易字符串指令调试
    Unity下简易字符串指令调试输入相应的字符串命令即可调用特定的方法,比如让角色等级提升,生成特定数量的Boss等usingSystem;usingUnityEngine;usingSystem.Collectio......
  • debug补充、员工管理系统、字符编码、文件操作
    目录一、debug补充二、员工管理系统三、字符编码(1)、概念(2)、字符编码的发展史(3)、字符编码的使用四、文件操作(1)、概念讲解(2)、通过代码打开文件的两种方式(3)、文件......
  • golang 字符串函数
    1.统计字符串的长度,按字节进行统计packagemainimport"fmt"funcmain(){ vars1string="hello,世界" fmt.Printf("s1字符串的长度为:%v",len(s1))//汉字为......