• 异步通知


    轮询:应用程序不断read;驱动程序不断read,占用大量的cpu资源。

    中断:应用程序阻塞在read;驱动程序休眠,只有发生中断时,驱动程序唤醒,读取键值,返回给应用程序;应用程序执行下一步。

    poll:应用程序在一定的时间内(用户定义),不断检测用户设置的flag,超时执行下一步;驱动程序在发生中断时,标记用户设置的flag。

    async:应用程序不会阻塞,不影响当前进程的其他任务的执行,只有在接收到驱动程序发送过来的信号,才去读取键值;在发生中断时,驱动程序发送信

    号给应用程序(通过进程号),通知应用程序读取键值。

       

    当按键中断发生时,发送信号给应用程序,应用程序再去读取键值,避免进程阻塞在read()函数,提高系统运用效率。

       

    实例

    driver

    1 #include <linux/module.h>
    2 #include <linux/kernel.h>
    3 #include <linux/fs.h>
    4 #include <linux/init.h>
    5 #include <linux/delay.h>
    6 #include <linux/irq.h>
    7 #include <asm/uaccess.h>
    8 #include <asm/irq.h>
    9 #include <asm/io.h>
    10 #include <asm/arch/regs-gpio.h>
    11 #include <asm/hardware.h>
    12
    13
    14 static int major;
    15
    16 static struct class *myKey_class;
    17 static struct class_device *myKey_class_dev;
    18
    19 volatile unsigned long *gpfcon;
    20 volatile unsigned long *gpfdat;
    21
    22 volatile unsigned long *gpgcon;
    23 volatile unsigned long *gpgdat;
    24
    25 static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
    26 static volatile int ev_press = 0;
    27
    28 static struct fasync_struct *button_fasyncq;
    29
    30 //normal:1; press:0;
    31 static unsigned char keyVal = 0;
    32
    33 struct pin_desc {
    34         unsigned int pin;
    35         unsigned int key_val;
    36 };
    37
    38 /*
    39 * 按键按下键值为0x01,...; 松开键值为0x81,...
    40 */
    41 struct pin_desc pins_desc[3] = {
    42         {S3C2410_GPF0, 0x01},
    43         {S3C2410_GPF2, 0x02},        
    44         {S3C2410_GPG11, 0x03},        
    45 };
    46
    47
    48 static int myKey_open(struct inode *inode, struct file *file);
    49 static int myKey_close(struct inode *inode, struct file *file);
    50 static ssize_t myKey_read(struct file *file, char __user *buf, size_t size, loff_t *ppos);
    51 static int myKey_fasync(int fd, struct file *filp, int on);
    52
    53
    54 static struct file_operations myKey_fops = {
    55         .open = myKey_open,
    56         .read = myKey_read,
    57         .owner = THIS_MODULE,
    58         .release = myKey_close,
    59         .fasync = myKey_fasync,
    60 };
    61
    62
    63 static irqreturn_t handle_buttons(int irq, void *dev)
    64 {
    65         unsigned int kval;
    66         struct pin_desc *pinDesc = dev;
    67
    68         kval = s3c2410_gpio_getpin(pinDesc->pin);
    69         if (kval)        //松开
    70         {
    71                 keyVal = 0x80 | pinDesc->key_val;
    72         }
    73         else {                //按下
    74                 keyVal = pinDesc->key_val;
    75         }
    76
    77         //唤醒休眠进程
    78         ev_press = 1;        //中断发生标志
    79         wake_up_interruptible(&button_waitq);
    80
    81         kill_fasync(&button_fasyncq, SIGIO, POLL_IN);
    82
    83         return IRQ_RETVAL(IRQ_HANDLED);
    84 }
    85
    86
    87 static int myKey_open(struct inode *inode, struct file *file)
    88 {
    89         request_irq(IRQ_EINT0, handle_buttons, IRQT_BOTHEDGE, "S2", &pins_desc[0]);
    90         request_irq(IRQ_EINT2, handle_buttons, IRQT_BOTHEDGE, "S3", &pins_desc[1]);
    91         request_irq(IRQ_EINT19, handle_buttons, IRQT_BOTHEDGE, "S5", &pins_desc[2]);
    92         
    93         return 0;
    94 }
    95
    96
    97 static int myKey_close(struct inode *inode, struct file *file)
    98 {
    99         free_irq(IRQ_EINT0, &pins_desc[0]);
    100         free_irq(IRQ_EINT2, &pins_desc[1]);
    101         free_irq(IRQ_EINT19, &pins_desc[2]);
    102
    103         return 0;
    104 }
    105
    106 int myKey_fasync(int fd, struct file *filp, int on)
    107 {        
    108         printk("driver: fasync_init ");
    109         fasync_helper(fd, filp, on, &button_fasyncq);
    110
    111         return 0;
    112 }
    113
    114 static ssize_t myKey_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
    115 {
    116         //无中断进入休眠
    117         wait_event_interruptible(button_waitq, ev_press);
    118
    119         ev_press = 0;        //清除中断发生标志
    120         copy_to_user(buf, &keyVal, 1);
    121         return 0;
    122 }
    123
    124 static int __init myKey_init(void)
    125 {
    126         /* 物理地址映射成虚拟地址 */
    127         gpfcon = (volatile unsigned long*)ioremap(0x56000050, 16);
    128         gpfdat = gpfcon + 1;
    129
    130         gpgcon = (volatile unsigned long*)ioremap(0x56000060, 16);
    131         gpgdat = gpgcon + 1;
    132
    133         major = register_chrdev(0, "myKey", &myKey_fops);
    134         
    135         myKey_class = class_create(THIS_MODULE, "myKeyclass");
    136         myKey_class_dev = class_device_create(myKey_class, NULL, MKDEV(major, 0), NULL, "myKey");
    137
    138         return 0;
    139 }
    140
    141 static void __exit myKey_exit(void)
    142 {
    143         /* 释放虚拟地址映射 */
    144         iounmap(0x56000050);
    145         iounmap(0x56000060);
    146
    147         unregister_chrdev(major, "myKey");
    148
    149         class_device_unregister(myKey_class_dev);
    150         class_destroy(myKey_class);
    151         return;
    152 }
    153
    154 module_init(myKey_init);
    155 module_exit(myKey_exit);

       

       

    app

    1 #include <sys/types.h>
    2 #include <sys/stat.h>
    3 #include <fcntl.h>
    4 #include <stdio.h>
    5 #include <signal.h>
    6 #include <unistd.h>
    7
    8 int fd;
    9
    10 void handle_signal(int signum)
    11 {
    12         unsigned char keyVal;
    13
    14         read(fd, &keyVal, 1);
    15         printf("keyVal: 0x%x ", keyVal);
    16
    17         return;
    18 }
    19
    20
    21 int main (void)
    22 {
    23         int oflag = 0;
    24
    25         printf("test app! ");
    26
    27         fd = open("/dev/myKey", O_RDWR);
    28         if(fd < 0)
    29         {
    30                 printf("open failed! %d ", fd);
    31                 return -1;
    32         }
    33
    34         signal(SIGIO, handle_signal);
    35         
    36         fcntl(fd, F_SETOWN, getpid());
    37         oflag = fcntl(fd, F_GETFL);
    38         fcntl(fd, F_SETFL, oflag | O_ASYNC);
    39         
    40         while(1)
    41         {
    42                 sleep(5);
    43         }
    44         return 0;        
    45 }

       

       

    Makefile

    1 KERN_DIR = /work/system/linux-2.6.22.6
    2
    3 all:
    4         make -C $(KERN_DIR) M=`pwd` modules
    5

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

    9
    10 obj-m += myKey_signal.o

  • 相关阅读:
    天天生鲜项目需求分析——基于Django框架的天天生鲜电商网站项目系列博客(一)
    预训练模型专题_GPT2_模型代码学习笔记
    Logistic模型原理详解以及Python项目实现
    【人生苦短,我学 Python】基础篇——基本语句(Day5)
    “TensorFlow 开发者出道计划”全攻略,玩转社区看这里!
    程序员常用的六大技术博客类
    [慕课笔记]Node入口文件分析和目录初始化
    如何在面试中脱颖而出?
    程序媛,坚持这几个好习惯让你越来越美
    2017前端精品面试文章总结
  • 原文地址:https://www.cnblogs.com/lilto/p/11878548.html
Copyright © 2020-2023  润新知