arm驅動程式——按鍵程式4_poll(韋東山的視訊總結及針對linux-2.6.30)
阿新 • • 發佈:2019-02-06
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");
{
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");