目录
Linux下按键驱动原理
按键驱动和LED驱动原理上来讲基本都是一样的,都是操作GPIO,只不过一个是读取GPIO 的高低电平,一个是从GPIO输出高低电平。实现按键输入,在驱动程序中使用一个整形变量来表示按键值,应用程序通过read函数来读取按键值,判断按键有没有按下。在这里,这个保存按键值的变量就是个共享资源,驱动程序要向其写入按键值,应用程序要读取按键值。所以我们要对其进行保护,对于整形变量而言我们首选的就是原子操作,使用原子操作对变量进行赋值以及读取。Linux下的按键驱动原理很简单,接下来开始编写驱动。
修改设备树文件
添加pinctrl节点
第3行,将GPIO_IO18这个PIN复用为GPIO1_IO18。
添加KEY设备节点
在根节点“/”下创建KEY节点,节点名为“key”,节点内容如下:
第6行, pinctrl-0属性设置KEY所使用的PIN对应的pinctrl节点。
第7行, key-gpio属性指定了KEY所使用的GPIO。
按键驱动程序编写
第36-46行,结构体key_dev为按键的设备结构体,第45行的原子变量keyvalue用于记录按键值。
第56-74行,函数keyio_init用于初始化按键,从设备树中获取按键的gpio信息,然后设置为输入。将按键的初始化代码提取出来,将其作为独立的一个函数有利于提高程序的模块化设计。
第83-94行, key_open函数通过调用keyio_init函数来始化按键所使用的IO,应用程序每次打开按键驱动文件的时候都会初始化一次按键IO。
第104-120行, keyread函数,应用程序通过read函数读取按键值的时候此函数就会执行。
第110行读取按键IO的电平,如果为0 的话就表示按键按下了,如果按键按下的话
第111行就等待按键释放。按键释放以后标记按键值为KEYOVALUE。
第135-171行,驱动入口函数,
第138行调用atomic_set 函数初始化原子变量默认为无效值。
第178-187行,驱动出口函数。
key.c文件代码很简单,重点就是key_read函数读取按键值,要对keyvalue进行保护。
编写测试APP
第51~56行,循环读取/dev/key文件,也就是循环读取按键值,并且将按键值打印出来。
运行测试
按下开发板上的KEY0按键,keyApp就会获取并且输出按键信息,如图所示:
从图可以看出,当我们按下KEY0以后就会打印出"KEYO Press, value=0XF0",表示按键按下。但是大家可能会发现,有时候按下一次KEYO但是会输出好几行"KEYO Press,value =0XF0",这是因为我们的代码没有做按键消抖处理。