Linux编写一个Linux按键中断Demo

Posted ZHONGCAI0901

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux编写一个Linux按键中断Demo相关的知识,希望对你有一定的参考价值。

文章目录

1. 前言

在内核里面实现了按键驱动,drivers/input/keyboard/gpio_keys.c,我们可以参考它来学着写一个按键中断程序。

2. 硬件介绍

通过下面的硬件我们可以知道按键检测GPIO默认是高电平,如果按键被按下就变成低电平。所以,我们可以配置GPIO为中断模式,检测KEY是否被按下。

3. 编写按键驱动程序

  • 在设备树中添加按键使用的引脚,如下:
    imx_gpio_keys 
    	compatible = "imx,gpio_key";
    	gpios = <&gpio5 1 GPIO_ACTIVE_HIGH
    			 &gpio4 14 GPIO_ACTIVE_HIGH>;
    	
    	pinctrl-names = "default";
    	pinctrl-0 = <&pinctrl_gpio_key1
    				 &pinctrl_gpio_key2>;
    ;
    
  • 在probe函数中从设备树获取GPIO,并且从GPIO中获得中断号
    count = of_gpio_count(node);
    if(!count)
    	printk("[%s:%d] There isn't gpio available!\\n", __FUNCTION__, __LINE__);
    	return -1;
    
    
    pGpioKeyCfg = kzalloc(count * sizeof(struct gpio_key_cfg), GFP_KERNEL);
    
    for(i = 0; i < count; i++)
    
    	pGpioKeyCfg[i].gpio_num = of_get_gpio_flags(node, i, &flag);
    	if(pGpioKeyCfg[i].gpio_num < 0)
    		printk("[%s:%d] of_get_gpio_flags is fail!!!\\n", __FUNCTION__, __LINE__);
    		return -1;
    	
    
    	pGpioKeyCfg[i].gpio_flag = flag & OF_GPIO_ACTIVE_LOW; // 获取GPIO的flag
    	pGpioKeyCfg[i].gpiod = gpio_to_desc(pGpioKeyCfg[i].gpio_num); // 获取GPIO的描述符
    	pGpioKeyCfg[i].gpio_irq = gpio_to_irq(pGpioKeyCfg[i].gpio_num); // 获取GPIO的中断号
    
    
  • 申请中断和编写中断函数
    for(i = 0; i < count; i++)
    
    	request_irq(pGpioKeyCfg[i].gpio_irq, gpio_key_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "gpio_key", &pGpioKeyCfg[i]);
    
    
    static irqreturn_t gpio_key_isr(int irq, void *dev_id)
    
    	int val;
    	struct gpio_key_cfg *pGpioKey = dev_id;
    
    	val = gpiod_get_value(pGpioKey->gpiod);
    
    	printk("key %d %d\\n", pGpioKey->gpio_num, val);
    
    	return IRQ_HANDLED;
    
    

4. 配置设备树

IMX平台可以通过“i.MX Pins Tool v6”配置gpio,一般一个引脚作为中断时,要通过 PinCtrl 把它设置为 GPIO 功能。配置效果如下:

工具生成的代码,对应修改dtsi如下:

diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
index 6b70f287e..52c5bd0ee 100644
--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
@@ -326,7 +326,7 @@
 &qspi 
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_qspi>;
-	status = "okay";
+	status = "disabled";
 
 	flash0: n25q256a@0 
 		#address-cells = <1>;
@@ -748,4 +748,10 @@
 			MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY    0x30b0
 		>;
 	;
+	
+	pinctrl_gpio_key2: gpio_key2 
+		fsl,pins = <
+			MX6UL_PAD_NAND_CE1_B__GPIO4_IO14       0x000010B0
+		>;
+	;
 ;
diff --git a/arch/arm/boot/dts/imx6ull-14x14-evk.dts b/arch/arm/boot/dts/imx6ull-14x14-evk.dts
index bb8f91034..44818b470 100644
--- a/arch/arm/boot/dts/imx6ull-14x14-evk.dts
+++ b/arch/arm/boot/dts/imx6ull-14x14-evk.dts
@@ -10,8 +10,27 @@
 / 
 	model = "Freescale i.MX6 ULL 14x14 EVK Board";
 	compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
+	
+	imx_gpio_keys 
+		compatible = "imx,gpio_key";
+		gpios = <&gpio5 1 GPIO_ACTIVE_HIGH
+				 &gpio4 14 GPIO_ACTIVE_HIGH>;
+		
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_key1
+					 &pinctrl_gpio_key2>;
+	;
 ;
 
+&iomuxc_snvs 
+	pinctrl_gpio_key1: gpio_key1 
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01        0x000110A0
+		>;
+	;
+;
+
+
 &clks 
 	assigned-clocks = <&clks IMX6UL_CLK_PLL3_PFD2>,
 			  <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;

5. 烧录验证

编译烧录验证如下:

6. 工程代码下载地址

完整的实验工程Demo代码下载地址如下:
https://download.csdn.net/download/ZHONGCAI0901/22268720

以上是关于Linux编写一个Linux按键中断Demo的主要内容,如果未能解决你的问题,请参考以下文章

Linux 中断实验

S5PV210在Linux下如何编写驱动

linux 中断管理

给驱动添加sysfs设备模型(基于中断的按键程序)

在Linux下的中断方式读取按键驱动程序

中断按键驱动