• linux之按键中断


    查看原理图确认引脚

    可以看到按键有两个,分别对应GPIO5_1和GPIO4_14
    在这里插入图片描述

    配置pinctrl,配置成GPIO模式

    1.使用官方工具,配置下引脚
    在这里插入图片描述
    2.将生成的代码复制到设备树里
    在这里插入图片描述
    在这里插入图片描述

    创建设备节点

    在这里插入图片描述

    生成二进制设备树文件

    在工具链表下使用

    make dtbs
    在这里插入图片描述

    或者使用

    ./scripts/dtc/dtc -I dts -O dtb -o tmp.dtb arch/arm/boot/dts/xxx.dts
    // 编译 dts 为 dtb

    都可以生成二进制设备树文件

    #include 
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    
    struct gpio_key{
    	int gpio;
    	struct gpio_desc *gpiod;
    	int flag;
    	int irq;
    } ;
    
    static struct gpio_key *gpio_keys_100ask;
    
    static irqreturn_t gpio_key_isr(int irq, void *dev_id)
    {
    	struct gpio_key *gpio_key = dev_id;
    	int val;
    	val = gpiod_get_value(gpio_key->gpiod);
    	
    
    	printk("key %d %d\n", gpio_key->gpio, val);
    	
    	return IRQ_HANDLED;
    }
    
    /* 1. 从platform_device获得GPIO
     * 2. gpio=>irq
     * 3. request_irq
     */
    static int gpio_key_probe(struct platform_device *pdev)
    {
    	int err;
    	struct device_node *node = pdev->dev.of_node;
    	int count;
    	int i;
    	enum of_gpio_flags flag;
    	unsigned flags = GPIOF_IN;
    		
    	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    
    	count = of_gpio_count(node);
    	if (!count)
    	{
    		printk("%s %s line %d, there isn't any gpio available\n", __FILE__, __FUNCTION__, __LINE__);
    		return -1;
    	}
    
    	gpio_keys_100ask = kzalloc(sizeof(struct gpio_key) * count, GFP_KERNEL);
    	for (i = 0; i < count; i++)
    	{
    		gpio_keys_100ask[i].gpio = of_get_gpio_flags(node, i, &flag);
    		if (gpio_keys_100ask[i].gpio < 0)
    		{
    			printk("%s %s line %d, of_get_gpio_flags fail\n", __FILE__, __FUNCTION__, __LINE__);
    			return -1;
    		}
    		gpio_keys_100ask[i].gpiod = gpio_to_desc(gpio_keys_100ask[i].gpio);
    		gpio_keys_100ask[i].flag = flag & OF_GPIO_ACTIVE_LOW;
    
    		if (flag & OF_GPIO_ACTIVE_LOW)
    			flags |= GPIOF_ACTIVE_LOW;
    
    		err = devm_gpio_request_one(&pdev->dev, gpio_keys_100ask[i].gpio, flags, NULL);
    
    		
    		gpio_keys_100ask[i].irq  = gpio_to_irq(gpio_keys_100ask[i].gpio);
    	}
    
    	for (i = 0; i < count; i++)
    	{
    		err = request_irq(gpio_keys_100ask[i].irq, gpio_key_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "100ask_gpio_key", &gpio_keys_100ask[i]);
    	}
            
        return 0;
        
    }
    
    static int gpio_key_remove(struct platform_device *pdev)
    {
    	//int err;
    	struct device_node *node = pdev->dev.of_node;
    	int count;
    	int i;
    
    	count = of_gpio_count(node);
    	for (i = 0; i < count; i++)
    	{
    		free_irq(gpio_keys_100ask[i].irq, &gpio_keys_100ask[i]);
    	}
    	kfree(gpio_keys_100ask);
        return 0;
    }
    
    
    static const struct of_device_id ask100_keys[] = {
        { .compatible = "100ask,gpio_key" },
        { },
    };
    
    /* 1. 定义platform_driver */
    static struct platform_driver gpio_keys_driver = {
        .probe      = gpio_key_probe,
        .remove     = gpio_key_remove,
        .driver     = {
            .name   = "100ask_gpio_key",
            .of_match_table = ask100_keys,
        },
    };
    
    /* 2. 在入口函数注册platform_driver */
    static int __init gpio_key_init(void)
    {
        int err;
        
    	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    	
        err = platform_driver_register(&gpio_keys_driver); 
    	
    	return err;
    }
    
    /* 3. 有入口函数就应该有出口函数:卸载驱动程序时,就会去调用这个出口函数
     *     卸载platform_driver
     */
    static void __exit gpio_key_exit(void)
    {
    	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    
        platform_driver_unregister(&gpio_keys_driver);
    }
    
    
    /* 7. 其他完善:提供设备信息,自动创建设备节点                                     */
    
    module_init(gpio_key_init);
    module_exit(gpio_key_exit);
    
    MODULE_LICENSE("GPL");
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162

    板子上执行

    将生成的设备树文件放到板子上,放到/boot目录里,然后重启以下

    安装驱动程序

    然后执行echo “7 4 1 7” > /proc/sys/kernel/printk可以将printk函数输出的信息输出到终端。

    按下按键就可以看到打印结果。在这里插入图片描述

  • 相关阅读:
    L9110S电机驱动——让小车动起来
    2023华为OD机试真题-2023(A+B卷)【Java、C++、Go、Python】
    MFC使用友元函数访问窗体类成员变量
    干测试这些年,去过阿里也去过小公司,给年轻测试员们一个忠告...
    【.NET6+WPF】WPF使用prism框架+Unity IOC容器实现MVVM双向绑定和依赖注入
    【已解决】vue项目之爆红红红红······
    二分查找总结
    【雷达通信】非相干多视处理(CSA)(Matlab代码实现)
    hack the box:RouterSpace题解
    keycloak~对接login-status-iframe页面判断用户状态变更
  • 原文地址:https://blog.csdn.net/m0_57678852/article/details/134223944