当前位置:   article > 正文

arm内核驱动-中断

arm内核驱动-中断

先介绍个东西   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那里,按一下按键就执行一次回调函数。

代码:

  1. #include <linux/init.h>
  2. #include <linux/kernel.h>
  3. #include <linux/types.h>
  4. #include <linux/fs.h>
  5. #include <linux/cdev.h>
  6. #include <linux/module.h>
  7. #include <linux/kdev_t.h>
  8. #include <asm/string.h>
  9. #include <asm/io.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/irqreturn.h>
  12. #include <mach/irqs.h>
  13. #include <linux/wait.h>
  14. #include <linux/sched.h>
  15. #define MAJOR_NUM 247
  16. #define MINOR_NUM 0
  17. #define DEV_NAME "eint8_key"
  18. static wait_queue_head_t wq;
  19. static int condition = 0;
  20. irqreturn_t eint8_handler(int irq, void *arg)
  21. {
  22. condition = 1;
  23. wake_up_interruptible(&wq);
  24. printk("irq = %d arg = %d\n", irq, *(int *)arg);
  25. return IRQ_HANDLED;
  26. }
  27. static int open(struct inode *node, struct file *file)
  28. {
  29. printk("kernrl open \n");
  30. return 0;
  31. }
  32. static int read(struct file *file, char __user *buf, size_t len, loff_t *loff)
  33. {
  34. condition = 0;
  35. wait_event_interruptible(wq, condition);
  36. printk("kernrl read \n");
  37. return 0;
  38. }
  39. static int write(struct file *file, const char __user *buf, size_t len, loff_t *loff)
  40. {
  41. printk("kernrl write \n");
  42. return 0;
  43. }
  44. static int close(struct inode *node, struct file *file)
  45. {
  46. printk("kernrl close \n");
  47. return 0;
  48. }
  49. static dev_t dev_num;
  50. static struct file_operations fops =
  51. {
  52. .owner = THIS_MODULE,
  53. .open = open,
  54. .read = read,
  55. .write = write,
  56. .release = close
  57. };
  58. static struct cdev dev;
  59. static unsigned int args = 100;
  60. static int __init exit_key_init(void)
  61. {
  62. int ret = 0;
  63. dev_num = MKDEV(MAJOR_NUM, MINOR_NUM);
  64. ret = cdev_add(&dev, dev_num, 1);
  65. if(ret < 0)
  66. goto err_add_failed;
  67. cdev_init(&dev, &fops);
  68. ret = register_chrdev_region(dev_num, 1, DEV_NAME);
  69. if(ret < 0)
  70. goto err2_register_failed;
  71. ret = request_irq(IRQ_EINT8, eint8_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED, "exit_key", &args);
  72. if(ret < 0)
  73. goto err_request_irq_failed;
  74. printk("eint8_key_init /\n");
  75. return 0;
  76. err_add_failed:
  77. printk("cdev_add failed\n");
  78. cdev_del(&dev);
  79. return ret;
  80. err2_register_failed:
  81. printk("register_chrdev_region failed\n");
  82. unregister_chrdev_region(dev_num, 1);
  83. cdev_del(&dev);
  84. return ret;
  85. err_request_irq_failed:
  86. printk("err_request_irq failed\n");
  87. disable_irq(IRQ_EINT8);
  88. free_irq(IRQ_EINT8, &args);
  89. unregister_chrdev_region(dev_num, 1);
  90. cdev_del(&dev);
  91. return ret;
  92. }
  93. static void __exit key_exit(void)
  94. {
  95. disable_irq(IRQ_EINT8);
  96. free_irq(IRQ_EINT8, &args);
  97. unregister_chrdev_region(dev_num, 1);
  98. cdev_del(&dev);
  99. printk("led_exit ....\n");
  100. }
  101. module_init(exit_key_init);
  102. module_exit(key_exit);

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/431496
推荐阅读
相关标签
  

闽ICP备14008679号