bcm2837linux编程_Linux读写GPIO的几种方法及一些有趣的应用

在智能音箱的设计中,最近在写LED的控制、触摸按键的检测,这不就是在Linux下读写GPIO,太简单吧,很多人就不屑一顾了。不过,简单读写IO也可以玩出花来,得到意外的惊喜。

这里就介绍Linux下树莓派的几种GPIO读写方式,以及一些有趣的应用。先从最基本的开始,同sysfs读写IO。

1. 用GPIO sysfs读写IO

在Linux中,最常见的读写GPIO方式就是用GPIO sysfs interface,是通过操作/sys/class/gpio目录下的export、unexport、gpio{N}/direction, gpio{N}/value(用实际引脚号替代{N})等文件实现的,经常出现shell脚本里面。比如在shell中控制树莓派3B的GPIO12:

sudo su

cd /sys/class/gpio

echo 12 > export

echo out > gpio12/direction # io used for output

echo 1 > gpio12/value # output logic 1 level

echo 0 > gpio12/value # output logic 0 level

echo 12 > unexport

基于GPIO sysfs interface封装的库很多,这里推荐vsergeev写的python-periphery、c-periphery和lua-periphery,python、lua和c任君挑选,通用性挺好的。

GPIO sysfs interface目前用的较广泛,但存在一些问题,比如不能并发获取sysfs属性、基本是为shell设计接口。所以从linux 4.8开始gpiod取代了它。Since linux 4.8 the GPIO sysfs interface is deprecated. User space should use

the character device instead. This library encapsulates the ioctl calls and

data structures behind a straightforward API.

2. 用libgpiod读写IO

新的设计gpiod,GPIO访问控制是通过操作字符设备文件(比如/dev/gpiodchip0)实现的,并通过libgpiod提供一些命令工具、c库以及python封装。The new character device interface guarantees all allocated resources are

freed after closing the device file descriptor and adds several new features

that are not present in the obsolete sysfs interface (like event polling,

setting/reading multiple values at once or open-source and open-drain GPIOs).

Unfortunately interacting with the linux device file can no longer be done

using only standard command-line tools. This is the reason for creating a

library encapsulating the cumbersome, ioctl-based kernel-userspace interaction

in a set of convenient functions and opaque data structures.

Additionally this project contains a set of command-line tools that should

allow an easy conversion of user scripts to using the character device.

通过libgpiod提供的gpioset、gpioget、gpiomon可以快速的读写GPIO和检测输入事件。

sudo apt install -y gpiod

sudo gpioset 0 12=0

sudo gpiomon 0 12 # detect event on gpio12

gpiod由于比较新,用的人还非常少,虽说libgpiod里面有python封装,但还没有打包到debian stretch的仓库里面,所以用python ctypes封装了一份,在voice-engine/gpio-next,控制一个LED的python代码是这样:

import time

from gpio_next import GPIO

LED = GPIO(12, direction=1)

for i in range(10):

LED.write(i & 1)

time.sleep(1)

用sysfs,或gpiod,都是用linux对GPIO封装的接口,封装之后的通用性好了,但性能会变弱。如果学过51、ARM单片机,最熟悉读写GPIO方式大概就是直接操作GPIO寄存器,这是最快速的操控IO口方式,而在Linux中同样也可以直接操作GPIO寄存器。

3. 寄存器直接读写IO

树莓派相对单片机,用的是带MMU的ARM SoC BCM2837,地址空间略复杂一点,有不同的地址空间的映射,从 BCM2837数据手册来看,GPIO寄存器总线地址(bus address)从0x7E200000开始(见下图),映射的物理地址是0x3F200000(参见手册第6页)。

在Linux下直接读写物理地址,先要打开设备文件/dev/mem,然后用mmap把文件映射,最后根据寄存器地址读写相应的寄存器。

可以用devmem2来读写物理内存地址,如果不能apt install devmem2,可以在https://github.com/VCTLabs/devmem2下载并编译一份。比如,读写树莓派的IO状态:

sudo devmem2 0x3F200034 wPhysical addresses range from 0x3F000000 to 0x3FFFFFFF for peripherals. The bus addresses for peripherals are setup to map on to the peripheral bus add ressrange starting at 0x7E000000. Thus a peripheral advertised here at bus address 0x7Ennnnnn is available at physical address 0x3Fnnnnnn.

Python库RPi.GPIO就是通过直接访问寄存器控制GPIO的,由于不同芯片的GPIO寄存器地址大多不一样,所以没有什么通用性。

由于树莓派上可以跑通用的Debian Linux系统,有很多软件资源可以使用,把IO口读写和一些软件资源结合起来,有些意想不到的效果。

应用1 :结合sigrok + pulseview用作一个逻辑分析仪

利用普通的IO作为输入采集信号,可以把树莓派当作多通道逻辑分析仪使用,结合sigrok可以分析各种协议,包括I2S、I2C、SPI、UART等。richardghirst/Panalyzer​github.come732431f0001e9e7e8daf4c33e719455.png

应用2:结合OpenOCD作为一个通用的调试下载器

如果你知道J-Link的话,OpenOCD + 树莓派是匹敌J-Link的存在,OpenOCD可以利用树莓派的普通GPIO模拟SWD或JTAG接口调试各种设备,调试STM32当然不在话下,近年来很火的ESP32也可以支持。

应用3:打造自己的FM无线电台

当我第一次看到有人仅仅用一个树莓派实现一个FM无线电台时,我能想到最浪漫的事,就是为心爱的她打造一个只属于她的电台,播放爱的广播。咳咳~扯远了

控制IO口和搭建一个FM无线电台看起来相差十万八千里,居然可以把两者结合到了一起,用单个树莓派就实现了一个FM无线电台,这是最令我惊叹的树莓派应用了。

怎么实现的呢?由于树莓派3B的ARM处理器可以跑到1.4GHz,用DMA+PWM可以很高频的控制IO口输出变化,可以达到100MHz以上,IO口电平变化,则有电场变化,电场变化引发磁场变化,然后发射出电磁波了。加上FM调制,就可以打造出一个FM无线电台!为了增强无线发射能力,可以在IO口上接一根线。实现的代码在:ChristopheJacquet/PiFmRds​github.com1a237da76a1bd4f04d45611d78f551d7.png

结合最基本的IO操作,还有很多有趣的应用可以实现,你想到了什么?

Have fun!

Table of Contents 1 Introduction 4 1.1 Overview 4 1.2 Address map 4 1.2.1 Diagrammatic overview 4 1.2.2 ARM virtual addresses (standard Linux kernel only) 6 1.2.3 ARM physical addresses 6 1.2.4 Bus addresses 6 1.3 Peripheral access precautions for correct memory ordering 7 2 Auxiliaries: UART1 & SPI1, SPI2 8 2.1 Overview 8 2.1.1 AUX registers 9 2.2 Mini UART 10 2.2.1 Mini UART implementation details. 11 2.2.2 Mini UART register details. 11 2.3 Universal SPI Master (2x) 20 2.3.1 SPI implementation details 20 2.3.2 Interrupts 21 2.3.3 Long bit streams 21 2.3.4 SPI register details. 22 3 BSC 28 3.1 Introduction 28 3.2 Register View 28 3.3 10 Bit Addressing 36 4 DMA Controller 38 4.1 Overview 38 4.2 DMA Controller Registers 39 4.2.1 DMA Channel Register Address Map 40 4.3 AXI Bursts 63 4.4 Error Handling 63 4.5 DMA LITE Engines 63 5 External Mass Media Controller 65 o Introduction 65 o Registers 66 6 General Purpose I/O (GPIO) 89 6.1 Register View 90 6.2 Alternative Function Assignments 102 6.3 General Purpose GPIO Clocks 105 7 Interrupts 109 7.1 Introduction 109 7.2 Interrupt pending. 110 7.3 Fast Interrupt (FIQ). 110 7.4 Interrupt priority. 110 7.5 Registers 112 8 PCM / I2S Audio 119 8.1 Block Diagram 120 8.2 Typical Timing 120 8.3 Operation 121 8.4 Software Operation 122 8.4.1 Operating in Polled mode 122 8.4.2 Operating in Interrupt mode 123 8.4.3 DMA 123 8.5 Error Handling. 123 8.6 PDM Input Mode Operation 124 8.7 GRAY Code Input Mode Operation 124 8.8 PCM Register Map 125 9 Pulse Width Modulator 138 9.1 Overview 138 9.2 Block Diagram 138 9.3 PWM Implementation 139 9.4 Modes of Operation 139 9.5 Quick Reference 140 9.6 Control and Status Registers 141 10 SPI 148 10.1 Introduction 148 10.2 SPI Master Mode 148 10.2.1 Standard mode 148 10.2.2 Bidirectional mode 149 10.3 LoSSI mode 150 10.3.1 Command write 150 10.3.2 Parameter write 150 10.3.3 Byte read commands 151 10.3.4 24bit read command 151 10.3.5 32bit read command 151 10.4 Block Diagram 152 10.5 SPI Register Map 152 10.6 Software Operation 158 10.6.1 Polled 158 10.6.2 Interrupt 158 10.6.3 DMA 158 10.6.4 Notes 159 11 SPI/BSC SLAVE 160 11.1 Introduction 160 11.2 Registers 160 12 System Timer 172 12.1 System Timer Registers 172 13 UART 175 13.1 Variations from the 16C650 UART 175 13.2 Primary UART Inputs and Outputs 176 13.3 UART Interrupts 176 13.4 Register View 177 14 Timer (ARM side) 196 14.1 Introduction 196 14.2 Timer Registers: 196 15 USB 200 15.1 Configuration 200 15.2 Extra / Adapted registers. 202
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值