实现的功能是在读取按键信息的时候,如果没有产生按键,则程序休眠在read函数中,利用poll机制,可以在没有退出的情况下让程序自动退出。

下面的程序就是在读取按键信息的时候,如果5000ms内没有按键信息,则自己退出。

首先应用程序执行poll函数

    kernel中的sys_poll

            do_sys_poll

              init_poll_funcptr-->do_poll

            do_poll

              for(;;)

              {

                if(do_pollfd(pfd,pt))

                {  

                  count++;  //如果驱动的poll返回非0值,那么count++

                  //把进程挂到队列中休眠

                   pt=null;}

                if( count || !*timeout || signal_pending(current))

                  break; //如果count非0  超时, 有信号等待处理

              }

              __timeout = schedule_timeout(__time_out);  //休眠 下次执行到上面的判断时,就会超时退出

驱动代码:

#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/random.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <linux/irq.h>
#include <linux/fs.h>
#include <asm/arch/regs-gpio.h>
#include <linux/interrupt.h>
#include <linux/poll.h> static struct class *key_class; //创建类
static struct class_device *key_class_devs; //创建类对应的设备 struct pin_desc{
unsigned int pin;
unsigned int key_val;
};
struct pin_desc pins_desc[] = {
{S3C2410_GPF0,0X01},
{S3C2410_GPF2,0X02},
{S3C2410_GPG3,0X03},
{S3C2410_GPG11,0X04},
};
unsigned char keyvals=; static volatile int ev_press = ;
static DECLARE_WAIT_QUEUE_HEAD(button_waitq); static irqreturn_t keys_irq(int irq, void *dev_id)
{
struct pin_desc *pindesc = (struct pin_desc *)dev_id;
unsigned int pinval;
pinval = s3c2410_gpio_getpin(pindesc->pin);
if(pinval)
{
keyvals = pindesc->key_val|0x80;
}
else
{
keyvals = pindesc->key_val;
}
ev_press = ;
wake_up_interruptible(&button_waitq);
return IRQ_HANDLED;
} int key_open(struct inode *inode, struct file *fp)
{
request_irq( IRQ_EINT0, keys_irq, IRQT_BOTHEDGE, "key2", &pins_desc[]);
request_irq( IRQ_EINT2, keys_irq, IRQT_BOTHEDGE, "key3", &pins_desc[]);
request_irq( IRQ_EINT11, keys_irq, IRQT_BOTHEDGE, "key4", &pins_desc[]);
request_irq( IRQ_EINT19, keys_irq, IRQT_BOTHEDGE, "key5", &pins_desc[]);
return ;
} ssize_t key_read(struct file *fp, char __user *buff, size_t count, loff_t *offp){ if(count != )
{
return -EINVAL;
}
wait_event_interruptible(button_waitq,ev_press); copy_to_user(buff,&keyvals,);
ev_press = ;
return ;
} ssize_t key_write(struct file *fp, const char __user *buf, size_t count, loff_t *ppos){
} int key_close(struct inode *inode, struct file *file)
{
free_irq(IRQ_EINT0,&pins_desc[]);
free_irq(IRQ_EINT2,&pins_desc[]);
free_irq(IRQ_EINT11,&pins_desc[]);
free_irq(IRQ_EINT19,&pins_desc[]);
} static unsigned int key_poll(struct file *file, struct poll_table_struct *wait)
{
unsigned int mask = ;
poll_wait(file, &button_waitq,wait);
if(ev_press)
mask |= POLLIN|POLLRDNORM;
return mask;
} struct file_operations led_fops={
.owner = THIS_MODULE,
.open = key_open,
.write = key_write,
.read = key_read,
.release = key_close,
.poll = key_poll,
}; int major;
static int key_init(void)
{
major = register_chrdev( ,"key_drv", &led_fops );
key_class = class_create(THIS_MODULE,"key_class");
key_class_devs = class_device_create(key_class,NULL,MKDEV(major,),NULL,"my_keys"); printk("key install Module\n");
return ;
} static void key_exit(void)
{
unregister_chrdev( major, "key_drv" );
class_device_unregister(key_class_devs);
class_destroy(key_class);
printk("key Module exit\n");
} module_init(key_init);
module_exit(key_exit);
MODULE_LICENSE("GPL");

应用测试代码:

#include <stdio.h>
#include <fcntl.h>
#include <poll.h> int main()
{
int fd;
int ret;
struct pollfd pfd[];
unsigned char key_val;
fd = open("/dev/my_keys",O_RDWR);
if(fd<)
{
printf("open failed\n");
return ;
}
pfd[].fd = fd;
pfd[].events = POLLIN;
while()
{
ret = poll(pfd, , );    //如果在5000ms之内没有按下按键 这自动退出
// read(fd, &key_val,1);
if(ret==)
printf("time out\n");
else
{
read(fd, &key_val,);
printf("key:%x\n",key_val);
}
}
}

sd

嵌入式Linux驱动学习之路(十二)按键驱动-poll机制的更多相关文章

  1. 嵌入式Linux驱动学习之路(十五)按键驱动-定时器防抖

    在之前的定时器驱动程序中,我们发现在连续按下按键的时候,正常情况下应该是一次按下对应一次松开.而程序有时候会显示是两次按下,一次松开.这个问题是因为在按下的时候,因为是机械按键,所以电压信号会产生一定 ...

  2. 嵌入式Linux驱动学习之路(十四)按键驱动-同步、互斥、阻塞

    目的:同一个时刻,只能有一个应用程序打开我们的驱动程序. ①原子操作: v = ATOMIC_INIT( i )  定义原子变量v并初始化为i atomic_read(v)        返回原子变量 ...

  3. 嵌入式Linux驱动学习之路(十八)LCD驱动

    驱动代码: /************************************************************************* > File Name: lcd ...

  4. 嵌入式Linux驱动学习之路(十)字符设备驱动-my_led

    首先贴上代码: 字符设备驱动代码: /** *file name: led.c */#include <linux/sched.h> #include <linux/signal.h ...

  5. 嵌入式Linux驱动学习之路(十九)触摸屏驱动、tslib测试

    触摸屏使用流程: 1. 按下产生中断. 2.在中断处理程序中启动AD转换XY坐标. 3.AD转换结束并产生AD中断. 4. 在AD的中断处理函数中上报信息,启动定时器. 5. 定时器时间到后进入中断, ...

  6. 嵌入式Linux驱动学习之路(十六)输入子系统

    以前写的一些输入设备的驱动都是采用字符设备处理的.问题由此而来,Linux开源社区的大神们看到了这大量输入设备如此分散不堪,有木有可以实现一种机制,可以对分散的.不同类别的输入设备进行统一的驱动,所以 ...

  7. 嵌入式linux的学习之路[转]

    我认为的一条学习嵌入式Linux的路: 1)学习 Linux系统安装. 常用命令.应用程序安装. 2) 学习 Linux 下的 C 编程.这本书必学<UNIX 环境高级编程>.<UN ...

  8. zigbee学习之路(十二):zigbee协议原理介绍

    一.前言 从今天开始,我们要正式开始进行zigbee相关的通信实验了,我所使用的协议栈是ZStack 是TI ZStack-CC2530-2.3.0-1.4.0版本,大家也可以从TI的官网上直接下载T ...

  9. Object-c学习之路十二(OC的copy)

    oc中的拷贝分为:copy(浅拷贝)和mutablecopy(深拷贝). 浅拷贝也为指针拷贝,拷贝后原来的对象计数器会+1: 深拷贝为对象拷贝,原来的对象计数器不变. 注意:自定义对象拷贝时要实现NS ...

随机推荐

  1. 更换Kali源让你更新更快

    在2016.1版本kali-linux(也就是kali滚动更新版)更新慢解决办法: (此源为2.0版本)中科大kali滚动更新版源(即kali2.0源) #kali官方源 deb http://htt ...

  2. WCF入门教程1——WCF简要介绍

    什么是WCF Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台. 整合了原有的windo ...

  3. [ASP.NET Core] Static File Middleware

    前言 本篇文章介绍ASP.NET Core里,用来处理静态档案的Middleware,为自己留个纪录也希望能帮助到有需要的开发人员. ASP.NET Core官网 结构 一个Web站台最基本的功能,就 ...

  4. jQuery拉开关闭帷幕

    查看效果:http://keleyi.com/keleyi/phtml/jqtexiao/7.htm HTML文件代码: <!DOCTYPE html PUBLIC "-//W3C// ...

  5. 深入浅出node(1) Node简介

    这一系列主要是自己在学习深入浅出node.js这本书的学习笔试,部分加入了自己的一些理解 分享给一起学习node的小伙伴 自己还是个初学者 有很多地方理解的不到位 一起交流 一 什么是node 1.1 ...

  6. 【blade的UI设计】理解前端MVC与分层思想

    前言 最近校招要来了,很多大三的同学一定按捺不住心中的焦躁,其中有期待也有彷徨,或许更多的是些许担忧,最近在开始疯狂的复习了吧 这里小钗有几点建议给各位: ① 不要看得太重,关心则乱,太紧张反而表现不 ...

  7. Android开发—已root的手机获取data路径

    开发android的时候,尽管手机已经root但是DDMS中还是没有data/data路径怎么办? 可以用cmd命令提示符为逐个文件夹设置权限: 打开cmd,输入 adb shell  回车—> ...

  8. Android Studio 恢复小窗口停靠模式(Docked Mode)

    安卓studio在使用小窗口时,如果我们点击取消了窗口的docked mode模式,窗口就会变成,你一旦触发窗口以外的区域,窗口就会龟缩回去.此时,如果你想要恢复回原来的docked mode的话,具 ...

  9. 数据结构->冒泡排序

    数据结构->冒泡排序 实现效果 从小到大排序 算法原理 重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到不再需要交换,也就是说该数列 ...

  10. (六)Maven之pom.xml文件简单说明

    通过前面几部分知识,我们对maven已经有了初步的印象,就像Make的Makefile.Ant的build.xml一样,Maven项目的核心是pom.xml.POM(Project Object Mo ...