博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
韦东山驱动视频笔记——3.字符设备驱动程序之poll机制
阅读量:5277 次
发布时间:2019-06-14

本文共 4522 字,大约阅读时间需要 15 分钟。

linux内核版本:linux-2.6.30.4 

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

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
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[4] = 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 = 0; 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 = 1; 60 61 return IRQ_HANDLED; 62 } 63 64 65 static int fourth_drv_open(struct inode *inode, struct file *file) 66 { 67 request_irq(IRQ_EINT1, buttons_irq, IRQ_TYPE_EDGE_BOTH, "S1", &pins_desc[0]); 68 request_irq(IRQ_EINT4, buttons_irq, IRQ_TYPE_EDGE_BOTH, "S2", &pins_desc[1]); 69 request_irq(IRQ_EINT2, buttons_irq, IRQ_TYPE_EDGE_BOTH, "S3", &pins_desc[2]); 70 request_irq(IRQ_EINT0, buttons_irq, IRQ_TYPE_EDGE_BOTH, "S4", &pins_desc[3]); 71 return 0; 72 } 73 74 75 static ssize_t fourth_drv_read(struct file *file, char __user *buf, 76 size_t count, loff_t *ppos) 77 { 78 if (count != 1) 79 return -EINVAL; 80 /*如果没有按键动作,休眠*/ 81 wait_event_interruptible(button_waitq, ev_press); 82 83 84 /*如果有按键动作发生,返回键值*/ 85 copy_to_user(buf, &key_val, 1); 86 ev_press = 0; 87 return 1; 88 } 89 90 static int fourth_drv_release(struct inode *inode, struct file *file) 91 { 92 free_irq(IRQ_EINT1, &pins_desc[0]); 93 free_irq(IRQ_EINT4, &pins_desc[1]); 94 free_irq(IRQ_EINT2, &pins_desc[2]); 95 free_irq(IRQ_EINT0, &pins_desc[3]); 96 return 0; 97 } 98 99 static unsigned int fourth_drv_poll(struct file *file, poll_table *wait) 100 101 { 102 unsigned int mask = 0; 103 104 /*这并不会休眠,只是把当前进程挂到队列里*/ 105 poll_wait(file, &button_waitq, wait); 106 107 if (ev_press) 108 { 109 mask |= (POLLIN | POLLRDNORM); 110 } 111 return mask; 112 } 113 114 115 static struct file_operations fourth_fops = { 116 .owner = THIS_MODULE, 117 .open = fourth_drv_open, 118 .read = fourth_drv_read, 119 .poll = fourth_drv_poll, 120 .release = fourth_drv_release, 121 }; 122 123 int fourth_init() 124 { 125 int ret; 126 major = register_chrdev(0, "fourth_drv", &fourth_fops); 127 fourth_drv_class = class_create(THIS_MODULE, "fourth_drv"); 128 device_create(fourth_drv_class, NULL, MKDEV(major, 0), NULL, "buttons"); 129 130 gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16); 131 gpfdat = gpfcon + 1; 132 133 return 0; 134 } 135 static void fourth_exit() 136 { 137 unregister_chrdev(major, "fourth_drv"); 138 device_destroy(fourth_drv_class, MKDEV(major, 0)); 139 class_destroy(fourth_drv_class); 140 iounmap(gpfcon); 141 } 142 143 module_init(fourth_init); 144 module_exit(fourth_exit); 145 146 MODULE_LICENSE("GPL");

测试程序:

1 #include 
2 #include
3 #include
4 #include
5 #include
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[1]; 15 16 17 fd = open("/dev/buttons", O_RDWR); 18 if (fd < 0) 19 { 20 printf("can't open!\n"); 21 } 22 23 fds[0].fd = fd; 24 fds[0].events = POLLIN; 25 while (1) 26 { 27 ret = poll(fds, 1, 5000); 28 if (ret == 0) 29 { 30 printf("time out!\n"); 31 } 32 else 33 { 34 read(fd, &key_val, 1); 35 printf("key_val === 0x%x\n", key_val); 36 } 37 } 38 39 return 0; 40 }

运行效果:

 

转载于:https://www.cnblogs.com/linux-rookie/p/3245407.html

你可能感兴趣的文章
161017、SQL必备知识点
查看>>
kill新号专题
查看>>
MVC学习系列——Model验证扩展
查看>>
mysqladmin 修改和 初始化密码
查看>>
字符串
查看>>
vue2.x directive - 限制input只能输入正整数
查看>>
实现MyLinkedList类深入理解LinkedList
查看>>
自定义返回模型
查看>>
C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 客户端多网络支持
查看>>
HDU 4122
查看>>
Suite3.4.7和Keil u3自带fx2.h、fx2regs.h文件的异同
查看>>
打飞机游戏【来源于Crossin的编程教室 http://chuansong.me/account/crossincode 】
查看>>
[LeetCode] Merge Intervals
查看>>
【翻译自mos文章】当点击完 finishbutton后,dbca 或者dbua hang住
查看>>
Linux编程简介——gcc
查看>>
2019年春季学期第四周作业
查看>>
MVC4.0 利用IActionFilter实现简单的后台操作日志功能
查看>>
rotate the clock
查看>>
bugku 变量
查看>>
数据库01 /Mysql初识以及基本命令操作
查看>>