ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

使用中断的按键处理程序,实现按键点灯的功能

2021-05-12 15:01:29  阅读:306  来源: 互联网

标签:__ 点灯 中断 irq platform 处理程序 gpiod 按键 gpio


基于exynos4412的开发板,编写了一个使用中断的按键程序,实现按键点灯的功能。

实现效果是按下按键灯亮,再按一次灯灭。

旨在学习中断的用法。

linux kernel version:4.4.38

 1 gpx3: gpx3 {
 2     gpio-controller;
 3     #gpio-cells = <2>;
 4 
 5     interrupt-controller;
 6     #interrupt-cells = <2>;
 7 };
 8 
 9 gpm4: gpm4 {
10     gpio-controller;
11     #gpio-cells = <2>;
12 
13     interrupt-controller;
14     #interrupt-cells = <2>;
15 };
16 
17 my_keys {
18     compatible = "interrupt-keys";
19 
20     interrupt-parent = <&gpx3>;
21     interrupts = <2 IRQ_TYPE_EDGE_FALLING>;    
22     key1-gpios = <&gpm4 0 GPIO_ACTIVE_LOW>;
23 };

mykeys是在DTS的根目录下创建的资源:描述使用的中断资源和led灯的gpio资源。

中断是GPX3的bit2,下降沿触发,led是GPM4的bit0

系统会自动将dts解析成platform device注册到内核,compatible用来和platform driver匹配。

接下来看原理图,可以看到和dts描述一致:

   

 

 

 

 

 

 


    static struct gpio_desc *gpiod;

1 static int mykey_probe(struct platform_device *pdev) 2 {
8 unsigned int irq; 9 int ret; 13 struct device_node* np = pdev->dev.of_node; 14 if(np == NULL) 15 { 16 printk(KERN_ALERT "%s %d of_node is NULL\n", __FUNCTION__, __LINE__); 17 return 0; 18 } 19    /*get irq num*/ 21 irq = platform_get_irq(pdev, 0); 22 printk(KERN_ALERT "%s %d irq = %d\n", __FUNCTION__, __LINE__, irq);
    /*register irq handler*/ 23 ret = devm_request_irq(&pdev->dev, irq, my_irq, 0, dev_name(&pdev->dev), NULL); 24 printk(KERN_ALERT "%s %d ret = %d\n", __FUNCTION__, __LINE__, ret); 25 26 gpiod = devm_gpiod_get_optional(&pdev->dev, "key1", GPIOD_OUT_HIGH); 27 if(gpiod == NULL){ 28 printk(KERN_ALERT "%s %d devm_gpiod_get_optional fail!!!\n", __FUNCTION__, __LINE__); 29 } 75 printk(KERN_ALERT "%s %d success===\n", __FUNCTION__, __LINE__); 76 return error; 77 }

21行:使用platform相关函数platform_get_irq,从platform device中获取irq num

23行:使用devm_request_irq注册中断,其中my_irq是中断处理函数,从原理图可知,按下按键产生下降沿,那么按下按键就会触发中断,执行中断处理函数my_irq

26行:gpiod是全局变量,旨在中断处理函数中操作它实现按键点灯灭灯功能。devm_gpiod_get_optional从platform device中获取信息,组成gpiod。第二个参数为dts中gpios的名字,第三个参数是将gpio设置为输出高电平(此处为逻辑高电平)

所以probe函数执行后,灯默认为亮的状态。

1 static irqreturn_t my_irq(int irqno, void *dev_id)
2 {
3     int level = gpiod_get_value(gpiod);
4     gpiod_set_value(gpiod, !level);
5     return IRQ_HANDLED;
6 }

中断处理函数中只做一件事,触发中断后改变led的亮灭状态。

这是我第一篇博客,程序也是demo级程序,如有错误还望指教~

 

标签:__,点灯,中断,irq,platform,处理程序,gpiod,按键,gpio
来源: https://www.cnblogs.com/ethandlwang/p/14759735.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有