wang12zhedi 发表于 2012-9-21 19:29:50

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 10:31:07

本帖最后由 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]
查看完整版本: poll机制的调用方法