linux内核版本:linux-2.6.30.4

目的:我们在中断方式的按键应用程序中,如果没有按键按下,read就会永远在那等待,所以如果在这个程序里还想做其他事就不可能了。因此我们这次改进它,让它在等待5秒钟,如果5秒钟内没有按键按下就返回,可以在read后面做其他事,只需要在驱动程序里加入poll机制就可以完成目的。

  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 <asm/uaccess.h>
  7. #include <asm/irq.h>
  8. #include <asm/io.h>
  9. #include <linux/device.h>
  10. #include <linux/irq.h>
  11. #include <linux/interrupt.h>
  12. #include <mach/regs-gpio.h>
  13. #include <linux/poll.h>
  14.  
  15. static struct class *fourth_drv_class;
  16. static struct class_device *fourth_drv_class_dev;
  17.  
  18. static volatile unsigned long *gpfcon;
  19. static volatile unsigned long *gpfdat;
  20. static int major;
  21.  
  22. struct pin_desc
  23. {
  24. unsigned int pin;
  25. unsigned int key_val;
  26. };
  27.  
  28. static unsigned char key_val;
  29.  
  30. static struct pin_desc pins_desc[] =
  31. {
  32. {S3C2410_GPF1, 0x01},
  33. {S3C2410_GPF4, 0x02},
  34. {S3C2410_GPF2, 0x03},
  35. {S3C2410_GPF0, 0x04},
  36. };
  37.  
  38. static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
  39. static volatile int ev_press = ;
  40.  
  41. static irqreturn_t buttons_irq(int irq, void *dev_id)
  42. {
  43. struct pin_desc *pin = (struct pin_desc *)dev_id;
  44. unsigned int pinval;
  45. pinval = s3c2410_gpio_getpin(pin->pin);
  46.  
  47. if (pinval)
  48. {
  49. //松开
  50. key_val = 0x80 | pin->key_val;
  51. }
  52. else
  53. {
  54. //按下
  55. key_val = pin->key_val;
  56. }
  57.  
  58. wake_up_interruptible(&button_waitq);
  59. ev_press = ;
  60.  
  61. return IRQ_HANDLED;
  62. }
  63.  
  64. static int fourth_drv_open(struct inode *inode, struct file *file)
  65. {
  66. request_irq(IRQ_EINT1, buttons_irq, IRQ_TYPE_EDGE_BOTH, "S1", &pins_desc[]);
  67. request_irq(IRQ_EINT4, buttons_irq, IRQ_TYPE_EDGE_BOTH, "S2", &pins_desc[]);
  68. request_irq(IRQ_EINT2, buttons_irq, IRQ_TYPE_EDGE_BOTH, "S3", &pins_desc[]);
  69. request_irq(IRQ_EINT0, buttons_irq, IRQ_TYPE_EDGE_BOTH, "S4", &pins_desc[]);
  70. return ;
  71. }
  72.  
  73. static ssize_t fourth_drv_read(struct file *file, char __user *buf,
  74. size_t count, loff_t *ppos)
  75. {
  76. if (count != )
  77. return -EINVAL;
  78. /*如果没有按键动作,休眠*/
  79. wait_event_interruptible(button_waitq, ev_press);
  80.  
  81. /*如果有按键动作发生,返回键值*/
  82. copy_to_user(buf, &key_val, );
  83. ev_press = ;
  84. return ;
  85. }
  86.  
  87. static int fourth_drv_release(struct inode *inode, struct file *file)
  88. {
  89. free_irq(IRQ_EINT1, &pins_desc[]);
  90. free_irq(IRQ_EINT4, &pins_desc[]);
  91. free_irq(IRQ_EINT2, &pins_desc[]);
  92. free_irq(IRQ_EINT0, &pins_desc[]);
  93. return ;
  94. }
  95.  
  96. static unsigned int fourth_drv_poll(struct file *file, poll_table *wait)
  97.  
  98. {
  99. unsigned int mask = ;
  100.  
  101. /*这并不会休眠,只是把当前进程挂到队列里*/
  102. poll_wait(file, &button_waitq, wait);
  103.  
  104. if (ev_press)
  105. {
  106. mask |= (POLLIN | POLLRDNORM);
  107. }
  108. return mask;
  109. }
  110.  
  111. static struct file_operations fourth_fops = {
  112. .owner = THIS_MODULE,
  113. .open = fourth_drv_open,
  114. .read = fourth_drv_read,
  115. .poll = fourth_drv_poll,
  116. .release = fourth_drv_release,
  117. };
  118.  
  119. int fourth_init()
  120. {
  121. int ret;
  122. major = register_chrdev(, "fourth_drv", &fourth_fops);
  123. fourth_drv_class = class_create(THIS_MODULE, "fourth_drv");
  124. device_create(fourth_drv_class, NULL, MKDEV(major, ), NULL, "buttons");
  125.  
  126. gpfcon = (volatile unsigned long *)ioremap(0x56000050, );
  127. gpfdat = gpfcon + ;
  128.  
  129. return ;
  130. }
  131. static void fourth_exit()
  132. {
  133. unregister_chrdev(major, "fourth_drv");
  134. device_destroy(fourth_drv_class, MKDEV(major, ));
  135. class_destroy(fourth_drv_class);
  136. iounmap(gpfcon);
  137. }
  138.  
  139. module_init(fourth_init);
  140. module_exit(fourth_exit);
  141.  
  142. MODULE_LICENSE("GPL");

测试程序:

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

运行效果:

韦东山驱动视频笔记——3.字符设备驱动程序之poll机制的更多相关文章

  1. 字符设备驱动程序之poll机制(韦大仙)

    明确为什么要引用poll机制? while(1) { read(fd,&key_val,1);//如果没有按键按下,它会一直在等待.现在想做这么一件事情:如果5s后,没有按键按下,它就会返回. ...

  2. 《linux设备驱动开发详解》笔记——6字符设备驱动

    6.1 字符设备驱动结构 先看看字符设备驱动的架构: 6.1.1 cdev cdev结构体是字符设备的核心数据结构,用于描述一个字符设备,cdev定义如下: #include <linux/cd ...

  3. 嵌入式Linux驱动学习之路(二十一)字符设备驱动程序总结和块设备驱动程序的引入

    字符设备驱动程序 应用程序是调用C库中的open read write等函数.而为了操作硬件,所以引入了驱动模块. 构建一个简单的驱动,有一下步骤. 1. 创建file_operations 2. 申 ...

  4. arm-linux字符设备驱动开发之---简单字符设备驱动

    一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 1.字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面 ...

  5. Linux驱动实践:你知道【字符设备驱动程序】的两种写法吗?

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...

  6. LINUX设备驱动程序笔记(三)字符设备驱动程序

          <一>.主设备号和次设备号        对字符设备的訪问时通过文件系统内的设备名称进行的.那些设备名称简单称之为文件系统树的节点,它们通常位于/dev文件夹. 字符设备驱动程 ...

  7. Linux 简单字符设备驱动程序 (自顶向下)

    第零章:扯扯淡 特此总结一下写的一个简单字符设备驱动程序的过程,我要强调一下“自顶向下”这个介绍方法,因为我觉得这样更容易让没有接触过设备驱动程序的童鞋更容易理解,“自顶向下”最初从<计算机网络 ...

  8. ARM Linux字符设备驱动程序

    1.主设备号和次设备号(二者一起为设备号): 一个字符设备或块设备都有一个主设备号和一个次设备号.主设备号用来标识与设备文件相连的驱动程序,用来反  映设备类型.次设备号被驱动程序用来辨别操作的是哪个 ...

  9. 浅析Linux字符设备驱动程序内核机制

    前段时间在学习linux设备驱动的时候,看了陈学松著的<深入Linux设备驱动程序内核机制>一书. 说实话.这是一本非常好的书,作者不但给出了在设备驱动程序开发过程中的所须要的知识点(如对 ...

随机推荐

  1. [排序] 快排 && 冒泡(自己写)

    #include <iostream> using namespace std; /* 快速排序 通过一趟排序,以轴点为界 分割为两部分:左部分 <= 轴点 <= 右部分 再分 ...

  2. github and SourceTree初步使用

    1.建立连接(一次就行了) 输入你的github名字 2.创建仓库 3.下载仓库 这个时候打开SouceTree就可以看到之前创的仓库了 点击克隆,创建一个文件夹,讲路径设置好 这时候查看本地列表就会 ...

  3. Xcode 创建静态库和动态库

    1.linux中静态库和动态库区别: 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 静态库:这类库的名字一般是libxxx.a:利用静态函数库编译成的文件 ...

  4. win7 64 + Ubuntu 14.04.1 64双系统安装,详解UEFI ~ GPT和legacy ~ MBR区别

    win7 64 + Ubuntu 14.04.1 64双系统安装 背景:我的笔记本之前的系统是window 7 64 + Ubuntu 14.04.1,用UEFI引导系统.安装过程是先装的win7,再 ...

  5. SSH开发实践part3:hibernate继承映射

    0 大家好.上次讲了关于hibernate中双向1-N的映射配置,可以参考:http://www.cnblogs.com/souvenir/p/3784510.html 实际项目中,对象间的关系比较复 ...

  6. iphone 异常捕获处理

    iphone 异常捕获处理 1 void UncaughtExceptionHandler(NSException *exception) { 2 NSArray *arr = [exception ...

  7. lintcode:二叉树的路径和

    题目 给定一个二叉树,找出所有路径中各节点相加总和等于给定 目标值 的路径. 一个有效的路径,指的是从根节点到叶节点的路径. 解题 下面有个小bug 最后比较的时候是叶子节点为空,左右都有叶子结点,所 ...

  8. java应用程序利用Exe4j打包exe文件

    1.      使用简介: 把java应用程序打成exe文件我们可以借助第三方软件exe4j来完成.Exe4j大家可以在网上下载,下载地址是: http://www.ej-technologies.c ...

  9. iOS复杂动画之抽丝剥茧(Objective-C & Swift)

    一.前言 随着开发者的增多和时间的累积,AppStore已经有非常多的应用了,每年都有很多新的APP产生.但是我们手机上留存的应用有限,所以如何吸引用户,成为产品设计的一项重要内容.其中炫酷的动画效果 ...

  10. jquery:cookie

    jquery使用cookie需要引入cookie插件: 插件下载地址:http://plugins.jquery.com/cookie/ cookie设置.获取和删除 <body> < ...