【问题标题】:How GPIO is mapped in memory?GPIO如何映射到内存中?
【发布时间】:2015-07-25 03:26:46
【问题描述】:

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

【问题讨论】:

    标签: linux-device-driver mmap gpio raspberry-pi2 ioports


    【解决方案1】:

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

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

    BCM2708 的 GPIO 如何映射到内存中?

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

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

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

    还有其他司机吗?

    是的。 pinctrl(引脚控制)驱动程序是比 GPIO 低层(即更靠近硬件)。它是处理引脚复用的 pinctrl 层(即引脚是用于外围功能还是用作 GPIO)。
    SoC 的 pinctrl 驱动程序(例如 drivers/pinctrl/pinctrl-bcm2835.c)是您可以找到 devm_ioremap_resources() 的位置(依次调用 devm_request_mem_region()devm_ioremap()) 用于 GPIO 寄存器块。

    我可以通过 R&W 来处理 GPIO 到 /sys/class/gpio/* 吗?

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

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

    【讨论】:

    • 我猜这就是 '/dev/mem' 映射地址的来源。据我所知,在这段代码中,它声明了一个平台设备来获取资源。 pinctrl 是 bcm2835 的 bcm2708 的控制器,GPIO驱动是上层导出到外面的吗?
    • 关于 RPi 驱动程序是否应参考 BCM2708 或 BDM2835/6 似乎存在争议。查看 BCM2835 数据表,GPIO 寄存器从 0x7E200000 开始。您可以查看 RPi 上的 /proc/iomem 以查看物理内存中的外围设备(由驱动程序声明)。尝试检查引导或系统日志(即dmesg 命令)以获取 pinctrl 和 GPIO 驱动程序消息。否则我不明白“pinctrl 是否作为控制器播放...”。 GPIO 驱动程序可由其他设备设备驱动程序(例如 SPI 从机的中断)以及 sysfs 访问。
    • 有关更多通用详细信息,请参阅pinctrlgpio 的 Linux 文档。
    • 我知道这个问题已经很老了,但我发现这个视频很有帮助youtube.com/watch?v=aT5XMOrid7Y
    【解决方案2】:

    这个响应可能不是“四面楚歌”,因为它只是为 Raspberry Pi 2 提供了一个 GPIO 基地址,而不是一个如何。

    尽管如此,Raspberry Pi 2 上的 Raspbian OS 在0x3f20,0000 提供了一个基地址。

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

    使用上述基地址通过mmmap 调用来闪烁 Raspberry Pi 2 上的 ACT LED 的粗略 ARMv7 汇编示例如下面的链接所示。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-09
      • 1970-01-01
      相关资源
      最近更新 更多