内核版本:linux2.6.22.6 硬件平台:JZ2440

驱动源码 poll_key_int_drv.c :

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/poll.h> static struct class *key_int_class;
static struct class_device *key_int_class_device; volatile unsigned long *GPFCON=NULL;
volatile unsigned long *GPFDAT=NULL;
volatile unsigned long *GPGCON=NULL;
volatile unsigned long *GPGDAT=NULL; struct pin_desc
{
unsigned int pin;
unsigned int key_val;
}; static unsigned char key_val;
static volatile int ev_press=; static struct pin_desc pin_desc_array[]={{S3C2410_GPF0,0x01},{S3C2410_GPF2,0X02},{S3C2410_GPG3,0x03},{S3C2410_GPG11,0x04}}; static DECLARE_WAIT_QUEUE_HEAD(wait_key); static irqreturn_t key_handler(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) key_val = 0x08 | pindesc->key_val;
else key_val = pindesc->key_val; wake_up_interruptible(&wait_key);
ev_press = ;
return IRQ_RETVAL(IRQ_HANDLED);
} static int key_drv_open(struct inode *inode,struct file *file)
{
request_irq(IRQ_EINT0, key_handler,IRQT_BOTHEDGE,"KEY1", &pin_desc_array[]);
request_irq(IRQ_EINT2, key_handler,IRQT_BOTHEDGE,"KEY2", &pin_desc_array[]);
request_irq(IRQ_EINT11, key_handler,IRQT_BOTHEDGE,"KEY3",&pin_desc_array[]);
request_irq(IRQ_EINT19, key_handler,IRQT_BOTHEDGE,"KEY4",&pin_desc_array[]); return ;
} ssize_t key_drv_read(struct file *file,const char __user *buf,size_t count,loff_t *ppos)
{
if (count != )
return -EINVAL; wait_event_interruptible(wait_key,ev_press);
ev_press=;
copy_to_user(buf,&key_val,); return ;
} static int key_drv_close(struct inode *inode,struct file *file) {
free_irq(IRQ_EINT0, &pin_desc_array[]);
free_irq(IRQ_EINT2, &pin_desc_array[]);
free_irq(IRQ_EINT11, &pin_desc_array[]);
free_irq(IRQ_EINT19, &pin_desc_array[]); return ;
} unsigned int key_drv_poll(struct file *file,poll_table *wait)
{
unsigned int mask=;
poll_wait(file,&wait_key,wait); if(ev_press) mask |= POLLIN | POLLRDNORM; return mask;
} static struct file_operations key_drv_mode=
{
.owner = THIS_MODULE,
.open = key_drv_open,
.read = key_drv_read,
.release = key_drv_close,
.poll = key_drv_poll, //发生中断才调用
}; //poll机制就是给定一段时间,在这一段时间内驱动处于睡眠状态一直等待某一个资源,
//得到资源则返回,超过时间也返回,有其他信号等待处理也返回
//返回后进程就是运行模式,不是休眠模式 int major=;
static int key_drv_init(void)
{
major = register_chrdev(,"poll_key_int_drv",&key_drv_mode); // /proc/devices key_int_class = class_create(THIS_MODULE,"key_int_class");
key_int_class_device = class_device_create(key_int_class,NULL,MKDEV(major,),NULL,"poll_key_int_drv"); // /dev/key_int_drv GPFCON=(volatile unsigned long *)ioremap(0x56000050,);
GPFDAT=GPFCON+;
GPGCON=(volatile unsigned long *)ioremap(0x56000060,);
GPGDAT=GPGCON+; return ;
} static void key_drv_exit(void)
{
unregister_chrdev(major,"poll_key_int_drv"); class_device_unregister(key_int_class_device);
class_destroy(key_int_class);
iounmap(GPFCON);
iounmap(GPGCON); } module_init(key_drv_init);
module_exit(key_drv_exit);
MODULE_LICENSE("GPL");

测试应用程序 poll_key_int_drv_test.c :

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<poll.h> int main(int argc,char **argv)
{
int fd=;
unsigned char key_val=; int ret;
struct pollfd fds[]; fd = open("/dev/poll_key_int_drv",O_RDWR);
if(fd <) printf("error: can't open device :/dev/poll_key_int_drv"); fds[].fd =fd;
fds[].events = POLLIN;
while()
{
ret = poll(fds, ,);
if(ret==) printf("time out\n");
else
{
read(fd,&key_val,);
printf("key_val=%d\n",key_val);
}
}
return ;
}

Makefile文件:

KER_DIR=/work/systems/kernel/linux-/linux-2.6.22.6

all:
make -C $(KER_DIR) M=`pwd` modules clean:
make -C $(KER_DIR) M=`pwd` modules clean
rm -fr moudles.order obj-m +=key_int_drv.o

内核poll机制的更多相关文章

  1. Linux内核poll/select机制简析

    0 I/O多路复用机制 I/O多路复用 (I/O multiplexing),提供了同时监测若干个文件描述符是否可以执行IO操作的能力. select/poll/epoll 函数都提供了这样的机制,能 ...

  2. poll机制分析

    更多文档:http://pan.baidu.com/s/1sjzzlDF linux poll/select用法及在字符驱动中的简单实现 1.poll和select 使用非阻塞I/O 的应用程序常常使 ...

  3. Linux学习 :中断处理机制 & poll机制

    中断是指在CPU正常运行期间,由于内外部事件或由程序预先安排的事件引起的CPU暂时停止正在运行的程序,转而为该内部或外部事件或预先安排的事件服务 的程序中去,服务完毕后再返回去继续运行被暂时中断的程序 ...

  4. 入门级的按键驱动——按键驱动笔记之poll机制-异步通知-同步互斥阻塞-定时器防抖

    文章对应视频的第12课,第5.6.7.8节. 在这之前还有查询方式的驱动编写,中断方式的驱动编写,这篇文章中暂时没有这些类容.但这篇文章是以这些为基础写的,前面的内容有空补上. 按键驱动——按下按键, ...

  5. 韦东山驱动视频笔记——3.字符设备驱动程序之poll机制

    linux内核版本:linux-2.6.30.4 目的:我们在中断方式的按键应用程序中,如果没有按键按下,read就会永远在那等待,所以如果在这个程序里还想做其他事就不可能了.因此我们这次改进它,让它 ...

  6. poll机制分析[转]

    所有的系统调用,基于都可以在它的名字前加上"sys_"前缀,这就是它在内核中对应的函数.比如系统调用open.read.write.poll,与之对应的内核函数为:sys_open ...

  7. 8.中断按键驱动程序之poll机制

    本节继续在上一节中断按键程序里改进,添加poll机制. 那么我们为什么还需要poll机制呢.之前的测试程序是这样: ) { read(fd, &key_val, ); printf(" ...

  8. linux驱动编写之poll机制

    一.概念 1.poll情景描述 以按键驱动为例进行说明,用阻塞的方式打开按键驱动文件/dev/buttons,应用程序使用read()函数来读取按键的键值.这样做的效果是:如果有按键按下了,调用该re ...

  9. 字符设备驱动(六)按键poll机制

    title: 字符设备驱动(六)按键poll机制 tags: linux date: 2018-11-23 18:57:40 toc: true --- 字符设备驱动(六)按键poll机制 引入 在字 ...

随机推荐

  1. React Native 进的第一个坑

    Bundling index.ios.js [development, non-minified, hmr disabled] 0.0% (0/1), failed. error: bundling ...

  2. Netbeans rcp中获得本地文件系统路径

    通过file协议 —————————————————————————————————————————————————————— URL url = new URL("file:///E:/A ...

  3. Active Directory Authentication in ASP.NET MVC 5 with Forms Authentication and Group-Based Authorization

    I know that blog post title is sure a mouth-full, but it describes the whole problem I was trying to ...

  4. SpringSecurity兑现多登录成功页面和登录成功返回被拦截界面

    SpringSecurity实现多登录成功页面和登录成功返回被拦截界面 使用SrpingSceurity作为认证和授权的安全框架可以省下很多基础工作. 具体可以参考SpringSecurity,这里不 ...

  5. [原]VS2012编译GLEW 1.11

    1.到http://glew.sourceforge.net/下载源代码 2.使用vs2012打开build下vc6的glew.dsw ,自动生成2012工程(一路点确定)特别注意:不要使用build ...

  6. 8 -- 深入使用Spring -- 5...3 使用@CacheEvict清除缓存

    8.5.3 使用@CacheEvict清除缓存 被@CacheEvict注解修饰的方法可用于清除缓存,使用@CacheEvict注解时可指定如下属性: ⊙ value : 必须属性.用于指定该方法用于 ...

  7. MySql安全模式的关闭和开启

    #MySql关闭安全模式 ; commit; #MySql开启安全模式 ; commit;

  8. 十二、K3 WISE 开发插件《工业单据老单与自己添加的窗体 - 互相传值传参》

    ===================================== 目录: 1.演示效果--[销售订单]传值给[自定义窗体] 2.演示效果--[自定义窗体]传值给[销售订单] 3.附源码 4. ...

  9. 关于ie6出现的问题的原因归结

    关于ie6出现的问题主要可以归结为以下几种情况把. 当然还存在各种原因,bug的情况也还有各种各样,我只是小结一下我自己经常遇到,比较有代表性的问题.会持续的更新. 1.浏览器本身存在的缺陷 比如: ...

  10. MFC窗口阴影

    SetClassLong(this->m_hWnd, GCL_STYLE, GetClassLong(this->m_hWnd, GCL_STYLE) | CS_DROPSHADOW);