GPIO在内存中的映射方式



我最近正在浏览pi2的GPIO驱动程序,我发现用户空间pi2 GPIO库(如RPi)。GPIO 0.5.11)为BCM2708使用/dev/mem(从0x20000000开始,GPIO相对从0x200000开始)来映射用户空间内存区域以处理GPIO。但是我发现linux源代码树中的drivers/gpio被设计为由/sys/class/gpio/*处理。我没有发现像request_io_region__io_remap这样的I/O端口映射。我的问题是GPIO BCM2708如何映射到内存中?还有别的司机吗?我可以通过R&W到/sys/class/gpio/*来处理GPIO吗?

我没有发现像request_io_region和__io_remap这样的I/O端口映射。

ARM没有I/O端口空间。所有外设寄存器都被分配到内存空间中的地址。

GPIO如何在内存中映射?

gpio通常被实现为控制寄存器的外设,RPi的BCM2835中的gpio遵循这一约定。这组控制寄存器可以有不同的名称;例如,Atmel将这些寄存器称为并行I/O (PIO)外设。

每个GPIO(或者更准确地说每个引脚)将由每个控制寄存器函数中的一个或多个位表示。控制寄存器功能包括引脚分配(又名多路复用),设置输出为高,设置输出为低,读取引脚电平,电平和边缘检测控制。

现在没有对应于GPIO的单个比特可以读写。对于GPIO,在特定的寄存器中会有一个位来获取输入电平。在另一个寄存器中有一个位将GPIO输出设置为高,在另一个寄存器中有一个位将GPIO输出设置为低。

还有别的司机吗?

是的。pintrl(引脚控制)驱动器比GPIO更底层(即更接近硬件)。这是处理引脚多路复用的pintrl层(即一个引脚是用于外围功能还是作为GPIO)。SoC的pinctrl驱动程序(例如drivers/pinctrl/pinctrl-bcm2835.c)是您可以找到devm_ioremap_resources()的地方(它反过来调用devm_request_mem_region()devm_ioremap())用于GPIO寄存器块。

和我可以处理GPIO只是R&W到/sys/class/GPIO/*?

是的。sysfs接口用于访问那些未分配给外设的引脚。

附录
sysfs GPIO接口的功能有限。显然有用户空间库来访问额外的引脚属性(例如启用上拉或下拉电阻),这些属性通常在pinctrl驱动程序的域中。通常,这些库通过/dev/mem psuedo-file直接访问PIO硬件寄存器。请注意,这些技术是不安全的,并且可能会干扰其他设备驱动程序。

这个响应可能不是"on all four ",因为它只是为Raspberry Pi 2提供了一个GPIO基址。

尽管如此,树莓派2上的树莓操作系统提供了一个位于0x3f20,0000的基址。

$ dmesg -H 
[  +0.000749] gpiomem-bcm2835 3f200000.gpiomem: Initialised: Registers at 0x3f200000

一个粗糙的ARMv7 Assembly示例使用上述基址,通过mmmap调用,在树莓派2上闪烁ACT LED,如下面的链接所示。

https://github.com/InfinitelyManic/Raspberry-Pi-2

最新更新