1. 用GPIO sysfs读写IO(Seeed的设备树不支持这种操作,仅作为介绍)) s9 g8 }, R2 ^5 d7 e4 ~1 |1 h# G
在Linux中,最常见的读写GPIO方式就是用GPIO sysfs interface,是通过操作/sys/class/gpio目录下的export、unexport、gpio{N}/direction, gpio{N}/value(用实际引脚号替代{N})等文件实现的,经常出现shell脚本里面。比如在shell中控制树莓派3B的GPIO12:
: g. S8 _, J/ X: N5 F" A- sudo su
! u0 O4 o; ?$ j - cd /sys/class/gpio+ g/ ]. B3 U, k% @
- echo 12 > export$ U( R) Q5 K. e) a3 z: ?. Y' n2 n
- echo out > gpio12/direction # io used for output$ a* S; N+ ]; M8 P+ O
- echo 1 > gpio12/value # output logic 1 level
5 L& c0 L3 ]6 f; F4 @ - echo 0 > gpio12/value # output logic 0 level( v2 t; J& J' P
- echo 12 > unexport
" ~% b. {- g0 ~5 Y6 Y9 e
复制代码 基于GPIO sysfs interface封装的库很多,这里推荐vsergeev写的python-periphery、c-periphery和lua-periphery,python、lua和c任君挑选,通用性挺好的。
Y+ `2 T9 p& ]! F8 S( u/ A! B" x/ y2 m. x
8 | |. ^8 @1 w0 u M
GPIO sysfs interface目前用的较广泛,但存在一些问题,比如不能并发获取sysfs属性、基本是为shell设计接口。所以从linux 4.8开始gpiod取代了它。$ `" `9 _7 x- O/ ]& l
Since linux 4.8 the GPIO sysfs interface is deprecated. User space should use3 r, _. r: B4 q
the character device instead. This library encapsulates the ioctl calls and
$ W% y5 |& b5 J3 S$ t7 vdata structures behind a straightforward API. 2. 用libgpiod读写IO(Seeed支持这种操作)% J( Z$ q+ @1 V
新的设计gpiod,GPIO访问控制是通过操作字符设备文件(比如/dev/gpiodchip0)实现的,并通过libgpiod提供一些命令工具、c库以及python封装。3 S9 I$ D6 L6 s
The new character device interface guarantees all allocated resources are/ f/ h/ B+ j: [9 d: w% d% n
freed after closing the device file descriptor and adds several new features
; \9 e: m/ x* [6 F9 ]that are not present in the obsolete sysfs interface (like event polling,# x* j1 w" l4 p5 I* C" l
setting/reading multiple values at once or open-source and open-drain GPIOs).8 g3 f {5 j, @# F, H$ `: g l
% R( N* ^6 N& L* ~- q& s
Unfortunately interacting with the linux device file can no longer be done. i7 ?. O ~& x5 y$ ~ r) \- x1 k
using only standard command-line tools. This is the reason for creating a9 B5 X3 b* m- v' h3 z
library encapsulating the cumbersome, ioctl-based kernel-userspace interaction
$ g& @5 }. E5 G4 Ein a set of convenient functions and opaque data structures.7 P0 H( C$ y( j1 d9 Q
% x" V7 j" y: b( \( DAdditionally this project contains a set of command-line tools that should
% p; i1 m; H5 s7 x7 l$ m1 @0 Qallow an easy conversion of user scripts to using the character device. 通过libgpiod提供的gpioset、gpioget、gpiomon可以快速的读写GPIO和检测输入事件。
8 Z, h! W7 N6 F- sudo apt install -y gpiod
- ?/ w, H/ D9 z' ^ - sudo gpioset 0 12=0
8 }. v1 E0 Q0 A5 W - sudo gpiomon 0 12 # detect event on gpio12
复制代码 gpiod由于比较新,用的人还非常少,虽说libgpiod里面有python封装,但还没有打包到debian stretch的仓库里面,所以用python ctypes封装了一份,在voice-engine/gpio-next,控制一个LED的python代码是这样:: ]' r# i- H9 L7 W F3 |) o
- import time
" [8 l" }4 c- J/ E+ w. k1 J - from gpio_next import GPIO* P. W0 Q) b2 ]0 A5 E% Z
- # o/ y% j# K; ^3 m
- LED = GPIO(12, direction=1)
" z8 U$ @! ~! e, x - for i in range(10):
" H% I d; D4 k - LED.write(i & 1)* S& T) D! `0 M* d9 g8 j
- time.sleep(1)
复制代码 当然也可以通过C语言调用系统操作的方式控制GPIO,具体的方法参照我的这篇博客:) Y0 ?( ^) f4 N6 G
C语言调用shell命令- [% r" ]( B1 t5 g8 x/ z. F) M
) `0 u8 k; m* l' f
# C* i1 d7 ~( |0 d9 D用sysfs,或gpiod,都是用linux对GPIO封装的接口,封装之后的通用性好了,但性能会变弱。在Linux中同样也可以直接操作GPIO寄存器这里网上资源比较多且较为深入。笔者能力有限,所以在此不再叙述。
0 ]) x4 K! f. ^" b$ t, O" ?( c: y/ F7 a' U9 y2 R9 A+ P# W, @0 e& w
+ y& \! ?5 W3 D8 }$ g4 t% U& x1 Q& T& p, x
|