使能上拉GPIO

使能上拉GPIO

问题描述:

即时通讯工具与AT91SAM9G25板,它有4个PIO控制器管理多达32个可编程I/O线。每个引脚可配置为仅用于通用I/O线 ,或者可配置为多路复用到两个外设I/O的I/O线。因此,例如根据文档(SAM9G25,第14页),可以将信号PC0复用为通用I/O线或VIDEO_ATMEL_ISI(图像传感器接口的ISI)的ISI_D0线。使能上拉GPIO

╔════════════╦════════════╦════════════╦════════════╦════════════╗ 
║ 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时,由于pullup,我在多个GPIO中读取“1”值作为INPUT。当它们可以与其他外设复用时,在几个电路板上复位时,这是GPIO(INPUT和上拉电阻)的正常安全状态吗?我没有看到我可以通过GPIOLIB禁用用户空间的pullup。例如,我看到当内核启动时它检查图像传感器外设是在内核还是作为模块启用,如果是的话,它将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 /内核/调试/ 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 /内核/调试/ 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线都是带有上拉的INPUTS,我没有找到内核或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); 

头拱/ ARM /马赫AT91 /包括/马赫/ 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:对不起,我的英文任何错误,我知道我需要改善它。

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

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

+0

嗨乔库尔,谢谢。我会检查一下继电器是否被输入引脚拉起来,我认为你是对的。我还有一个相关的问题,那我该如何寻找GPIO的内核API?我是一个使用内核连接应用程序的begginer,我只知道通过GNU C库调用系统(POSIX)的方式。但是如果在我构建内核时没有创建模块,我应该使用哪个库?哪种方式在内核中使用驱动程序,而不使用库?对不起,如果它的一个愚蠢的问题,或者我可能需要更多的Linux驱动程序背景。 – MABC 2013-03-16 12:51:11

+0

最简单的开始方法是在Linux控制台上使用命令。检查上面的sysfs链接。 Linux控制台是您要登录的位置,然后输入其他命令(如ls)以查看目录内容。如果你想将GPIO#82作为输出低电平驱动到继电器,这些命令可以这样做:echo 82>/sys/class/gpio/export; echo out>/sys/class/gpio/gpio82/direction; echo 0>/sys/class/gpio/gpio82/value。如果你想从一个Linux应用程序来做到这一点,你可以把它们放在一个shell脚本文件(/home/me/my.sh)中,然后在应用程序中添加下面这行代码:system(“/ home/me/my.sh” ); – 2013-03-17 00:50:56

+0

嗨,再次感谢乔。我知道通过sysfs驱动GPIO的方式,但启用或禁用GPIO上拉的功能不会导出到sysfs,那么我认为我必须通过sysfs将此功能导出到用户空间,但现在我认为这个问题已经解决,因为上拉激活继电器的能力非常弱。问题是关于在Linux中使用通用驱动程序,我认为唯一的方法是使用librarys或内核模块,或通过一般系统调用libc,我吧? – MABC 2013-03-17 01:16:41

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

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

但是这将是非常甜蜜的,如果pinctrl有一个用户空间界面像GPIO所以在控制引脚的是用户空间控制的完整解决方案。