This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ]: Transitioning the GPIO userspace interface from SYSFS to Chardev

I am familiar with SYSFS interface to interact with GPIO pins. In SDK 9.0, this interface for GPIO was removed. How can I use the Chardev interface? This is for the AM62x and AM64x.

  • In SDK 9.0, the legacy SYSFS interface for GPIO was removed and the Chardev interface takes its place.  This FAQ will introduce the Chardev interface and how to get started.

    Chardev Interface

    The Character Device (Chardev) Interface uses the gpiod library to interact with GPIO pins in userspace. It uses commands in the EVM terminal to perform the same operations that SYSFS does.

    Read about these commands in the Manpages: https://manpages.debian.org/experimental/gpiod/index.html

    Here is a quick overview of the commands:

    Commands

    Function

    gpiodetect

    This shows the different gpiochip available, addresses, and pin count.

    gpiofind

    This finds a gpiochip and line number based on the name of the pin. Most of the pins do not have a name.

    gpioget

    This returns the value of a pin. This command will change the direction of the pin to input.

    gpioinfo

    This shows information about gpiochips like direction and name.

    gpiomon

    This is a monitor to detect changes in value.

    gpioset

    This sets the value of a pin. This command will change the direction of the pin to output.

    SYSFS vs Chardev

    Here are some of the benefits of using Chardev over SYSFS:

    1. Allows for reading and writing multiple pins at the same time
    2. Allows for better polling of events than what SYSFS offers
    3. Allows for control over state configurations like open-drain, push-pull etc.

    The only drawback of using Chardev over SYSFS is lack of control over pin direction. gpioset and gpioget  are commands that will change the direction of the pin and requires cautious use of these commands. With Chardev, changing the direction of a pin will erase the current value of the pin and set it to undefined.

    An example:

    If a user sets a pin value using gpioset then tries to read the value using gpioget , the outcome is unexpected. The direction was changed due to these commands and the value will differ from hardware and software. From the software perspective, the value will be whatever the default value is (usually 1/high). From the hardware perspective, the measured voltage will be around .5V to .7V which means its undefined (High=3.3V and Low=0V).

    Replicating SYSFS process with Chardev

    For SYSFS, the steps to set a pin include:

    1. Finding the GPIO line integer (Base number + offset)
    2. Export the GPIO number
    3. Set the pin direction
    4. Set the pin value

    The Chardev interface can complete steps 3 and 4 in the same command line. Steps 1 and 2 for SYSFS are removed since they are unneeded, but a different step will be used. Here is how this process can be replicated with Chardev:

    1. use gpiodetect to find which gpiochip to use
    2. use gpioset to set the value and direction of the pin

    Lets work through an example of GPIO0_39 using both interfaces to see the differences.

    Example with GPIO0_39


    Starting with SYSFS:

    # cd /sys/class/gpio/
    
    # ls -l #step 1
    
    total 0
    
    --w------- 1 root root 4096 Feb 24 04:51 export
    
    lrwxrwxrwx 1 root root    0 Feb 24 04:51 gpiochip287 -> ../../devices/platform/bus@f0000/20010000.i2c/i2c-1/1-0022/gpio/gpiochip287
    
    lrwxrwxrwx 1 root root    0 Feb 24 04:51 gpiochip311 -> ../../devices/platform/bus@f0000/601000.gpio/gpio/gpiochip311
    
    lrwxrwxrwx 1 root root    0 Feb 24 04:51 gpiochip399 -> ../../devices/platform/bus@f0000/600000.gpio/gpio/gpiochip399
    
    lrwxrwxrwx 1 root root    0 Feb 24 04:51 gpiochip486 -> ../../devices/platform/bus@f0000/bus@f0000:bus@4000000/4201000.gpio/gpio/gpiochip486
    
    lrwxrwxrwx 1 root root    0 Feb 24 04:51 gpiochip510 -> ../../devices/platform/bus@f0000/3b000000.memory-controller/gpio/gpiochip510
    
    --w------- 1 root root 4096 Feb 24 04:51 unexport
    
    # echo 438 > export #step 2
    # cd gpio438
    # echo out > direction #step 3
    # echo 1 > value #step 4

    To get gpio438, we matched the base address of GPIO0 (0x600000) to the gpiochip base number(gpiochip399). This means the base number for GPIO0 is 399. Then we add the offset number of the pin (39) to the base to get 438. Finally, it was exported.

    Please note GPIO1 has an address of 0x601000 and MCU_GPIO0 has an address of 0x4201000.

    Using the SYSFS interface, GPIO0_39 is an output with value 1. Let's get the same result with Chardev interface:

    Chardev:
    # gpiodetect #step 1
    
    gpiochip0 [4201000.gpio] (24 lines)
    
    gpiochip1 [600000.gpio] (92 lines)
    
    gpiochip2 [601000.gpio] (52 lines)
    
    gpiochip3 [1-0022] (24 lines)
    
    # gpioset gpiochip1 39=1 #step 2

    Since GPIO0 has a base address of 0x600000, gpiodetect tells us that gpiochip1 corresponds to GPIO0.

    Please note GPIO1 has an address of 0x601000 and MCU_GPIO0 has an address of 0x4201000.

    GPIO0_39 is an output with value 1 just like SYSFS interface. Notice the following:

    1. Instead of finding the base number, only the chip number is needed by using gpiodetect.
    2. There is no need to export the pin.
    3. Both the pin value and direction were set with gpioset.

    From here, explore some of the other commands available in the Chardev interface like gpiomon for event polling and gpioinfo for more information about pins.