6410之中断处理编写代码(1)
来源:互联网 发布:mac eclipse真机调试 编辑:程序博客网 时间:2024/06/14 14:36
代码如下,在open中申请中断,在release中释放中断。
#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <asm/uaccess.h>#include <linux/device.h>#include <asm/io.h>#include <linux/interrupt.h>struct class *buttons_class;struct device *buttons_dev;volatile unsigned long *gpncon = NULL;volatile unsigned long *gpndat = NULL;static irqreturn_t button_irq_handle(int irq, void *devid){printk("irq = %d\n",irq);return IRQ_HANDLED;}static int buttons_drv_open(struct inode *inode, struct file *file){printk("buttons_drv_open \n");//配置按键gpio引脚为输入引脚//*gpncon &= ~0xfff;request_irq(IRQ_EINT(0),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD1", 1);request_irq(IRQ_EINT(1),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD2", 1);request_irq(IRQ_EINT(2),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD3", 1);request_irq(IRQ_EINT(3),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD4", 1);return 0;}static ssize_t buttons_drv_read( struct file *file, char __user *buffer, size_t len, loff_t *offset ){//printk("buttons_drv_read \n");char reg_val[6];if(len != sizeof(reg_val)){return -EINVAL;}int i;for(i = 0 ; i < 6 ; i++){reg_val[i] = (*gpndat & 1 << i ) ? 1 : 0;}copy_to_user(buffer,reg_val,sizeof(reg_val));return sizeof(reg_val);}int buttons_drv_release(struct inode *inode, struct file *file){free_irq(IRQ_EINT(0),1);free_irq(IRQ_EINT(1),1);free_irq(IRQ_EINT(2),1);free_irq(IRQ_EINT(3),1);return 0;}static struct file_operations buttons_fops = { .owner = THIS_MODULE, .open = buttons_drv_open, .read = buttons_drv_read, .release = buttons_drv_release,};int major;static int __init buttons_drv_init(void){printk("buttons_drv_init \n");major = register_chrdev(0,"buttons",&buttons_fops);buttons_class = class_create(THIS_MODULE,"buttons");buttons_dev = device_create(buttons_class,NULL,MKDEV(major,0),NULL,"buttons");gpncon = (volatile unsigned long *)ioremap(0x7F008830 ,16);gpndat = gpncon + 1;return 0;}static void __exit buttons_drv_exit(void){device_destroy(buttons_class,MKDEV(major,0));class_destroy(buttons_class);unregister_chrdev(major,"buttons");iounmap(gpncon);}module_init(buttons_drv_init);module_exit(buttons_drv_exit);MODULE_LICENSE("GPL");
编译后,
执行
/test # insmod buttons_drv_irq.ko
buttons_drv_init
/test # lsmod
buttons_drv_irq 1788 0 - Live 0xbf000000
/test # exec 5</dev/buttons
buttons_drv_open
其中的PAD1-PAD4就是申请的中断
关闭exec 5<&-
优化代码:
#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <asm/uaccess.h>#include <linux/device.h>#include <asm/io.h>#include <linux/interrupt.h>#include <mach/regs-gpio.h>#include <linux/gpio.h>struct class *buttons_class;struct device *buttons_dev;volatile unsigned long *gpncon = NULL;volatile unsigned long *gpndat = NULL;static unsigned char key_val;struct pin_desc{unsigned int pin;unsigned int key_val;};struct pin_desc pins_desc[4] = {{S3C64XX_GPN(0),0x01},{S3C64XX_GPN(1),0x02},{S3C64XX_GPN(2),0x03},{S3C64XX_GPN(3),0x04},};static irqreturn_t button_irq_handle(int irq, void *devid){printk("irq = %d\n",irq);struct pin_desc * pindesc = (struct pin_desc *)devid;unsigned int pinval;pinval = gpio_get_value(pindesc->pin);if (pinval){key_val = 0x80 | pindesc->key_val;printk("songkai\n");}else{key_val = pindesc->key_val;printk("anxia\n");}return IRQ_HANDLED;}static int buttons_drv_open(struct inode *inode, struct file *file){printk("buttons_drv_open \n");request_irq(IRQ_EINT(0),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD1", &pins_desc[0]);request_irq(IRQ_EINT(1),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD2", &pins_desc[1]);request_irq(IRQ_EINT(2),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD3", &pins_desc[2]);request_irq(IRQ_EINT(3),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD4", &pins_desc[3]);return 0;}static ssize_t buttons_drv_read( struct file *file, char __user *buffer, size_t len, loff_t *offset ){if (len != 1)return -EINVAL;copy_to_user(buffer, &key_val, 1);return 1;}int buttons_drv_release(struct inode *inode, struct file *file){free_irq(IRQ_EINT(0),&pins_desc[0]);free_irq(IRQ_EINT(1),&pins_desc[1]);free_irq(IRQ_EINT(2),&pins_desc[2]);free_irq(IRQ_EINT(3),&pins_desc[3]);return 0;}static struct file_operations buttons_fops = { .owner = THIS_MODULE, .open = buttons_drv_open, .read = buttons_drv_read, .release = buttons_drv_release,};int major;static int __init buttons_drv_init(void){printk("buttons_drv_init \n");major = register_chrdev(0,"buttons",&buttons_fops);buttons_class = class_create(THIS_MODULE,"buttons");buttons_dev = device_create(buttons_class,NULL,MKDEV(major,0),NULL,"buttons");return 0;}static void __exit buttons_drv_exit(void){device_destroy(buttons_class,MKDEV(major,0));class_destroy(buttons_class);unregister_chrdev(major,"buttons");}module_init(buttons_drv_init);module_exit(buttons_drv_exit);MODULE_LICENSE("GPL");
目前中断程序还没有完成,如果使用之前查询方式的测试程序,还会出现不断的读取键值的现象。这就需要引入休眠唤醒操作:
休眠的API为:
wait_event_interruptible(button_waitq, ev_press);
定义如下:
#define wait_event_interruptible(wq, condition) \
({ \
int __ret = 0;\
if (!(condition))\
__wait_event_interruptible(wq, condition, __ret);\ //当condition为0的时候,应用程序就进入休眠
__ret; \
})
唤醒的API为:
wake_up_interruptible(&button_waitq);
代码如下:
#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <asm/uaccess.h>#include <linux/device.h>#include <asm/io.h>#include <linux/interrupt.h>#include <mach/regs-gpio.h>#include <linux/gpio.h>struct class *buttons_class;struct device *buttons_dev;static DECLARE_WAIT_QUEUE_HEAD(button_waitq);//定义休眠队列static volatile int ev_press = 0; //初始值为0,处于休眠状态static unsigned char key_val;struct pin_desc{unsigned int pin;unsigned int key_val;};struct pin_desc pins_desc[4] = {{S3C64XX_GPN(0),0x01},{S3C64XX_GPN(1),0x02},{S3C64XX_GPN(2),0x03},{S3C64XX_GPN(3),0x04},};static irqreturn_t button_irq_handle(int irq, void *devid){printk("irq = %d\n",irq);struct pin_desc * pindesc = (struct pin_desc *)devid;unsigned int pinval;pinval = gpio_get_value(pindesc->pin);if (pinval){key_val = 0x80 | pindesc->key_val;printk("songkai\n");}else{key_val = pindesc->key_val;printk("anxia\n");}ev_press = 1; //唤醒 wake_up_interruptible(&button_waitq); return IRQ_HANDLED;}static int buttons_drv_open(struct inode *inode, struct file *file){printk("buttons_drv_open \n");request_irq(IRQ_EINT(0),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD1", &pins_desc[0]);request_irq(IRQ_EINT(1),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD2", &pins_desc[1]);request_irq(IRQ_EINT(2),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD3", &pins_desc[2]);request_irq(IRQ_EINT(3),button_irq_handle,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "PAD4", &pins_desc[3]);return 0;}static ssize_t buttons_drv_read( struct file *file, char __user *buffer, size_t len, loff_t *offset ){if (len != 1)return -EINVAL;wait_event_interruptible(button_waitq, ev_press);//进入睡眠copy_to_user(buffer, &key_val, 1);ev_press = 0;return 1;}int buttons_drv_release(struct inode *inode, struct file *file){free_irq(IRQ_EINT(0),&pins_desc[0]);free_irq(IRQ_EINT(1),&pins_desc[1]);free_irq(IRQ_EINT(2),&pins_desc[2]);free_irq(IRQ_EINT(3),&pins_desc[3]);return 0;}static struct file_operations buttons_fops = { .owner = THIS_MODULE, .open = buttons_drv_open, .read = buttons_drv_read, .release = buttons_drv_release,};int major;static int __init buttons_drv_init(void){printk("buttons_drv_init \n");major = register_chrdev(0,"buttons",&buttons_fops);buttons_class = class_create(THIS_MODULE,"buttons");buttons_dev = device_create(buttons_class,NULL,MKDEV(major,0),NULL,"buttons");return 0;}static void __exit buttons_drv_exit(void){device_destroy(buttons_class,MKDEV(major,0));class_destroy(buttons_class);unregister_chrdev(major,"buttons");}module_init(buttons_drv_init);module_exit(buttons_drv_exit);MODULE_LICENSE("GPL");
使用top发现该程序使用的资源很少:
- 6410之中断处理编写代码(1)
- 6410之中断处理
- 6410之中断处理
- 6410之异常中断处理
- 驱动编写之中断
- Linux中断处理驱动程序编写
- Linux中断处理驱动程序编写
- Linux中断处理驱动程序编写
- Linux中断处理驱动程序编写
- Linux中断处理驱动程序编写
- Linux中断处理驱动程序编写
- Linux中断处理驱动程序编写
- Linux中断处理驱动程序编写
- Linux中断处理驱动程序编写
- eCos学习笔记之中断处理代码分析
- 6410之linux中断处理结构
- 中断处理之RTC
- div溢出中断处理代码
- Java序列化问题总结
- nyoj-8-一种排序
- listview的分割线
- 手把手教你把Vim改装成一个IDE编程环境(图文)
- mysql_connect连接两次,释放两次,出现Warning: mysql_close(): 13 is not a valid MySQL-Link resource
- 6410之中断处理编写代码(1)
- CSS ------ float 属性
- GridView模仿Gallery
- 内存拷贝探究
- IronPython入门:什么是IronPython?
- yum配置
- CSS------ overflow 属性
- 游戏音乐音效添加管理
- 安卓JNI传结构体