1. 程式人生 > >arm驅動程式——按鍵程式4_poll(韋東山的視訊總結及針對linux-2.6.30)

arm驅動程式——按鍵程式4_poll(韋東山的視訊總結及針對linux-2.6.30)

static irqreturn_t button_irq(int irq,void *dev)
{
    irq_dec = (struct pindec*)dev;

    /*修改定時器的超時時間*/
    mod_timer(&second_key_timer,jiffies+HZ/100);
    return IRQ_RETVAL(IRQ_HANDLED);
}
static int second_key_poll_open(struct inode *inode, struct file *file)
{
    /*註冊中斷*/
    request_irq(IRQ_EINT1,button_irq,IRQ_TYPE_EDGE_BOTH,"s1",&pin_dec[0]);
    request_irq(IRQ_EINT4,button_irq,IRQ_TYPE_EDGE_BOTH,"s2",&pin_dec[1]);
    request_irq(IRQ_EINT2,button_irq,IRQ_TYPE_EDGE_BOTH,"s3",&pin_dec[2]);
    request_irq(IRQ_EINT0,button_irq,IRQ_TYPE_EDGE_BOTH,"s4",&pin_dec[3]);
    return 0;
}


static ssize_t second_key_poll_read(struct file *file, char __user *user_buffer, 
                                    size_t count, loff_t *ppos)
{
    if(count != 1)
    return -EINVAL;
    /*ev_press中斷標誌為0,休眠,即未發生中斷時,休眠*/
    wait_event_interruptible(button_wait_head,ev_press);
    /*傳資料到使用者空間*/
    copy_to_user(user_buffer,&key_val,1);
    /*中斷結束,中斷標誌置0,休眠*/
    ev_press = 0;
    return 1;
}
static unsigned int second_key_poll(struct file *file, 
                                    struct poll_table_struct*wait)
{

    unsigned int mask = 0;
    /*掛載到佇列中去*/
    poll_wait(file, &button_wait_head, wait);
    if(ev_press)
    mask = POLLIN; /*普通或優先順序帶資料可讀*/
    return mask;
}


static int second_key_poll_close(struct inode *inode, struct file *file)
{
    free_irq(IRQ_EINT1,&pin_dec[0]);
    free_irq(IRQ_EINT4,&pin_dec[1]);
    free_irq(IRQ_EINT2,&pin_dec[2]);
    free_irq(IRQ_EINT0,&pin_dec[3]);
    return 0;
}
void second_timer_function(unsigned long data)
{
    unsigned int pinval;
    struct pindec *pin_desc =irq_dec;
    /*獲得引腳狀態*/
    pinval=s3c2410_gpio_getpin(pin_desc->pin);
    if(pinval)
        key_val = pin_desc->val;
    else
        key_val = pin_desc->val|0x80;
    /*喚醒*/
    ev_press = 1;
    wake_up_interruptible(&button_wait_head);
}
/*定義一個file_operations結構體*/
static struct file_operations second_key_poll_fops = {
   .owner = THIS_MODULE,
   .open  = second_key_poll_open,
   .read  = second_key_poll_read,
   .poll  = second_key_poll,
   .release = second_key_poll_close,
};
static int second_key_init(void)
{
   /*註冊*/
   major = register_chrdev(0,"second_key",&second_key_poll_fops);
   /*建立類在/sys/class可以查詢到*/
   second_key_class = class_create(THIS_MODULE,"second_key_class");
   /*類下建立裝置可以在/sys/class/second_key_class可以查詢到*/
   second_key_device = 
     device_create(second_key_class,NULL,MKDEV(major,0),NULL,"second_key_device");
   /*初始化定時器*/
   init_timer(&second_key_timer);
   second_key_timer.function = second_timer_function;
   /*啟動定時器*/
   add_timer(&second_key_timer);
   return 0;
 }
static void second_key_exit(void)
{
    /*登出*/
    unregister_chrdev(major,"second_key");
    /*刪除定時器*/
    del_timer(&second_key_timer);
    /*登出類*/
    device_unregister(second_key_device);
    /*銷燬定義的類*/
    class_destroy(second_key_class);

}
/*修飾*/
module_init(second_key_init);
module_exit(second_key_exit);
MODULE_LICENSE("GPL");