分类: LINUX

poll函数用于监测多个等待事件,若事件未发生,进程睡眠,放弃CPU控制权,若监测的任何一个事件发生,poll将唤醒睡眠的进程,并判断是什么等待事件发生,执行相应的操作。poll函数退出后,struct pollfd变量的所有值被清零,需要重新设置。

示例是使用poll函数来监测按键的输入

----------------------------------------------------------------------------------------------------------

 

驱动代码:

  1. #include <linux/config.h>
  2. #include <linux/module.h>
  3. #include <linux/kernel.h>
  4. #include <linux/fs.h>
  5. #include <linux/init.h>
  6. #include <linux/devfs_fs_kernel.h>
  7. #include <linux/miscdevice.h>
  8. #include <linux/delay.h>
  9. #include <asm/irq.h>
  10. #include <asm/arch/regs-gpio.h>
  11. #include <asm/hardware.h>
  12. #include <linux/cdev.h>
  13. #include <linux/mm.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/poll.h>
  16. #include <asm/uaccess.h>
  17. #include <asm/ioctl.h>
  18. #include <asm/arch/regs-irq.h>
  19. #include <asm/io.h>
  20. #define key S3C2410_GPF0
  21. #define key_irq IRQ_EINT0 //IRQ_EINT0是中断号
  22. #define key_cfg S3C2410_GPF0_EINT0 //设置为外部中断功能
  23. #define DEVICE_NAME "key"
    //注意加上双引号
  24. #define DEVICE_MAJOR major
  25. #define DEVICE_MINOR 0
  26. static dev_t dev;
    //dev_t类型用于存放主设备号和次设备号
  27. static
    int major;
  28. struct cdev *p_cdev;
    //声明一个指向字符设备结构的指针
  29. static
    int key_event=0;
    时满足唤醒条件,静态全局变量
  30. static
    int key_value=1;
    //按键键值
  31. static DECLARE_WAIT_QUEUE_HEAD(wq);
    //调用宏定义,静态创建一个名为wq的等待队列
  32. static
    void key_interrupt(void)
    //中断处理函数,注册中断时已注册了中断程序的入口地址
  33. {
  34.  key_value=s3c2410_gpio_getpin(key);
  35.  key_event=1;
    //唤醒标记置位,表示条件达到,可以唤醒进程继续执行
  36.  wake_up_interruptible(&wq);
    //调用宏定义,唤醒标记置位后调用此函数,&wq是队列入口地址
  37. }
  38. static
    int key_read(struct
    file
    *filp,char __user *buff,size_t count,loff_t *offp)
  39. {
  40. ,从此处将进程放入wq等待队列休眠,等待中断;key_event==1时,此宏不执行操作
  41. //调用poll的时候来等待,这里可以不用wait_event_interrupt()
  42.  key_value=s3c2410_gpio_getpin(key);
  43.  copy_to_user(buff,&key_value,sizeof(key_event));
    //将&key_value地址的值从内核空间复制到用户空间
  44.  key_event=0;
    //完成中断操作,将唤醒标记清零,继续休眠
  45.  return 0;
  46. }
  47. static unsigned int key_poll(struct
    file
    *filp,poll_table *wait)
  48. {
  49.  unsigned int mask=0;
    //用来记录发生的事件,以unsigned int类型返回
  50.  poll_wait(filp,&wq,wait);
    //将当前进程添加到wq等待队列中
  51.  if(key_event==1)mask|=POLLIN|POLLRDNORM;
    //中断事件发生,这时有数据可读,在mask中标记是可读事件发生
  52.  return mask;
    则表示等待事件超时
  53. }
  54. //设置寄存器,申请中断号等在open函数中完成
  55. static
    int key_open(struct inode *inode,struct
    file
    *filp)
  56. {
  57.  int ret;
  58.  s3c2410_gpio_cfgpin(key,key_cfg);
    //设置引脚功能
  59.  s3c2410_gpio_pullup(key,1);
    为禁止内部上拉
  60.  ret=request_irq(key_irq,(void
    *)key_interrupt,SA_INTERRUPT,DEVICE_NAME,NULL);
    //注册中断,中断不共享时最后一个参数为NULL
  61.  if(ret)
    {
  62.   printk("Could not register interrupt\n");
  63.   return ret;
  64.  }
  65.  set_irq_type(key_irq,IRQT_BOTHEDGE);
    //设置中断方式为双边触发
  66.  return 0;
  67. }
  68. static
    int key_close(struct inode *inode,struct
    file
    *filp)
  69. {
  70.  free_irq(key_irq,NULL);
    //中断无共享时第二个参数为NULL
  71.  return 0;
  72. }
  73. static
    struct file_operations key_fops={
  74.  .owner=THIS_MODULE,
  75.  .open=key_open,
  76.  .release=key_close,
  77.  .read=key_read,
  78.  .poll=key_poll,
  79. };
  80. int key_init(void)
  81. {
  82.  int ret;
  83.  ret=alloc_chrdev_region(&dev,DEVICE_MINOR,1,DEVICE_NAME);
    //采用主设备号动态分配
  84.  if(ret<0){
  85.   printk("Register /dev/key failed!\n");
  86.   return ret;
  87.  }
  88.  else printk("Register /dev/key successfully!\n");
  89.  major=MAJOR(dev);
    //取得分配到的主设备号
  90.  p_cdev=cdev_alloc();
    //申请一个字符设备结构并返回指向它的指针
  91.  cdev_init(p_cdev,&key_fops);
    //相当于p_cdev->ops=&key_fops
  92.  p_cdev->owner=THIS_MODULE;
  93.  ret=cdev_add(p_cdev,dev,1);
    //向系统添加这个字符设备
  94.  if(ret<0){
  95.   printk("Add cdev failed!\n");
  96.   return ret;
  97.  }
  98.  devfs_mk_cdev(dev,S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP,DEVICE_NAME);
  99.  return 0;
  100. }
  101. void key_exit(void)
  102. {
  103.  unregister_chrdev_region(dev,1);
  104.  cdev_del(p_cdev);
    //删除字符设备
  105.  devfs_remove(DEVICE_NAME);
  106.  printk("Device unregister!\n");
  107. }
  108. MODULE_LICENSE("GPL");
  109. MODULE_AUTHOR("HJW");
  110. module_init(key_init);
  111. module_exit(key_exit);
  112. ---------------------------------------------------------------------------------------------------
  113. 测试程序代码:
  114. #include <stdio.h>
  115. #include <stdlib.h>
  116. #include <unistd.h>
  117. #include <sys/ioctl.h>
  118. #include <sys/types.h>
  119. #include <sys/stat.h>
  120. #include <fcntl.h>
    /*文件控制*/
  121. #include <sys/select.h>
  122. #include <sys/time.h>
    /*时间方面的函数*/
  123. #include <errno.h>
    /*有关错误方面的宏*/
  124. #include<sys/poll.h>
    //poll()
  125. #include<fcntl.h>
  126. #include<string.h>
    //memset()
  127. int main(void)
  128. {
  129.  int fd,key_value,ret;
  130.  struct pollfd event;
    //创建一个struct pollfd结构体变量,存放文件描述符、要等待发生的事件
  131.  fd=open("/dev/key",O_RDWR);
  132.  if(fd<0){
  133.   perror("open /dev/key error!\n");
  134.   exit(1);
  135.  }
  136.  printf("open /dev/key sucessfully!\n");
  137.  while(1){
    //poll结束后struct pollfd结构体变量的内容被全部清零,需要再次设置
  138.   memset(&event,0,sizeof(event));
    //memst函数对对象的内容设置为同一值
  139.   event.fd=fd;
    //存放打开的文件描述符
  140.   event.events=POLLIN;
    //存放要等待发生的事件
  141.   ret=poll((struct pollfd *)&event,1,5000);
    毫秒后超时,-1为无限等待
  142. 是设定的时间超时,整数表示等待的时间发生
  143.   if(ret<0){
  144.    printf("poll error!\n");
  145.    exit(1);
  146.   }
  147.   if(ret==0){
  148.    printf("Time out!\n");
  149.    continue;
  150.   }
  151.   if(event.revents&POLLERR){
    //revents是由内核记录的实际发生的事件,events是进程等待的事件
  152.    printf("Device error!\n");
  153.    exit(1);
  154.   }
  155.   if(event.revents&POLLIN){
  156.    read(fd,&key_value,sizeof(key_value));
  157.    printf("Key value is '%d'\n",key_value);
  158.   }
  159.  }
  160.  close(fd);
  161.  return 0;
  162. }

poll()函数的使用的更多相关文章

  1. linux poll函数

    poll函数与select函数差不多 函数原型: #include <poll.h> int poll(struct pollfd fd[], nfds_t nfds, int timeo ...

  2. poll函数

    poll函数与select函数的功能基本一样,其定义如下: #include <poll.h> int poll(struct pollfd fds[], nfds_t nfds, int ...

  3. select与poll函数介绍

    select与poll函数介绍 在所有依从POSIX的平台上,select函数使我们可以执行I/O多路转接.传向select的参数告诉内核: 1)我们所关心的描述符 2)对于每个描述符我们所关心的状态 ...

  4. I/O多路复用——select函数与poll函数

    1 区别 同:(1)机制类似,本质上没有多大差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理.(2)包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就 ...

  5. poll函数和串口设置

    2015.1.24 今天星期六,多云,早晨8:17起床的,今天是来南京起床最迟的一天,因为昨晚睡得有点迟,今天又不用上课,整个人有点放松.收拾好来到教室,教室门没有开,胡明也到了,其他人还在宿舍睡觉, ...

  6. [转载] poll()函数

    原地址:http://baike.baidu.com/view/2997591.htm   poll()函数:这个函数是某些Unix系统提供的用于执行与select()函数同等功能的函数,下面是这个函 ...

  7. I/O多路转接之poll 函数

    poll 一.poll()函数: 这个函数是某些Unix系统提供的用于执行与select()函数同等功能的函数,自认为poll和select大同小异,下面是这个函数的声明: #include < ...

  8. UNIX网络编程——select函数的并发限制和 poll 函数应用举例

    一.用select实现的并发服务器,能达到的并发数,受两方面限制 1.一个进程能打开的最大文件描述符限制.这可以通过调整内核参数.可以通过ulimit -n来调整或者使用setrlimit函数设置,  ...

  9. 【unix网络编程第三版】阅读笔记(五):I/O复用:select和poll函数

    本博文主要针对UNP一书中的第六章内容来聊聊I/O复用技术以及其在网络编程中的实现 1. I/O复用技术 I/O多路复用是指内核一旦发现进程指定的一个或者多个I/O条件准备就绪,它就通知该进程.I/O ...

随机推荐

  1. Timus 2068. Game of Nuts 解题报告

    1.题目描述: 2068. Game of Nuts Time limit: 1.0 secondMemory limit: 64 MB The war for Westeros is still i ...

  2. 我的第一个hadoop程序

    利用virtualbox+win的开发环境搭设好咯,在win下做开发,利用linux跑hadoop,伪分布式的. 上第一个程序 package org.apache.hadoop.examples; ...

  3. js中进行金额计算parseFloat

    在js中进行以元为单位进行金额计算时 使用parseFloat会产生精度问题var price = 10.99;var quantity = 7;var needPay = parseFloat(pr ...

  4. VB 中 NumericUpDown 控件 如何为手动输入设定触发事件

    Private Sub numDuration_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) ...

  5. MySQL主从同步配置(Ubuntu)

    一.在两台Linux机器上安装MySQL 二.Master主服务器配置(192.168.1.3) 1.编辑my.cnf(命令查找文件位置:find / -name my.cnf) vi /etc/my ...

  6. JavaScript中正则表达式test()、exec()、match() 方法

    转自http://www.cnblogs.com/jane-y/articles/5183859.html 1.test test 返回 Boolean,查找对应的字符串中是否存在模式.var str ...

  7. mySQL函数根据经纬度计算两点距离

    DROP FUNCTION IF EXISTS func_calcDistance ; CREATE FUNCTION func_calcDistance( origLng ,), -- 目的地经度 ...

  8. python读取和写入csv文件

    读取csv文件: def readCsv(): rows=[] with file(r'E:\py\py01\Data\system.csv','rb') as f: reads=csv.reader ...

  9. 24-React Components组件

    Components 组件 1.组件 可以让UI独立的分割出来,可以让UI重复利用. 2.组件就像是JavaScript函数,它们能够接收任意的输入(称为"props",即属性)并 ...

  10. 公钥私钥和RSA算法

    1, RSA算法原理(一) http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html 2, RSA算法原理(二) http: ...