if(ret)
return ret;
ret = request_irq(IRQ_EINT(2), buttons_irq, IRQ_TYPE_EDGE_BOTH, "key3", &key_descs[2]);
if(ret)
return ret;
ret = request_irq(IRQ_EINT(3), buttons_irq, IRQ_TYPE_EDGE_BOTH, "key4", &key_descs[3]);
if(ret)
return ret;
ret = request_irq(IRQ_EINT(4), buttons_irq, IRQ_TYPE_EDGE_BOTH, "key5", &key_descs[4]);
if(ret)
return ret;
ret = request_irq(IRQ_EINT(5), buttons_irq, IRQ_TYPE_EDGE_BOTH, "key6", &key_descs[5]);
if(ret)
return ret;
ret = request_irq(IRQ_EINT(22), buttons_irq, IRQ_TYPE_EDGE_BOTH, "key7", &key_descs[6]);
if(ret)
return ret;
ret = request_irq(IRQ_EINT(23), buttons_irq, IRQ_TYPE_EDGE_BOTH, "key8", &key_descs[7]);
if(ret)
return ret;
return 0;
}
static ssize_t buttons_read(struct file * file, char __user *data, size_t count, loff_t *loff){
if(count != 1){
printk(KERN_ERR "The driver can only give one key value once!\n");
return -ENOMEM;
}
wait_event_interruptible(button_waitq, pressed);
pressed = 0;
if(copy_to_user(data, &key_val, 1)){
printk(KERN_ERR "The driver can not copy the data to user area!\n");
return -ENOMEM;
}
return 0;
}
static int buttons_close(struct inode *inode, struct file *file){
free_irq(IRQ_EINT(0), &key_descs[0]);
free_irq(IRQ_EINT(1), &key_descs[1]);
free_irq(IRQ_EINT(2), &key_descs[2]);
free_irq(IRQ_EINT(3), &key_descs[3]);
free_irq(IRQ_EINT(4), &key_descs[4]);
free_irq(IRQ_EINT(5), &key_descs[5]);
free_irq(IRQ_EINT(22), &key_descs[6]);
free_irq(IRQ_EINT(23), &key_descs[7]);
return 0;
}
struct file_operations buttons_ops = {
.open = buttons_open,
.read = buttons_read,
.release = buttons_close,
};
int buttons_init(void){
int ret;
cdev_init(&cdev, &buttons_ops);
cdev.owner = THIS_MODULE;
ret = alloc_chrdev_region(&devno, 0, 1, "buttons");
if(ret){
printk(KERN_ERR "alloc char device region faild!\n");
return ret;
}
ret = cdev_add(&cdev, devno, 1);
if(ret){
printk(KERN_ERR "add char device faild!\n");
goto add_error;
}
buttons_class = class_create(THIS_MODULE, "buttonsdrv");
if(IS_ERR(buttons_class)){
printk(KERN_ERR "create class error!\n");
goto class_error;
}
buttons_device = device_create(buttons_class, NULL, devno, NULL, "buttons");
if(IS_ERR(buttons_device)){
printk(KERN_ERR "create buttons device error!\n");
goto device_error;
}
init_waitqueue_head(&button_waitq);
return 0;
device_error:
class_destroy(buttons_class);
class_error:
cdev_del(&cdev);
add_error:
unregister_chrdev_region(devno,1);
return -ENODEV;
}
void buttons_exit(void){
device_destroy(buttons_class, devno);
class_destroy(buttons_class);
cdev_del(&cdev);
unregister_chrdev_region(devno, 1);
}
module_init(buttons_init);
module_exit(buttons_exit);
MODULE_LICENSE("GPL");
测试程序代码:
[cpp]
#include
#include
int main(){
int fd = open("/dev/buttons", O_RDWR);
if(fd < 0){
printf("open error");;
return 0;
}
unsigned char key;
while(1){
read(fd, &key, 1);
printf("The key = %x\n", key);
}
close(fd);
}
#include
#include
int main(){
int fd = open("/dev/buttons", O_RDWR);
if(fd < 0){
printf("open error");;
return 0;
}
unsigned char key;
while(1){
read(fd, &key, 1);
printf("The key =