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


    异步通知:

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

    比如按键驱动:

    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 ", 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! ");
    }

    /* 接收驱动程序消息 */
    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
    ", 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!
    ");
        }
    
        fcntl(fd, F_SETOWN, getpid());
        
        Oflags = fcntl(fd, F_GETFL); 
        
        fcntl(fd, F_SETFL, Oflags | FASYNC);
    
    
        while (1)
        {
            sleep(1000);
        }
        
        return 0;
    }
  • 相关阅读:
    保存时出错jup
    Spyder默认页面布局调整
    根据所处位置提取单元格内容的函数(left、right、mid)和查找字符串位于单元格内容第几位的函数(find)
    excel打印出现多余空白页
    Excel的布尔值运算
    excel VBA一个fuction同时执行多个正则表达式,实现方法
    excel VBA把一个单元格内容按逗号拆分并依次替换到另一个单元格的括号里面(本题例子,把文本中的括号换成{答案}的格式,并按顺序填空)
    excel自动记录项目完成进度,是否逾期,逾期/提前完成天数,计算天数可以把now()改为today()
    jquery循环动画
    jquery动画(控制动画隐藏、显示时间轴)
  • 原文地址:https://www.cnblogs.com/yihujiu/p/6404682.html
Copyright © 2020-2023  润新知