Using GPIO from a Linux Shell
  • 30 Sep 2021
  • 5 Minutes to read
  • Dark
    Light
  • PDF

Using GPIO from a Linux Shell

  • Dark
    Light
  • PDF

Use the userspace GPIO driver

The following guide shows how to use the new userspace char device driver and API (libgpiod). The new character device and API makes use of /dev/gpiochip devices through ioctl calls:\

root@pico-imx8mm:~# ls /dev/gpiochip*
/dev/gpiochip0
/dev/gpiochip1
/dev/gpiochip2
/dev/gpiochip3
/dev/gpiochip4

Each entry in /dev/gpiochip corresponds to a GPIO device (i.e. a bank of GPIOs). In i.MX, each bank can contain up to 32 GPIO lines (0-31).To get the GPIO correspond to a particular module pin, you might reference the hardware manual for the module. In some cases, you might also need to reference the SOC reference manual.For example, in the PICO-IMX8M-MINI Hardware Reference Manual:NXP IMX8M-MINI reference manual snapshot showing GPIO08 and GPIO09

Using the Command Line Tools

To make GPIO simple to access via scripts and the command line, there are several command line tools available.

gpiodetect

Search for gpio devices and indicate how many GPIOs are controlled by each.

root@pico-imx8mm:~# gpiodetect
gpiochip0 [30200000.gpio] (32 lines)
gpiochip1 [30210000.gpio] (32 lines)
gpiochip2 [30220000.gpio] (32 lines)
gpiochip3 [30230000.gpio] (32 lines)
gpiochip4 [30240000.gpio] (32 lines)

gpioinfo

List the information for the gpio lines per bank.

    root@pico-imx8mm:~# gpioinfo
    gpiochip0 - 32 lines:
    line 0: unnamed unused input active-high
    line 1: unnamed unused input active-high
    line 2: unnamed unused input active-high
    line 3: unnamed "interrupt" input active-high [used]
    line 4: unnamed unused input active-high
    line 5: unnamed unused output active-high
    line 6: unnamed unused input active-high
    line 7: unnamed unused input active-high
    line 8: unnamed unused input active-high
    line 9: unnamed "usb_otg_vbus" output active-high [used]
    line 10: unnamed "backlight_pwr" output active-high [used]
    line 11: unnamed "WL_REG_ON" output active-high [used]
    line 12: unnamed "?" output active-high [used]

This command is useful to see which GPIOs are already used, are inputs/outputs, and their active state (high/low). Adding a number after the command, corresponding to the bank, will list only the GPIOs in that bank. No argument lists all the GPIOs in all banks.

gpioset

Set a the value of a GPIO. For example, setting the value of line 9 of gpio bank 3 to 1 below:

    root@pico-imx8mm:~# gpioset gpiochip3 9=1

You can also omit the 'gpiochip' name below as:

    root@pico-imx8mm:~# gpioset 3 9=1

Setting the value to 0:

    root@pico-imx8mm:~# gpioset 3 9=0

gpioget

Get a the value of a GPIO. For example, read the value of line 8 of gpio bank 3:

    root@pico-imx8mm:~# gpioget gpiochip3 8
    0

You can also omit the 'gpiochip' name below as:

    root@pico-imx8mm:~# gpioget 3 8
    0

Using legacy sysfs-based GPIO

The following method is deprecated and no longer recommended for use. It may not be supported in modern kernels.

Background

The iMX-series CPUs (iMX5, iMX6, iMX6SX, iMX6UL, iMX7D, iMX8M, ...) refer to GPIOs using two parameters: a bank number and an io number. For example typical GPIOs can be GPIO2_IO12 or GPIO1_IO00.The bank refers to the internal GPIO controller inside the CPU, and one controller has 32 IOs. For the example gpios, GPIO2_IO12 uses bank 2 and io 12.

Finding gpio number

To use a GPIO its number needs to be known. If we know the bank and io number, the kernel's number can be calculated with

    N = (BANK – 1) * 32 + IO

For example GPIO2_IO12 would get the kernel GPIO number

    N = (2 – 1) * 32 + 12 = 44

Finding out which bank and io a pin has, one has to consult the schematics.

Once the pin name has been found, its corresponding GPIO bank and io number can be looked up either in the processor's reference manual or from within the kernel source code.

In the latter the pinmuxes are defined in the device tree folder arch/arm/boot/dts/, usually in a file named *pinfunc.h or so.

A pin can only have one pinmux as GPIO, and a GPIO+IO can only be present on one pin (it is a one-to-one mapping).

Setting and reading a GPIO {#setting_and_reading_a_gpio}

The GPIOs are typically accessible in /sys/class/gpio folder.

Each GPIO has its own folder. For instance GPIO 44 will use folder named /sys/class/gpio/gpio44.

If the folder is not present, the GPIO needs to be exported first. This can be done by:

    # echo 44 > /sys/class/gpio/export

and similarily unexported by

    # echo 44 > /sys/class/gpio/unexport

Inside the gpio folder are the two important 'files': value and direction.

To read the value of a gpio, first set the gpio as an input by:

    # echo in > /sys/class/gpio/gpio44/direction

and then read the value by

    # cat /sys/class/gpio/gpio44/value

Similarily, set the value of output GPIOs by first setting the direction

    # echo out > /sys/class/gpio/gpio44/direction

and then set the value low by

    # echo 0 > /sys/class/gpio/gpio44/value

or to high

    # echo 1 > /sys/class/gpio/gpio44/value
Note

On products that have isolated GPIOs this semantic is reversed, use 1 for low and 0 for high

GPIO expanders

GPIO expanders appear on some TechNexion products. Typically the GPIOs on expander chips do not follow the bank/io priniciple.

Instead, the GPIOs are directly mapped to the end of the gpio number space. Look for folders name gpiochip* in /sys/class/gpio/.

Easiest way to find the expander is to look at the ngpio file in the gpiochipN folder. A 8-bit expander will have an 8 in ngpio.

Then the GPIO numbers can be found by looking at the base file. A value of, say, 208 means that the expanders gpios will be number 208, 209, 210, ...

When the GPIO numbers have been identified, they can be exported and used just as the CPU native banked GPIOs.

Troubleshooting GPIOs

Sometimes it might appear that writes to the value file have no effect, the value stays 0 and measuring the voltage on the gpio line gives the same result.Some common causes for this type of problems are:

  • The pin is already used by something else, typically defined to do so in the device tree. Look there first.
  • The pin number is wrong. Do the math again. 🙂
  • The pin is not muxed as GPIO after all. Re-check the device tree.
  • The pin is an isolated GPIO and cannot be set in desired mode
  • The pin is an isolated output GPIO, and there is no external power connected to the GPIO port

Was this article helpful?