抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

1.引脚控制

最古老也是最普世的引脚控制方法:操作引脚寄存器

1.1 pinctrl子系统

  • 配置引脚功能用于UART、SPI、I2C、GPIO等
  • 提供接口配置中断
  • 使用设备树定义

举例&iomux下有子节点

pinctrl_keys: keysgrp {
    fsl,pins = <
        MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x80000000
        MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x80000000 
        MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x80000000    
    >;
};

pin controller没有统一的格式,在i.MX6ULL中应作如上形式配置。此节点记录了将哪个引脚复用为何种功能并做什么配置,即“引脚-功能-配置”的对应。

引用pin controller结点的结点称为client device,例如根节点下方可以有如下子节点

gpio-keys {
    compatible = "gpio-keys";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_keys>; 
    #address-cells = <1>; 
    #size-cells = <0>; 
    autorepeat; 

其中pinctrl-name只有一个值,表示这个设备只有一种状态,即default,对应pinctrl-0,其引用了pinctrl_keys结点。即当设备处于此状态时,引脚将被复用为彼功能。
问题:驱动如何选择状态?

1.2 GPIO子系统

提供API操作GPIO引脚如

gpio_request():请求一个GPIO引脚并进行相关的配置,使其可用于驱动程序的操作;
gpio_free():释放之前请求的GPIO引脚,将其解除分配并释放资源;
gpio_direction_input():将指定的GPIO引脚配置为输入模式;
gpio_direction_output():将指定的GPIO引脚配置为输出模式;
gpio_get_value():获取指定GPIO引脚的当前输入值;
gpio_set_value():设置指定GPIO引脚的输出值;
gpio_cansleep():检查指定的GPIO引脚是否支持睡眠(sleep)操作;
gpio_to_desc():根据GPIO引脚的编号获取对应的GPIO描述符;

这些函数通常定义在<linxu/gpio.h>头文件中,使用时需要包含该头文件。编写驱动时会使用这些函数。

2.LED驱动适配

2.1 修改设备树

打开arch/arm/boot/dts/imx6ul-pinfunc.h找到需要引脚宏定义。

gedit arch/arm/boot/dts/imx6ul-pinfunc.h

imx6ul-pinfunc.h存放imx6ul和imx6ull通用内容,引脚复用通过&iomuxc结点修改
imx6ull-pinfunc-snvs.h存放imx6ull独有内容,引脚复用通过&iomuxc_snvs结点修改

搜索欲要复用的引脚,有

#define MX6UL_PAD_JTAG_MOD__GPIO1_IO10          0x0044 0x02D0 0x0000 0x5 0x0
#define MX6UL_PAD_UART1_CTS_B__GPIO1_IO18       0x008C 0x0318 0x0000 0x5 0x0
#define MX6UL_PAD_GPIO1_IO00__GPIO1_IO00        0x005C 0x02E8 0x0000 0x5 0x0

打开设备树文件

gedit arch/arm/boot/dts/imx6ull-elf1-emmc.dts

在&iomuxc 节点下添 加子节点pinctrl_leds0

pinctrl_leds0:leds0grp { 
    fsl,pins = <
        MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x10b0
        MX6UL_PAD_JTAG_MOD__GPIO1_IO10 0x10b0
        MX6UL_PAD_GPIO1_IO00__GPIO1_IO00 0x10b0
        >;
};

在根节点下方添加leds子节点

leds {
    compatible = "gpio-leds";      //驱动匹配
    pinctrl-names = "default";     //pinctrl名字
    pinctrl-0 = <&pinctrl_leds0 >; //对IOMUX配置进行引用
    status = "okay";               //设备可用
    led1{
        lable = "led1"; //可有可无
        gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; //指定并配置引脚 ACTIVE_LOW:低电平点亮
        default-state = "off";               //默认状态
    };
    led2{
        lable = "led2";
        gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
        default-state = "on";
    };
    led3{
        lable = "led3";
        gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
        default-state = "on";
    };

2.2 编译驱动进内核

编译配置文件后使用make menuconfig命令

make imx6ull_elf1_defconfig
make menuconfig

搜索LEDS_GPIO,若有[=y]则表示该驱动已被选择编译进内核。编译内核与设备树。

./build.sh

拷贝内核与设备树

scp arch/arm/boot/zImage root@\192.168.0.232:/run/media/mmcblk1p1/
scp arch/arm/boot/dts/imx6ull-elf1\-emmc.dtb root@192.168.0.232:/run/media/mmcblk1p1/

开发板输入指令

sync
reboot

2.3 测试

测试指令

echo 1 > /sys/class/leds/led1/brightness
echo 0 > /sys/class/leds/led1/brightness
echo heartbeat > /sys/class/leds/led1/trigger
echo none > /sys/class/leds/led1/trigger

作用依次为:LED1亮、LED1灭、LED1心跳闪烁、关闭LED1触发器

3.按键驱动适配

使用Linux系统中集成的gpio-key驱动

开发板按键资源
key1->GPIO5_4(22脚)
key2->GPIO5_2(34脚)
key3->GPIO5_9(43脚)
平时为高电平,触发后为低电平

3.1 修改设备结点

复用按键引脚为GPIO功能
宏定义位于arch/arm/boot/dts/imx6ull-pinfunc-snvs.h
在设备树文件arch/arm/boot/dts/imx6ull-elf1-emmc.dts中的&iomux_snvs结点下添加子节点pinctrl_keys

pinctrl_keys: keysgrp {
    fsl,pins = <
        MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x80000000
        MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x80000000 
        MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x80000000    
    >;
};

在根节点下方添加设备结点

gpio-keys {
    compatible = "gpio-keys";
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_keys>; 
    #address-cells = <1>; 
    #size-cells = <0>; 
    autorepeat; 
    
    key1 { 
        label = "KEY1"; 
        linux,code = <KEY_ENTER>; 
        gpios = <&gpio5 4 GPIO_ACTIVE_LOW>; 
    }; 
    
    key2 { 
        label = "KEY2"; 
        linux,code= <KEY_UP>; 
        gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
    };
    
    key3 { 
        label = "KEY3";
        linux,code = <KEY_DOWN>; 
        gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; 
    }; 
};

gpios属性值指定了具体的GPIO引脚以及引脚的极性配置

在include/dt-bindings/input/input.h可查看按键定义的键值

d#efine KEY_ENTER 28
#define KEY_UP 103
#define KEY_DOWN 108

3.2 编译驱动

检查驱动是否编辑进内核

make menuconfig

驱动路径:Device Drivers->Input device support->Keyboards

为减少编译时间,可用“#”注释build.sh文件中的make distclean

编译并拷贝内核及设备树

./build.sh
scp arch/arm/boot/zImage root@\192.168.0.232:/run/media/mmcblk1p1/
scp arch/arm/boot/dts/imx6ull-elf1\-emmc.dtb root@192.168.0.232:/run/media/mmcblk1p1/

重启开发板

sync
reboot

3.3 测试

查看key所对应事,输入事件测试指定并选择对应事件。

cat /proc/bus/input/devices
evtest

评论