Firefly开源社区

firefly-rk3288实现的按键中断

416

积分

3

威望

0

贡献

技术达人

Rank: 2

积分
416
发表于 2017-6-9 15:19:03     
目前在学习驱动,之前在书上看了linux的中断,现在手边正好有个震动马达和按键,就用现成了材料写了个按键中断的驱动程序,还有部分疑惑,希望在和大家学习交流的过程中,能有人指出我的不足。
首先是我的设备树配置,如下图所示,可以看到的是我使用的是GPIO7 A3和GPIO0 B5,一个控制马达,一个控制按键
dts.PNG

按键原本接GND的我接的是VCC,因为我不会设置上拉(还是根本没有,这个希望有人能解答下,因为芯片手册不全,很苦恼)
驱动使用的是platform总先,通过of开头的函数可以获取到我们在设备树种定义的硬件信息
platform.PNG

probe.png

获取到GPIO后,我们就可以使用这个gpio号去申请中断了,申请的函数是request_irq(),申请中断后需要使能中断,就是单片机的mask
interrupt.png

参数1是中断号,参数2是中断处理函数,参数3是中断触发方式,参数4是名字,参数5是传给中断处理函数的参数,这个时候我们就可以在中断处理函数中执行我们的操作了,这个地方的中断处理只是中断顶半部,因为这只是个按键操作,没有必要用到中断底半部,如果有比较耗时的操作,还是建议放到中断底半部去。
回复

使用道具 举报

416

积分

3

威望

0

贡献

技术达人

Rank: 2

积分
416
发表于 2017-6-9 15:20:03     
本帖最后由 z3j6w9 于 2017-6-9 15:22 编辑
  1. #include <linux/kernel.h>
  2. #include <linux/init.h>
  3. #include <linux/module.h>
  4. #include <linux/delay.h>
  5. #include <linux/gpio.h>
  6. #include <linux/fs.h>
  7. #include <linux/cdev.h>
  8. #include <linux/slab.h>
  9. #include <linux/uaccess.h>
  10. #include <linux/interrupt.h>
  11. #include <asm/irq.h>

  12. #ifdef CONFIG_OF
  13. #include <linux/of.h>
  14. #include <linux/of_gpio.h>
  15. #include <linux/of_platform.h>
  16. #endif

  17. #define GPIO_LOW 0
  18. #define GPIO_HIGH 1

  19. static int gpio7_a3;
  20. static int gpio0_b5;
  21. static int global_major;
  22. static int irq;
  23. static struct class *motor_class;
  24. static struct device *motor_device;


  25. irqreturn_t motor_irq_handler(int irq, void *dev_id)
  26. {
  27.         int gpio_voltage = 0;
  28.         static int cnt = 0;
  29.         printk("%s \n", __FUNCTION__);
  30.         gpio_voltage = gpio_get_value(gpio0_b5);
  31.         if (gpio_voltage)
  32.         {
  33.                 cnt++;
  34.         }
  35.         else
  36.         {
  37.                 cnt = 0;
  38.         }
  39.         if (cnt == 8)
  40.         {
  41.                 gpio_set_value(gpio7_a3, GPIO_HIGH);
  42.                 mdelay(50);
  43.                 gpio_set_value(gpio7_a3, GPIO_LOW);
  44.                 cnt = 0;
  45.         }
  46.         return IRQ_HANDLED;
  47. }


  48. static int MOTOR_probe(struct platform_device *pdev)
  49. {
  50.         int ret = -1;
  51.         int  flag;
  52.         struct gpio_desc *gpio_desc = NULL;
  53.         struct device_node *motor_node = pdev->dev.of_node;

  54.         printk(KERN_INFO "motor-probe\n");
  55.         gpio7_a3 = of_get_named_gpio_flags(motor_node, "motor-out", 0, &flag);
  56.         if (!gpio_is_valid(gpio7_a3))
  57.         {
  58.                 printk("gpio7_a3 is invalid\n");
  59.         }

  60.         ret = gpio_request(gpio7_a3, "motor");
  61.         if (0 != ret)
  62.         {
  63.                 printk("free gpio7_a3\n");
  64.                 gpio_free(gpio7_a3);
  65.                 return -EIO;
  66.         }

  67.         gpio0_b5 = of_get_named_gpio(motor_node, "key-out", 0);
  68.         if (!gpio_is_valid(gpio0_b5))
  69.         {
  70.                 printk("gpio0_a7 is invalid.\n");
  71.         }

  72.         ret = gpio_request(gpio0_b5, "motor");
  73.         if (0 != ret)
  74.         {
  75.                 printk("free gpio0_b5\n");
  76.                 gpio_free(gpio0_b5);
  77.                 return -EIO;
  78.         }

  79.         gpio_direction_output(gpio7_a3, GPIO_LOW);
  80.         //gpio_direction_input(gpio0_b5);
  81.         irq = __gpio_to_irq(gpio0_b5);
  82.         if (ENXIO == irq)
  83.         {
  84.                 printk("Get irq failed. \n");
  85.                 return -EFAULT;
  86.         }
  87.         ret = request_irq(irq, motor_irq_handler, IRQF_TRIGGER_HIGH, "motor", &gpio0_b5);
  88.         if (ret)
  89.         {
  90.                 printk("Request irq failed.%s \n", __FUNCTION__);
  91.                 return -EFAULT;
  92.         }

  93.         enable_irq(irq);
  94.        
  95. #if 0

  96.         for (i=0; i < 10; ++i)
  97.         {
  98.                 gpio_set_value(gpio, GPIO_LOW);
  99.                 mdelay(5000);
  100.                 gpio_set_value(gpio, GPIO_HIGH);
  101.                 mdelay(5000);
  102.         }
  103. #endif

  104.         return 0;
  105. }

  106. static int MOTOR_remove(struct platform_device *pdev)
  107. {
  108.         free_irq(irq, &gpio0_b5);
  109.         return 0;
  110. }

  111. #ifdef CONFIG_OF
  112. static const struct of_device_id of_motor_match[] = {
  113.         {        .compatible = "vr, motor"},
  114.         {                                 },
  115. };
  116. #endif

  117. static struct platform_driver motor_driver = {
  118.         .probe = MOTOR_probe,
  119.         .remove = MOTOR_remove,
  120.         .driver = {
  121.                 .name = "motor",
  122.                 .owner = THIS_MODULE,
  123.                 .of_match_table = of_motor_match,
  124.         },
  125. };

  126. ssize_t motor_read(struct file *filep, char __user *buf, size_t size, loff_t *offset)
  127. {
  128.         int gpio_value = 0;
  129.         gpio_value = gpio_get_value(gpio0_b5);
  130.         (void)copy_to_user(buf,&gpio_value,1);
  131.         return 0;
  132. }

  133. ssize_t motor_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset)
  134. {
  135. #if 1
  136.         gpio_set_value(gpio7_a3, GPIO_HIGH);
  137.         mdelay(10);
  138.         gpio_set_value(gpio7_a3, GPIO_LOW);
  139. #endif
  140.         return 0;
  141. }

  142. int motor_open(struct inode *inode, struct file *filep)
  143. {
  144.         return 0;
  145. }

  146. int motor_release(struct inode *inode, struct file *filep)
  147. {
  148.         return 0;
  149. }

  150. static struct file_operations motor_fops = {
  151.         .owner =   THIS_MODULE,
  152.         .read  =   motor_read,
  153.         .write =   motor_write,
  154.         .open  =   motor_open,
  155.         .release = motor_release,
  156. };

  157. static int __init MOTOR_init(void)
  158. {
  159.         printk("motor driver init \n");

  160.         //int devno = MKDEV(global_major, 0);
  161.         //int ret = 0;
  162.         /*
  163.         if (global_major)
  164.         {
  165.                 ret = register_chrdev_region(devno, 1, "motor");
  166.         }
  167.         else
  168.         {
  169.                 ret = alloc_chrdev_region(&devno, 0, 1, "motor");
  170.         }
  171.         */

  172.         /*system will auto allocate major*/
  173.         global_major = register_chrdev(0, "motor", &motor_fops);

  174.         /*create class*/
  175.         motor_class = class_create(THIS_MODULE, "motordrv");

  176.         /*create device for app*/
  177.         motor_device = device_create(motor_class, NULL, MKDEV(global_major, 0),NULL,"motor");
  178.        

  179.         //if (ret < 0)
  180.         //        return ret;
  181.         platform_driver_register(&motor_driver);
  182.         return 0;
  183. }

  184. static void __exit MOTOR_exit(void)
  185. {
  186.         device_destroy(motor_class,MKDEV(global_major, 0));
  187.         class_destroy(motor_class);
  188.         //unregister_chrdev_region(MKDEV(global_major, 0), 1);
  189.         unregister_chrdev(global_major, "motor");
  190.         platform_driver_unregister(&motor_driver);
  191. }


  192. subsys_initcall(MOTOR_init);
  193. module_exit(MOTOR_exit);

  194. MODULE_LICENSE("GPL");
复制代码

回复

使用道具 举报

416

积分

3

威望

0

贡献

技术达人

Rank: 2

积分
416
发表于 2017-6-9 15:23:18     
不知道为啥不能上传.c文件,只好贴一下代码了,还好代码比较少。
回复

使用道具 举报

116

积分

0

威望

0

贡献

技术小白

积分
116
发表于 2017-6-23 11:18:58     
谢谢分享! 收藏了!
回复

使用道具 举报

11

积分

0

威望

0

贡献

技术小白

积分
11
发表于 2019-1-10 14:33:32     
楼主,我按照你所说的进行操作步骤,代码与你给的一样,在进行platform_driver_register后,遇到了如下问题:
[ 7243.851937] platform_driver_register success!
[ 7243.852583] rockchip_rt5631_audio_probe............................................
[ 7243.853074] rockchip-rt5631 rockchip-rt5631.31: ASoC: CODEC (null) not registered
[ 7243.853179] rockchip_rt5631_audio_probe() register card failed:-517
[ 7243.853392] platform rockchip-rt5631.31: Driver rockchip-rt5631 requests probe deferral
请问能帮忙解决一下吗?
回复

使用道具 举报

38

积分

0

威望

0

贡献

技术小白

积分
38
发表于 2019-10-7 11:21:32     
大佬写的简明易懂,学习了!
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 爱板网 电子发烧友论坛 云汉电子社区 粤ICP备14022046号-2
快速回复 返回顶部 返回列表