使用device-tree (DT) overlay应该是更方便的方法:

http://blog.gegg.us/2017/01/setting-up-a-gpio-button-keyboard-on-a-raspberry-pi/

Back in late 2013, when I wrote the first Version of a raspberry-pi based software controlling a HD44780 based 4×20 characters LCD and 4 input buttons I started querying the buttons using the generic GPIO driver included in Raspbian and its sysfs interface.

However, this has a couple of drawbacks. First of all it is hardly portable to other Linux based hardware and one has to do a lot of stuff like debouncing on the application level.

Fast forward to early 2017. Raspbian now uses a device-tree based approach for system setup and a driver called gpio-keys is readily available in its standard kernel.

However, as it is often the case in the Free Software world, the documentation of this driver is limited to some README files included in the Linux kernel and some discussions scattered all around the web.

Linux already has drivers for almost all of the common low level peripheral interfaces like I2C, SPI, OneWire, hardware PWM and generic GPIO. It is usually the better approach to use them instead of constantly re-inventing the wheel.

So here is my quick guide for setting up a “keyboard” made up from a couple of buttons connected via GPIO ports as shown in the image.

While this has currently only been tested on Raspberry Pi, it will likely also work on other Linux based boards with device tree enabled (e.g Beaglebone and others).

Keyboards in modern Linux Kernels are presented to userland as a so called input event device. To inspect them I would recommend the installation of the evtest and input-utils packages on Debian/Ubuntu based distributions. The lsinput command (run as root) shows which ones are available on a system.

So, what do we need to do to make a keyboard from our GPIO connected push-buttons?

The missing link between the gpio-keys driver and the setup of the actual GPIO ports, where the buttons are connected to, is a so called device-tree (DT) overlay.

While DT itself is a data structure for describing hardware, a DT overlay is something a user can put in place to change such a hardware description in a way which matches the actual application scenario (like buttons, buses etc. connected to the device).

So let’s build such an overlay for the four buttons shown in our schematic above.

The Documentation available at raspberrypi.org provides some clues about device tree overlays as well.

Here is the final result which works, so let’s go into the details:

/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; fragment@0 {
target-path = "/";
__overlay__ {
keypad: breadboard_keys {
compatible = "gpio-keys";
#address-cells = <1>;
#size-cells = <0>;
autorepeat;
button@22 {
label = "breadboard Menu";
linux,code = <28>;
gpios = <&gpio 22 1>;
};
button@10 {
label = "breadboard down";
linux,code = <108>;
gpios = <&gpio 10 1>;
};
button@9 {
label = "breadboard up";
linux,code = <103>;
gpios = <&gpio 9 1>;
};
button@11 {
label = "breadboard enter";
linux,code = <14>;
gpios = <&gpio 11 1>;
};
};
};
};
};

Our overlay fragment contains a keypad called breadboard_keys. This is actually the string which lsinput will show as the actual name of our input device. 22, 10, 9 and 11 are the GPIO port numbers corresponding to the green wires in our schematic.

The file gpio-keys.txt from the Linux Kernel source-tree will show us what our four button definitions need to look like. We need a label, which is arbitrary text, a linux,code which is actually a keycode as defined in /usr/include/linux/input-event-codes.h and we need a gpio definition with two options, the number of the GPIO to use and a boolean value indicating if the button is active low (1, as in our case) or active high (0).

Another thing I would like to point at is the autorepeat keyword. If given this will activate a key-press repeat behavior known from ordinary keyboards. The production of key-press-events will be repeated as long as the button is pressed.

Now how to enable this overlay on Raspberry Pi?

Very simple, once you know how ��

First put the above code in a file e.g. breadboard.dts.

Then compile a binary version and put it into the right place:

dtc -I dts -O dtb -o /boot/overlays/breadboard.dtbo breadboard.dts

Finally the following line must be added to /boot/config.txt:

dtoverlay=breadboard

Now we are done.

Here is how this looks like on the software side without any other input devices like keyboards connected:

root@raspberrypi:~# lsinput
/dev/input/event0
bustype : BUS_HOST
vendor : 0x1
product : 0x1
version : 256
name : "breadboard_keys"
phys : "gpio-keys/input0"
bits ev : EV_SYN EV_KEY EV_REP root@raspberrypi:~# input-events 0
/dev/input/event0
bustype : BUS_HOST
vendor : 0x1
product : 0x1
version : 256
name : "breadboard_keys"
phys : "gpio-keys/input0"
bits ev : EV_SYN EV_KEY EV_REP waiting for events
20:00:23.629190: EV_KEY KEY_BACKSPACE (0xe) pressed
20:00:23.629190: EV_SYN code=0 value=0
20:00:23.749163: EV_KEY KEY_BACKSPACE (0xe) released
20:00:23.749163: EV_SYN code=0 value=0
20:00:23.969176: EV_KEY KEY_DOWN (0x6c) pressed
20:00:23.969176: EV_SYN code=0 value=0
20:00:24.099151: EV_KEY KEY_DOWN (0x6c) released
20:00:24.099151: EV_SYN code=0 value=0
20:00:24.329158: EV_KEY KEY_UP (0x67) pressed
20:00:24.329158: EV_SYN code=0 value=0
20:00:24.439154: EV_KEY KEY_UP (0x67) released
20:00:24.439154: EV_SYN code=0 value=0
20:00:24.669157: EV_KEY KEY_ENTER (0x1c) pressed
20:00:24.669157: EV_SYN code=0 value=0
20:00:24.759176: EV_KEY KEY_ENTER (0x1c) released
20:00:24.759176: EV_SYN code=0 value=0
root@raspberrypi:~# grep breadboard /sys/kernel/debug/gpio
gpio-9 ( |breadboard up ) in hi
gpio-10 ( |breadboard down ) in hi
gpio-11 ( |breadboard enter ) in hi
gpio-22 ( |breadboard Menu ) in hi

Finally something which is not strictly on-topic concerning this post. There is something one should know about keyboard like input event devices like this. Pressing a button will send events to all applications normally consuming them (e.g. applications running on Linux console or X-Window system).

This might be an unwanted behavior. If so, your application software needs to issue a EVIOCGRAB ioctl after opening the input device.

more references:

https://github.com/fivdi/gpio-button

树莓派 -- 输入设备驱动 (key) 续2: 转载 Setting up a GPIO-Button “keyboard” on a Raspberry Pi的更多相关文章

  1. 树莓派 -- 输入设备驱动 (key) 续1

    测试 安装 input-utils pi@raspberrypi:~ $ sudo apt-get install input-utils Reading package lists... Done ...

  2. 树莓派 -- 输入设备驱动 (key)

    输入设备(如按键,键盘,触摸屏等)是典型的字符设备,其一般工作原理是底层在按键或触摸等动作发生时产生一个中断,然后CPU通过SPI,I2C总线读取键值. 在这些工作中之后中断和读键值是与设备相关的,而 ...

  3. linux 输入设备驱动

    <输入子系统简介> a:背景 内核的输入子系统是对“分散的”,“多种不同类别”的输入设备(键盘,鼠标,跟踪杆,触摸屏,加速度计等)进行“统一处理”的驱动程序.具有如下特点: a-1:统一各 ...

  4. 【树莓派】【转载】Raspberry Pi (树莓派)折腾记

    在网上看到一篇对树莓派折腾记录比较详细的文章,时间比较早,但是有些东西没变. 对于新手而言,还是有点参考价值.文章参见:http://skypegnu1.blog.51cto.com/8991766/ ...

  5. Android中Input型输入设备驱动原理分析(一)

    转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反 ...

  6. Android中Input型输入设备驱动原理分析<一>

    话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反正这个是没变的,在android的底层开发中对于Linux的基本驱动程序设计还是没变的,当然Android底层机制也 ...

  7. 树莓派 -- 按键 (key)使用BCM2835 gpio library

    BCM2835 GPIO library介绍 This is a C library for Raspberry Pi (RPi). It provides access to GPIO and ot ...

  8. python代码实现树莓派3b+驱动步进电机

    python代码实现树莓派3b+驱动步进电机 之前买了个树莓派,刚买回来那会儿热情高涨,折腾了一段时间,然后就放那吃灰了.前几天忽然想起来这个东西了,决定再玩玩儿,于是就从某宝上购买了一套步进电机.驱 ...

  9. 【树莓派】【转】将树莓派Raspberry Pi设置为无线路由器(WiFi热点AP,RTL8188CUS芯片)

    下文为转载,文章转自:http://wangye.org/blog/archives/845/,仅供本次学习实践参考. 最近又开始折腾起Raspberry Pi来了,因为某处上网需要锐捷拨号,于是我就 ...

随机推荐

  1. hdu1115【多边形求重心模板】

    1.质量集中在顶点上.n个顶点坐标为(xi,yi),质量为mi,则重心(∑( xi×mi ) / ∑mi, ∑( yi×mi ) / ∑mi) 2.质量分布均匀.这个题就是这一类型,算法和上面的不同. ...

  2. (2)css的复合选择器与特性

    css的复合选择器与特性 在本篇学习资料中,将深入了解css的相关概念,上一篇介绍的3种基本选择器的基础上,学习3种由基本选择器复合构成的选择器,然后再介绍css的两个重要的特性. 1.复合选择器 复 ...

  3. Spring AOP 面向切面编程入门

    什么是AOP AOP(Aspect Oriented Programming),即面向切面编程.众所周知,OOP(面向对象编程)通过的是继承.封装和多态等概念来建立一种对象层次结构,用于模拟公共行为的 ...

  4. C++this详解

    以前对this指针误解挺多的,在这里单独写一篇进行总结,有不对之处,欢迎指正批评! 一.问题 1.一个类中的不同对象在调用自己的成员函数时,其实它们调用的是同一段函数代码,那么成员函数如何知道要访问哪 ...

  5. ACM配置指南

    Ubuntu桌面入门指南 ACM比赛系统ubuntu 使用指南 ACM核武器 简明 Vim 练级攻略 Vim命令合集 代码编辑神器VIM(附我写acm程序时的配置) my_vimrc in ubunt ...

  6. 二进制流BinaryFormatter存储读取数据的细节测试

    二进制流的使用很方便,为了更好的理解应用它,我创建简单对象开始测试它的增加特性和减少特性. [Serializable] class Data----------开始时候的存储对象 { public ...

  7. 比较C#中几种常见的复制字节数组方法的效率[转]

    [原文链接] 在日常编程过程中,我们可能经常需要Copy各种数组,一般来说有以下几种常见的方法:Array.Copy,IList<T>.Copy,BinaryReader.ReadByte ...

  8. andorid IOS 判断APP下载

    <?phpif(strpos($_SERVER['HTTP_USER_AGENT'], 'iPhone')||strpos($_SERVER['HTTP_USER_AGENT'], 'iPad' ...

  9. Java常用的排序查找算法

    public static void main(String[] args) {      // bubbleSort(); // int[] a = {20,2,10,8,12,17,4,25,11 ...

  10. 'NSUnknownKeyException' … setValue:forUndefinedKey:]: …not key value coding compliant

    解决一个问题: 当我添加一个IBout, 报了如下错误 NSUnknownKeyException' … setValue:forUndefinedKey:]: …not key value codi ...