poll机制的调用方法
我的中断驱动程序/*中断法测试按键*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/poll.h>
static struct class *button_class;
static struct class_device *button_class_dev;
/* 定义变量*/
static DECLARE_WAIT_QUEUE_HEAD(button_waitq);/*等待队列头,为休眠和唤醒做准备*/
/*中断事件标志,中断服务程序将其置1,read函数将它请0*/
static volatile int ev_press = 0;
static unsigned long gpio_table [] =
{
S3C2410_GPF0,
S3C2410_GPF1,
S3C2410_GPF2,
S3C2410_GPF4,
};
/* 用来指定GPIO引脚的功能:输出 */
static unsigned int gpio_cfg_table [] =
{
S3C2410_GPF0_INP,
S3C2410_GPF1_INP,
S3C2410_GPF2_INP,
S3C2410_GPF4_INP,
};
/*结构体类型的声明*/
struct pin_desc{
unsigned int pin;
unsigned int pin_val;
};
unsigned int key_val;
/*当按下按键显示 0X01 0X02 0X04 0X08
当松开按键时,显示0X81 0X82 0X84 0X88
*/
struct pin_desc pins_desc = {//结构体数组初始化
{S3C2410_GPF0, 0x01},
{S3C2410_GPF1, 0x02},
{S3C2410_GPF2, 0x03},
{S3C2410_GPF4, 0x04},
};
/*
*确定按键值
*/
staticirqreturn_t button_irq(int irq,void *dev_id)
{
struct pin_desc * pindesc = (struct pin_desc *)dev_id;//(struct pin_desc *)强制类型转换
//(struct pin_desc *)dev_id;传入时已经创中断信息?????????
unsigned int pin_value;
pin_value=s3c2410_gpio_getpin(pindesc ->pin);
if(pin_value )
{
/*按下按键*/
key_val = 0x80 |pindesc->pin_val;
}
else
{
/*松开按键?/
key_val = pindesc ->pin_val;
}
ev_press = 1; //表示中断发生
wake_up_interruptible(&button_waitq);//唤醒休眠
//printk(" button_irqoccured\n");
return IRQ_HANDLED; /*return应该在函数的最后,不然return之后的代码不起作用的澹垮*/
}
static int button_open(struct inode *inode, struct file *file)//此处的函数名可以随便热″?只要在fopsd的对应
//正确即可???????????
{
/* 配置GPF0,2为输入引脚 */
request_irq(IRQ_EINT0,button_irq,IRQ_TYPE_EDGE_BOTH,"KEY4",&pins_desc);
request_irq(IRQ_EINT1,button_irq,IRQ_TYPE_EDGE_BOTH,"KEY1",&pins_desc);
request_irq(IRQ_EINT2,button_irq,IRQ_TYPE_EDGE_BOTH,"KEY3",&pins_desc);
request_irq(IRQ_EINT4,button_irq,IRQ_TYPE_EDGE_BOTH,"KEY2",&pins_desc);
// printk("button_open\n");
return 0;
}
ssize_t button_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
/* 如果没有按键动作发生,休眠 */
wait_event_interruptible(button_waitq,ev_press);////当有按键按下时,中断当前运行(终止当前休眠)
//跳转到button_irq处继续运行,当button_irq运行完毕,再从此处继续向下运行
/* 如果有按键动作发生,返回按键值 */
if (size != 1)
return -EINVAL;
copy_to_user(buf,&key_val,1);
ev_press = 0;
//printk("button_read\n");
return 1;
}
/*释放中断函数*/
int button_release(struct inode * inode, struct file * file)
{
free_irq(IRQ_EINT0,&pins_desc);
free_irq(IRQ_EINT1,&pins_desc);
free_irq(IRQ_EINT2,&pins_desc);
free_irq(IRQ_EINT4,&pins_desc);
// printk("button_release\n");
}
static unsigned button_poll(struct file *file,poll_table *wait)
{
unsigned int mask = 0;
poll_wait(file,&button_waitq,wait);
if(ev_press)
mask |=POLLIN |POLLRDNORM;
return mask;
}
static struct file_operations button_fops = {
.owner= THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
.open = button_open,
.read = button_read,
.release = button_release,
.poll = button_poll,
};
int major;
static int button_init(void)
{
major = register_chrdev(0, "button_drv", &button_fops);
button_class = class_create(THIS_MODULE, "buttons_irq");
button_class_dev = device_create(button_class, NULL, MKDEV(major, 0), NULL, "Buttons_irq"); /* /dev/buttons */
printk("button_init\n");
return 0;
}
static void button_exit(void)
{
unregister_chrdev(major, "button");
device_unregister(button_class_dev);
class_destroy(button_class);
printk("button_exit\n");
return 0;
}
module_init(button_init);
module_exit(button_exit);
MODULE_LICENSE("GPL");
我的测试程序
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
/* seconddrvtest
*/
int main(int argc, char **argv)
{
int fd;
int retd;
/*这里的key_val是在测试程序里定义的,无需和驱动程序里
copy_to_user(buf,&key_val,1);中的key_val相同,其实从变量的作用域角度
也很容易理解
*/
unsigned char key_val;
int cnt = 0;
int ret;
struct pollfd fda;;
fd = open("/dev/Buttons_irq", O_RDWR);
if (fd < 0)
{
printf("can't open!\n\n");
}
fda.fd= fd;
fda.events = POLLIN;
while (1)
{
retd = poll(fda,1,8000);//超时时间以毫秒为单位;
if(retd==0)
printf("time out\n");
else
{
ret=read(fd, &key_val, 1);
printf ("keykey_val = 0x%x\n",key_val);
}
}
return 0;
}
问题:测试程序中retd = poll(fda,1,8000);//超时时间以毫秒为单位;
的三个参数是如何传递给内核的,
static unsigned button_poll(struct file *file,poll_table *wait)只有两个参数呀?? 本帖最后由 wang12zhedi 于 2012-9-22 11:50 编辑
网上说先调用sys_poll,但是
没找到这个函数呀
.
sys_poll函数位于fs/select.c文件中,代码如下:
asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,
long timeout_msecs)
{
……
这个函数是不是在2.6.30.4里改变啦
页:
[1]