【问题标题】:Enable pullup GPIO启用上拉 GPIO
【发布时间】:2013-03-14 14:15:29
【问题描述】:

我正在使用 AT91SAM9G25 板,该板具有 4 个 PIO 控制器,可管理多达 32 条可编程 I/O 线。每个引脚均可配置为通用 I/O 线 或作为多路复用至多两个外围 I/O 的 I/O 线。因此,例如,根据文档(SAM9G25,第 14 页),信号 PC0 可以多路复用,例如通用 I/O 线或 VIDEO_ATMEL_ISI(图像传感器接口的 ISI)的 ISI_D0 线。

╔════════════╦════════════╦════════════╦════════════╦════════════╗
║  Primary   ║ Alternates ║   PeripA   ║   PeripB   ║  PeripC    ║
╠════════════╬════════════╬════════════╬════════════╬════════════╣
║ Signal/Dir ║ Signal/Dir ║ Signal/Dir ║ Signal/Dir ║ Signal/Dir ║
║ ---------  ║ ---------  ║ ---------  ║ ---------  ║ ---------  ║
║ PC0 / I/O  ║            ║            ║ ISI_D0 / I ║            ║
╚════════════╩════════════╩════════════╩════════════╩════════════╝

所有 GPIO 线的复位状态为方向 IN 和上拉使能。当我通过 sysfs 使用 GPIOLIB 时,由于上拉,我在几个 GPIO 中读取了一个“1”值作为 INPUT。这是 GPIO(带上拉电阻的输入)在多个板中复位时的正常安全状态,当它们可以与其他外设复用时?我看不到如何使用 GPIOLIB 通过用户空间禁用上拉。例如,我看到当内核启动时,它会检查图像传感器外围设备是否在内核或模块中启用,如果是,它将 PC0 设置为外围设备 B。这是在 /arch/arm/mach 的内核源代码中-at91/at91sam9x5_devices.c

#if defined(CONFIG_VIDEO_ATMEL_ISI) || defined(CONFIG_VIDEO_ATMEL_ISI_MODULE)
....
         at91_set_B_periph(AT91_PIN_PC0, 0);    /* ISI_D0 */
...
#endif

如果我没有在内核中启用 ISI 支持,我可以使用 PC0 信号作为 GPIO 线。这是 /sys/kernel/debug/gpio:

    # cat /sys/kernel/debug/gpio

    GPIOs 32-63, A:

    GPIOs 64-95, B:
    [atmel_usba_udc] GPIOB16: [gpio] set
    [d1] GPIOB18: [gpio] clear

    GPIOs 96-127, C:

    GPIOs 128-159, D:
    [ohci_vbus] GPIOD19: [gpio] clear
    [ohci_vbus] GPIOD20: [gpio] clear
    [d2] GPIOD21: [gpio] set

这是 /sys/kernel/debug/at91_gpio

    # cat /sys/kernel/debug/at91_gpio

    Pin     PIOA            PIOB            PIOC            PIOD

    0:      A               A               GPIO:1          A
    1:      A               A               GPIO:1          A
    2:      GPIO:1          A               GPIO:1          A
    3:      GPIO:1          A               GPIO:1          A
    4:      GPIO:1          A               GPIO:1          GPIO:1
    5:      GPIO:1          A               GPIO:1          GPIO:1
    6:      GPIO:1          A               GPIO:1          A
    7:      B               A               GPIO:1          A
    8:      GPIO:1          GPIO:1          GPIO:1          A
    9:      A               A               GPIO:1          A
    10:     A               A               GPIO:1          A
    11:     A               GPIO:1          GPIO:1          A
    12:     A               GPIO:1          GPIO:1          A
    13:     A               GPIO:1          GPIO:1          A
    14:     A               GPIO:1          GPIO:1          GPIO:1
    15:     GPIO:1          GPIO:1          GPIO:1          A
    16:     GPIO:1          GPIO:1          GPIO:0          A
    17:     GPIO:1          GPIO:1          GPIO:1          A
    18:     GPIO:1          GPIO:1          GPIO:1          A
    19:     GPIO:1          A               GPIO:1          GPIO:0
    20:     GPIO:1          A               GPIO:0          GPIO:0
    21:     GPIO:1          A               GPIO:0          GPIO:1
    22:     GPIO:1          A               GPIO:1          A
    23:     GPIO:1          A               GPIO:1          A
    24:     GPIO:1          A               GPIO:1          A
    25:     GPIO:1          A               GPIO:1          A
    26:     GPIO:1          A               GPIO:1          A
    27:     GPIO:0          A               GPIO:1          A
    28:     GPIO:1          A               GPIO:0          A
    29:     GPIO:1          A               GPIO:0          A
    30:     GPIO:1          A               GPIO:1          A
    31:     GPIO:1          A               GPIO:1          A

上面的输出表明 PIOA0 被多路复用到外设 A(TXD0 UART 线),例如 PIOC20 被清除,但文档说所有处于复位状态的 GPIO 线都是带上拉的输入,我找不到内核或 u -boot 禁用此 GPIO 的上拉(如果没有触摸他的寄存器,GPIO 可能会保持其状态?)

但他的主要问题是,如何清除 GPIO 线的上拉寄存器?我在内核源代码中发现 /arch/arm/mach-at91/at91sam9x5_devices.c 使用了在 linux-2.6.39/arch/arm/mach-at91/gpio.c 中实现的这个函数。

    /*
    * enable/disable the pull-down.
    * If pull-up already enabled while calling the function, we disable it.
    */
    int __init_or_module at91_set_pulldown(unsigned pin, int is_on)
    {
        void __iomem    *pio = pin_to_controller(pin);
        unsigned    mask = pin_to_mask(pin);

        if (!pio || !cpu_has_pio3())
            return -EINVAL;

        /* Disable pull-up anyway */
        __raw_writel(mask, pio + PIO_PUDR);
        __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR));
        return 0;
    }
    EXPORT_SYMBOL(at91_set_pulldown);

头文件arch/arm/mach-at91/include/mach/gpio.h

    #ifndef __ASSEMBLY__
    /* setup setup routines, called from board init or driver probe() */
    .....
    extern int __init_or_module at91_set_pulldown(unsigned pin, int is_on);
    .....
    #endif  /* __ASSEMBLY__ */

如何在我的工具链中使用这些功能,或者我应该制作一个内核模块?

谢谢

PD:抱歉我的英语有任何错误,我知道我需要改进它。

【问题讨论】:

    标签: linux embedded arm gpio


    【解决方案1】:

    也许你可以不理会引体向上。我在 OMAP SoC 上使用过 GPIO,在最低级别有类似的引脚复用器选项,但不必担心上拉。通常无论是什么驱动它都可以吸收足够的电流(这是EE /电路的观点,如果您不熟悉,请不要担心)。浮动输入可能是随机且麻烦的;拉高应该没问题。

    我认为您不需要制作内核模块。我建议您尝试使用现有的用户模式界面。您的内核应该已经连接了低级驱动程序以通过 sysfs 提供访问。请参阅sysfsomap gpio。我认为我没有在 sysfs 中看到 pullup 选项。如果你得到了一些工作并且需要从 C 代码中调用它,那么你可以寻找 API,或者只使用 system()。

    【讨论】:

    • 嗨乔库尔,谢谢。我会检查继电器是否被带上拉的输入线激活,我认为你是对的。我有另一个相关的问题,那就是我如何寻找 GPIO 的内核 API?我是一个将我的应用程序与内核接口的初学者,我只知道通过 GNU C 库的调用系统(POSIX)方式。但是如果我在构建内核时没有构建模块,我应该使用什么库?哪种方法可以在内核中使用 libc 中的驱动程序并且没有库?抱歉,如果这是一个愚蠢的问题,或者我可能需要更多关于 linux 驱动程序的背景知识。
    • 最简单的开始方法是在 linux 控制台上使用命令。检查上面的 sysfs 链接。 Linux 控制台是您登录的地方,然后输入 ls 等其他命令以查看目录内容。如果您想将 GPIO #82 作为继电器的输出驱动为低电平,可以使用以下命令:echo 82 > /sys/class/gpio/export;回显 > /sys/class/gpio/gpio82/direction;回声 0 > /sys/class/gpio/gpio82/value。如果您想从 Linux 应用程序执行此操作,您可以将它们放在 shell 脚本文件 (/home/me/my.sh) 中,然后在应用程序中添加以下代码行:system("/home/me/my.sh" );
    • 你好乔库尔,谢谢。我知道通过 sysfs 驱动 GPIO 的方式,但是启用或禁用 GPIO 上拉的功能没有导出到 sysfs,然后我想我必须通过 sysfs 将此功能导出到用户空间,但现在我认为这个问题已经解决了,因为上拉激活继电器的能力非常弱。问题是关于在 linux 中使用通用驱动程序,我认为唯一的方法是使用库或内核模块,或者通过 libc 的通用系统调用,对吗?
    • 嗨。如果您需要调用像 at91_set_pulldown() 这样的涉及硬件的低级函数,则需要内核驱动程序或 hack/rebuild 是的。但这对初学者来说很难。在这种情况下,我认为 GPIO 将为您工作而没有任何麻烦。感谢您回答问题,祝您好运:)
    【解决方案2】:

    在使用设备树的较新内核上,您可以通过重新编译设备树“blob”来控制它,而无需更改内核或编写内核驱动程序。

    http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt

    但是,如果 pinctrl 有一个像 gpio 这样的用户空间接口,那就太好了,所以控制 pin 的完整解决方案是用户空间控制。

    【讨论】:

      猜你喜欢
      • 2016-02-11
      • 2023-04-04
      • 2020-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-05
      • 1970-01-01
      相关资源
      最近更新 更多