赞
踩
先介绍个东西 ctags
这个工具可以像keil一样在工程里查找跳转,帮我们找到我们想要的东西。
安装教程可以找到,这里只讲怎么用。
在工程目录(包含所有你会用到的头文件等)下,先加载这个命令,可能要等待一会
然后在我们写代码过程中,比如下面
以按键中断为例
按键K1中断源为EINT8
与裸机不同,操作系统下,很多东西别人已经写好了
我们在用到中断时
直接CTRL + ] 就会帮你搜索跳转到所要查找的文件里。CRTL + O回跳。我们也可以通过这个方式找到头文件。
回到中断
在操作系统中,我们不需要用很多的寄存器去配置中断。我们只需要按步骤配置就行了
1.注册中断 request_irq
参数:
irq:中断号,就是我们上面第一张图所显示的,这里是K1的EINT8
handler:中断回调函数,懂的都懂
flags:中断行为、触发方式
下降沿触发
关闭其他中断(后面要用其他中断需要开启)
后面两个参数就是中断的名字和我们给回调函数传的参数,不在赘述。
回调函数
read函数
当我们调用read函数时,会进入wake_event阻塞。然后按键产生的中断会唤醒。
这里用的wake_even_interruptible而不用wake_event,如果是wake_event,在进入底层后,程序调度无法影响到它
用wake_even_interruptible这个卡死就可以被中断,也可以用wake_even_timeout,设置超时时间,当时间到了还在之前的地方就会被强制打断,上图红字所示 。
所以整个程序,中断前卡死在read那里,按一下按键就执行一次回调函数。
代码:
- #include <linux/init.h>
- #include <linux/kernel.h>
- #include <linux/types.h>
- #include <linux/fs.h>
- #include <linux/cdev.h>
- #include <linux/module.h>
- #include <linux/kdev_t.h>
- #include <asm/string.h>
- #include <asm/io.h>
- #include <linux/interrupt.h>
- #include <linux/irqreturn.h>
- #include <mach/irqs.h>
- #include <linux/wait.h>
- #include <linux/sched.h>
-
- #define MAJOR_NUM 247
- #define MINOR_NUM 0
- #define DEV_NAME "eint8_key"
- static wait_queue_head_t wq;
- static int condition = 0;
-
- irqreturn_t eint8_handler(int irq, void *arg)
- {
- condition = 1;
- wake_up_interruptible(&wq);
-
- printk("irq = %d arg = %d\n", irq, *(int *)arg);
- return IRQ_HANDLED;
- }
-
- static int open(struct inode *node, struct file *file)
- {
- printk("kernrl open \n");
- return 0;
- }
-
- static int read(struct file *file, char __user *buf, size_t len, loff_t *loff)
- {
- condition = 0;
- wait_event_interruptible(wq, condition);
- printk("kernrl read \n");
- return 0;
- }
-
-
- static int write(struct file *file, const char __user *buf, size_t len, loff_t *loff)
- {
- printk("kernrl write \n");
-
- return 0;
- }
-
- static int close(struct inode *node, struct file *file)
- {
- printk("kernrl close \n");
- return 0;
- }
-
- static dev_t dev_num;
- static struct file_operations fops =
- {
- .owner = THIS_MODULE,
- .open = open,
- .read = read,
- .write = write,
- .release = close
- };
- static struct cdev dev;
- static unsigned int args = 100;
-
- static int __init exit_key_init(void)
- {
- int ret = 0;
- dev_num = MKDEV(MAJOR_NUM, MINOR_NUM);
-
- ret = cdev_add(&dev, dev_num, 1);
- if(ret < 0)
- goto err_add_failed;
-
- cdev_init(&dev, &fops);
-
-
- ret = register_chrdev_region(dev_num, 1, DEV_NAME);
- if(ret < 0)
- goto err2_register_failed;
-
- ret = request_irq(IRQ_EINT8, eint8_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED, "exit_key", &args);
- if(ret < 0)
- goto err_request_irq_failed;
-
-
- printk("eint8_key_init /\n");
- return 0;
-
- err_add_failed:
- printk("cdev_add failed\n");
- cdev_del(&dev);
- return ret;
-
- err2_register_failed:
- printk("register_chrdev_region failed\n");
- unregister_chrdev_region(dev_num, 1);
- cdev_del(&dev);
- return ret;
-
- err_request_irq_failed:
- printk("err_request_irq failed\n");
- disable_irq(IRQ_EINT8);
- free_irq(IRQ_EINT8, &args);
- unregister_chrdev_region(dev_num, 1);
- cdev_del(&dev);
- return ret;
-
- }
-
- static void __exit key_exit(void)
- {
- disable_irq(IRQ_EINT8);
- free_irq(IRQ_EINT8, &args);
- unregister_chrdev_region(dev_num, 1);
- cdev_del(&dev);
- printk("led_exit ....\n");
- }
-
- module_init(exit_key_init);
- module_exit(key_exit);
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。