1. 简介
在前面的实验我们都是使用的 GPIO 输出功能,还没有用过 GPIO 输入功能,本实验我们就来学习一下如果在 Linux 下编写 GPIO 输入驱动程序。 I.MX6U-ALPHA 开发板上有一个按键,我们就使用此按键来完成 GPIO 输入驱动程序,同时利用原子操作来对按键值进行保护。
2. 实验原理
按键驱动和 LED 驱动原理上来讲基本都是一样的,都是操作 GPIO,只不过一个是读取GPIO 的高低电平,一个是从 GPIO 输出高低电平。本实验我们实现按键输入,在驱动程序中使用一个整形变量来表示按键值,应用程序通过 read 函数来读取按键值,判断按键有没有按下。在
这里,这个保存按键值的变量就是个共享资源,驱动程序要向其写入按键值,应用程序要读取按键值。所以我们要对其进行保护,对于整形变量而言我们首选的就是原子操作,使用原子操作对变量进行赋值以及读取。 Linux 下的按键驱动原理很简单,接下来开始编写驱动。
注意,本例程只是为了演示 Linux 下 GPIO 输入驱动的编写,实际中的按键驱动并不会采用本实验中所讲解的方法, Linux 下的 input 子系统专门用于输入设备!
2.1 硬件原理
按键就两个状态:按下或弹起,将按键连接到一个 IO 上,通过读取这个 IO 的值就知道按键是按下的还是弹起的。至于按键按下的时候是高电平还是低电平要根据实际电路来判断。当 GPIO 连接按键的时候就要做为输入使用,主要工作就是配置按键所连接的 IO 为输入功能,然后读取这个 IO 的值来判断按键是否按下。
从图可以看出,按键 KEY0 是连接到 I.MX6U 的 UART1_CTS 这个 IO 上的, KEY0接了一个 10K 的上拉电阻,因此 KEY0 没有按下的时候 UART1_CTS 应该是高电平,当 KEY0按下以后 UART1_CTS 就是低电平。
3. 实验程序
实验步骤如下:·
- 1.添加 pinctrl 节点
I.MX6U-ALPHA 开发板上的 KEY 使用了 UART1_CTS_B 这个 PIN,打开 imx6ull-alientekemmc.dts,在 iomuxc 节点的 imx6ul-evk 子节点下创建一个名为“pinctrl_key”的子节点,节点内容如下所示:
第 3 行,将 GPIO_IO18 这个 PIN 复用为 GPIO1_IO18。
- 2.添加 KEY 设备节点
在根节点“/”下创建 KEY 节点,节点名为“key”,节点内容如下:
第 6 行, pinctrl-0 属性设置 KEY 所使用的 PIN 对应的 pinctrl 节点。
第 7 行, key-gpio 属性指定了 KEY 所使用的 GPIO。
- 3.检查 PIN 是否被其他外设使用
在实验中key使用的 PIN 为 UART1_CTS_B,因此先检查 PIN 为 UART1_CTS_B 这个 PIN 有没有被其他的 pinctrl 节点使用,如果有使用的话就要屏蔽掉,然后再检查 GPIO1_IO18这个 GPIO 有没有被其他外设使用,如果有的话也要屏蔽掉。
设备树编写完成以后使用“ make dtbs”命令重新编译设备树,然后使用新编译出来的imx6ull-alientek-emmc.dtb 文件启动 Linux 系统。启动成功以后进入“/proc/device-tree”目录中查看“key”节点是否存在,如果存在的话就说明设备树基本修改成功(具体还要驱动验证).
- 4.实验驱动编写
评论