zoukankan      html  css  js  c++  java
  • poll机制

    poll机制的作用:使阻塞型函数超时返回,避免一直阻塞。

       

     

    实例:

    driver.c

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

       

    app.c

    1 #include <sys/types.h>
    2 #include <sys/stat.h>
    3 #include <fcntl.h>
    4 #include <stdio.h>
    5 #include <poll.h>
    6
    7 int main (void)
    8 {
    9         int fd;
    10         unsigned char keyVal;
    11         int ret;
    12         struct pollfd fds[1];
    13         
    14         printf("test app! ");
    15
    16         fd = open("/dev/myKey", O_RDWR);
    17         if(fd < 0)
    18         {
    19                 printf("open failed! %d ", fd);
    20                 return -1;
    21         }
    22
    23         fds[0].fd = fd;
    24         fds[0].events = POLLIN;
    25         
    26         while(1)
    27         {
    28                 ret = poll(fds, 1, 5000);
    29                 if (!ret)
    30                 {
    31                         printf("time out(5s) ");
    32                 }
    33                 else {
    34                         read(fd, &keyVal, 1);
    35                         printf("keyVal: 0x%x ", keyVal);
    36                 }
    37         }
    38         return 0;        
    39 }

       

    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_pollmcn.o

  • 相关阅读:
    Atitit fms Strait (海峡) lst 数据列表目录1. 4大洋 12. 著名的海大约40个,总共约55个海 13. 海区列表 23.1. 、波利尼西亚(Polynesia,
    Atitit trave islands list 旅游资源列表岛屿目录1. 东南亚著名的旅游岛屿 21.1. Cjkv 日韩 冲绳 琉球 济州岛 北海道 21.2. 中国 涠洲岛 南澳
    Atitit Major island groups and archipelagos 主要的岛群和群岛目录资料目录1. 岛群 波利尼西亚(Polynesia, 美拉尼西亚(Melanesia,
    Atitit glb 3tie city lst 三线城市列表 数据目录1. 全球范围内约90个城市 三线 12. 世界性三线城市全球共
    Atitit glb 1tie 2tie city lst 一二线城市列表数据约50个一线城市Alpha ++ 阿尔法++,,London 伦敦,,New York 纽约,,Alpha +
    Attit 现代编程语言重要特性目录第一章 类型系统 基本三大类型 2第一节 字符串 数字 bool 2第二节 推断局部变量 2第三节 动态类型 2第二章 可读性与开发效率 简单性 2
    Atitit 未来数据库新特性展望目录1. 统一的翻页 21.1. 2 Easy Top-N
    使用Chrome DevTools(console ande elements panel)进行xpath/css/js定位
    chrome -console妙用之定位xpath/js/css
    表达式树之构建Lambda表达式
  • 原文地址:https://www.cnblogs.com/lilto/p/11878055.html
Copyright © 2011-2022 走看看