自学内容网 自学内容网

树莓派3B+驱动开发(6)- 中断实验

github主页:https://github.com/snqx-lqh
本项目github地址:https://github.com/snqx-lqh/RaspberryPiDriver
本项目硬件地址:https://oshwhub.com/from_zero/shu-mei-pai-kuo-zhan-ban
欢迎交流

笔记说明

用按键来测试GPIO中断相关的实验,使用gpio子系统控制电平,使用gpiod的api。

主要参考的文章

正点原子《I.MX6U 嵌入式 Linux 驱动开发指南 V1.81》

韦东山《01_嵌入式Linux应用开发完全手册V5.1_IMX6ULL_Pro开发板》

本节源码路径02_Firmware/07_key_drv_irq

设备树

中断设备,主要配置按键相关,然后配置的gpio主要需要说明的就是加了interrupt-parent和interrupts,interrupts分别需要填写的就是中断的引脚,和中断的方式,2,是下降沿中断。可以使用,的方式多加几个引脚。这里为了减少篇幅,只是添加了按键相关的,完整的看项目源代码。

// Definitions for gpio-key module
/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2835";

    fragment@0{
        target-path = "/";
        __overlay__ {
            shb_key: shb_key@0{
                compatible = "shb-key";
                pinctrl-names = "default";
                pinctrl-0  = <&shb_key_pins>;
                status = "okay";

                key1-gpios = <&gpio 26 0>;
                key2-gpios = <&gpio 21 0>;
                key3-gpios = <&gpio 20 0>;

                interrupt-parent = <&gpio>;
                interrupts = <26 2>,<21 2>,<20 2>;
            };
        };
    };

    fragment@1 {
        // Configure the gpio pin controller
        target = <&gpio>;
        __overlay__ {
            shb_key_pins: shb_key_pins@0 {
                brcm,pins = <26 21 20>; // gpio number
                brcm,function = <0 0 0>; // 0 = input, 1 = output
                brcm,pull = <2 2 2>; // 0 = none, 1 = pull down, 2 = pull up
            };
        };
    };
};

驱动编写

为了方便,关于按键这一节的代码,我全部都是使用的misc设备,方便注册。

比较核心的代码就是中断的注册和中断服务函数的编写,如下:

先获取中断引脚,然后转到中断设备号,再注册中断。

中断服务函数可以传入参数。在释放的时候需要释放中断号。

typedef struct{
    int key_num;
    struct gpio_desc *key_gpiod;
    int key_irq;
}key_gpio_t;

typedef struct{
    dev_t devid;              /* 设备号 */
    struct cdev cdev;         /* cdev */
    struct device_node *node; /* KEY 设备节点 */
    key_gpio_t key_gpio[3];
}key_dev_t;

static key_dev_t key_dev;

static irqreturn_t gpio_key_isr(int irq, void *dev_id)
{
    key_gpio_t *gpio_key = dev_id;
    int val;

    val = gpiod_get_value(gpio_key->key_gpiod);
    printk("key %d %d\n", gpio_key->key_num, val);  

    return IRQ_RETVAL(IRQ_HANDLED);
}

static int key_probe(struct platform_device *dev)
{  
    int ret;
    //读节点信息
    key_dev.key_gpio[0].key_gpiod = gpiod_get(&dev->dev, "key1", 0);
    key_dev.key_gpio[1].key_gpiod = gpiod_get(&dev->dev, "key2", 0);
    key_dev.key_gpio[2].key_gpiod = gpiod_get(&dev->dev, "key3", 0);

    key_dev.key_gpio[0].key_num = 1;
    key_dev.key_gpio[1].key_num = 2;
    key_dev.key_gpio[2].key_num = 3;

    /* 初始化key相关 */
    ret = gpiod_direction_input(key_dev.key_gpio[0].key_gpiod);
    ret = gpiod_direction_input(key_dev.key_gpio[1].key_gpiod);
    ret = gpiod_direction_input(key_dev.key_gpio[2].key_gpiod);
    
    key_dev.key_gpio[0].key_irq = gpiod_to_irq(key_dev.key_gpio[0].key_gpiod);
    key_dev.key_gpio[1].key_irq = gpiod_to_irq(key_dev.key_gpio[1].key_gpiod);
    key_dev.key_gpio[2].key_irq = gpiod_to_irq(key_dev.key_gpio[2].key_gpiod);

    //注册gpio中断
    ret = request_irq(key_dev.key_gpio[0].key_irq, gpio_key_isr, IRQF_TRIGGER_FALLING, "shb_gpio_key_0", &key_dev.key_gpio[0]);
    ret = request_irq(key_dev.key_gpio[1].key_irq, gpio_key_isr, IRQF_TRIGGER_FALLING, "shb_gpio_key_1", &key_dev.key_gpio[1]);
    ret = request_irq(key_dev.key_gpio[2].key_irq, gpio_key_isr, IRQF_TRIGGER_FALLING, "shb_gpio_key_2", &key_dev.key_gpio[2]);

    /* 注册misc字符设备驱动 */
    ret = misc_register(&key_miscdev);

    if(ret < 0){
        printk("misc device register faikey!\r\n");
        return -EFAULT;
    }
    return 0;
}

static int key_remove(struct platform_device *dev)
{
    gpiod_put(key_dev.key_gpio[0].key_gpiod);
    gpiod_put(key_dev.key_gpio[1].key_gpiod);
    gpiod_put(key_dev.key_gpio[2].key_gpiod);

    for (int i = 0; i < 3; i++)
    {
        free_irq(key_dev.key_gpio[i].key_irq, &key_dev.key_gpio[i]);
    }

    /* 注销misc设备 */
    misc_deregister(&key_miscdev);
    return 0;
}

原文地址:https://blog.csdn.net/wan1234512/article/details/144305058

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!