|  | 
 
| 我的中断驱动程序 /*中断法测试按键*/
 #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[4] = {  //结构体数组初始化
 {S3C2410_GPF0, 0x01},
 {S3C2410_GPF1, 0x02},
 {S3C2410_GPF2, 0x03},
 {S3C2410_GPF4, 0x04},
 };
 /*
 *确定按键值
 */
 static  irqreturn_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_irq  occured\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[0]);
 request_irq(IRQ_EINT1,button_irq,IRQ_TYPE_EDGE_BOTH,"KEY1",&pins_desc[1]);
 request_irq(IRQ_EINT2,button_irq,IRQ_TYPE_EDGE_BOTH,"KEY3",&pins_desc[2]);
 request_irq(IRQ_EINT4,button_irq,IRQ_TYPE_EDGE_BOTH,"KEY2",&pins_desc[3]);
 
 // 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[0]);
 free_irq(IRQ_EINT1,&pins_desc[1]);
 free_irq(IRQ_EINT2,&pins_desc[2]);
 free_irq(IRQ_EINT4,&pins_desc[3]);
 // 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[1];;
 
 fd = open("/dev/Buttons_irq", O_RDWR);
 if (fd < 0)
 {
 printf("can't open!\n\n");
 
 }
 
 fda[0].fd= fd;
 fda[0].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)只有两个参数呀??
 | 
 |