linux中断如何通知应用程序,linux中断和异步通知 基于QT210

#include static dev_t devno;

static struct cdev cdev;

static struct class* buttons_class;

static struct device* buttons_device;

static wait_queue_head_t button_waitq;

static struct timer_list buttons_timer;

static volatile int pressed = 0;

static unsigned int key_val;

static struct fasync_struct *button_async;

struct key_desc{

unsigned int pin;

unsigned char value;

};

static struct key_desc *irq_pd;

static volatile unsigned long *gph3con;

static volatile unsigned long *gph3dat;

static struct key_desc key_descs[8] = {

[0] = {

.pin = S5PV210_GPH2(3),

.value = 0x00,

},

[1] = {

.pin = S5PV210_GPH2(4),

.value = 0x01,

},

[2] = {

.pin = S5PV210_GPH2(5),

.value = 0x02,

},

[3] = {

.pin = S5PV210_GPH2(6),

.value = 0x03,

},

[4] = {

.pin = S5PV210_GPH2(7),

.value = 0x04,

},

};

static void buttons_timer_function(unsigned long data)

{

struct key_desc * pindesc = irq_pd;

unsigned int pinval;

if (!pindesc)

return;

pinval = gpio_get_value(pindesc->pin);

if (pinval)

{

/* 松开 */

key_val = 0x80 | pindesc->value;

}

else

{

/* 按下 */

key_val = pindesc->value;

}

pressed = 1;

wake_up_interruptible(&button_waitq);

kill_fasync (&button_async, SIGIO, POLL_IN);

}

static irqreturn_t buttons_irq(int irq, void *dev_id){

printk("buttons_irq happen\n");

/* 10ms后启动定时器 */

irq_pd = (struct key_desc *)dev_id;

mod_timer(&buttons_timer, jiffies+HZ/100);

return IRQ_RETVAL(IRQ_HANDLED);

}

static int buttons_open(struct inode *inode, struct file *file){

int ret;

ret = request_irq(IRQ_EINT(19), buttons_irq, IRQ_TYPE_EDGE_BOTH, "key1", &key_descs[0]);

if(ret)

return ret;

ret = request_irq(IRQ_EINT(20), buttons_irq, IRQ_TYPE_EDGE_BOTH, "key2", &key_descs[1]);

if(ret)

return ret;

ret = request_irq(IRQ_EINT(21), buttons_irq, IRQ_TYPE_EDGE_BOTH, "key3", &key_descs[2]);

if(ret)

return ret;

ret = request_irq(IRQ_EINT(22), buttons_irq, IRQ_TYPE_EDGE_BOTH, "key4", &key_descs[3]);

if(ret)

return ret;

ret = request_irq(IRQ_EINT(23), buttons_irq, IRQ_TYPE_EDGE_BOTH, "key5", &key_descs[4]);

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)

return -EINVAL;

if (file->f_flags & O_NONBLOCK)

{

if (!pressed)

return -EAGAIN;

}

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(19), &key_descs[0]);

free_irq(IRQ_EINT(20), &key_descs[1]);

free_irq(IRQ_EINT(21), &key_descs[2]);

free_irq(IRQ_EINT(22), &key_descs[3]);

free_irq(IRQ_EINT(23), &key_descs[4]);

return 0;

}

static int buttons_fasync (int fd, struct file *filp, int on)

{

printk("driver: buttons_fasync\n");

return fasync_helper (fd, filp, on, &button_async);

}

struct file_operations buttons_ops = {

.open = buttons_open,

.read = buttons_read,

.release = buttons_close,

.fasync = buttons_fasync,

};

int buttons_init(void){

int ret;

init_timer(&buttons_timer);

buttons_timer.function = buttons_timer_function;

//buttons_timer.expires = 0;

add_timer(&buttons_timer);

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);

gph3con = (volatile unsigned long *)ioremap(0xE0200C60, 16);

gph3dat = gph3con + 1;

*gph3con &= (~0x000000ff);

*gph3con |=0x11;

*gph3dat &= ~0x03;

printk("buttons init\n");

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){

printk("buttons exit\n");

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");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值