Search code examples
androidembedded-linuxgpiosysfs

what is the /sys/class/gpio/export and `/sys/class/gpio/unexport mechanism and what is the underlying sysfs functionality?


Using the legacy sysfs GPIO under Android and Linux the first step in the process is toe export the particular GPIO pins you want to use. And when you are done with the GPIO pin to unexport it.

I've been looking for an explanation of what the export command actually does however everything I've found is about the builtin bash command which has nothing to do with GPIO.

Then I realized the actual command from the command line was echo 938 > /sys/class/gpio/export and /sys/class/gpio/export is a special device file in folder /sys/class/gpio.

The only comment that I have found indicates that writing the GPIO pin number to /sys/class/gpio/export causes the GPIO special file associated with that GPIO pin to be "exported to user space" which then allows a user application to use the specified GPIO pin with file I/O to the special device file.

GPIO Sysfs Interface for Userspace

“export” …

Userspace may ask the kernel to export control of a GPIO to userspace by writing its number to this file.

Example: “echo 19 > export” will create a “gpio19” node for GPIO #19, if that’s not requested by kernel code.

“unexport” …

Reverses the effect of exporting to userspace.

Example: “echo 19 > unexport” will remove a “gpio19” node exported using the “export” file.

So if I specify echo 938 > /sys/class/gpio/export then a special device file folder /sys/class/gpio/gpio938 with special device files /sys/class/gpio/gpio938/value and /sys/class/gpio/gpio938/direction are created. And when I do an echo 938 > /sys/class/gpio/unexport then those special device files are removed?

In researching about using GPIO pins with a DragonBoard 410C under Android 5.1 an online course about this device I am taking said to add the following lines to the boot initialization script.

set -A pins 938 915 1017 926 937 930 914 971 901 936 935
for i in 0 1 2 3 4 5 6 7 8 9 10
do
    echo ${pins[i]} > /sys/class/gpio/export;
    chmod 777 /sys/class/gpio/gpio${pins[i]};
    chmod 777 /sys/class/gpio/gpio${pins[i]}/value;
    chmod 777 /sys/class/gpio/gpio${pins[i]}/direction;
done

My understanding is that these commands create the special device files for GPIO pins 938, 915, 1017, 926, 937, 914, 901, 936, 935 so that an application can read and write to these GPIO pins to do something such as turning an LED on and off by writing values to, for instance /sys/class/gpio/gpio938/value.

My understanding about this boot initialization script is that this removes the need for a user to use the sudo command with each of the shell command lines in order to perform these commands by a user before running an application that accesses the GPIO pins using sysfs. Is that true?

My Questions

What are these special device files /sys/class/gpio/export and /sys/class/gpio/unexport and how are they connected to some kind of functionality in the Linux kernel which creates and destroys special device files in the /sys/class/gpio folder?

With the suggested change to the boot initialization script are the special device files representing the GPIO pins created with access by anyone so an application program can just use the pins and not bother with export or unexport? A user application can just perform read/write to the special device without having to use sudo echo 938 > /sys/class/gpio/export first?

What is the access and sharing permissions for these special files created by the boot initialization script and can multiple applications be manipulating the same GPIO pins simultaneously?


Solution

  • There are several directory structures within the Linux file system that are not actual disk file directories. Instead these directory structures and the "files" within them are pseudo files or Linux operating system services and data that are presented as files and can be accessed using file operations but are not actual files stored on a persistent store such as a hard disk or solid state disk.

    A Study of Modern Linux API Usage and Compatibility: What to Support When You’re Supporting

    In addition to the main system call table, Linux exports many additional APIs through pseudo-file systems, such as /proc, /dev, and /sys. These are called pseudo-file systems because they are not backed by disk, but rather export the contents of kernel data structures to an application or administrator as if they were stored in a file. These pseudofile systems are a convenient location to export tuning parameters, statistics, and other subsystem-specific or device specific APIs. Although many of these pseudo-files are used on the command line or in scripts by an administrator, a few are routinely used by applications. In order to fully understand usage patterns of the Linux kernel, pseudo-files must also be considered.

    An analogy for pseudo files

    A way to think about these pseudo files from a user perspective is they are a kind of Remote Procedure Call interface to the Linux kernel that uses file system semantics to request that some operation be done. The file system semantics map to the following generic actions and behavior:

    • open the pseudo file means to open a connection between the user application and some functionality within the Linux kernel
    • read the pseudo file means to read a block of data provided by some functionality within the Linux kernel through the connection
    • write the pseudo file means to send a request message to some functionality within the Linux kernel through the connection (the message may be a command with data, a command only, or data only)
    • close the pseudo file means to close a connection between the user application and some functionality within the Linux kernel

    Different pseudo files expose different Linux kernel data and services which means that the interface specification as to how the file operations map to the Linux kernel functionality exposed through the pseudo file will vary depending not only on the Linux kernel functionality or handler for the pseudo file but also the Linux kernel version.

    This StackOverFlow posting, Create sysfs entry from kernel module , contains a simple example of a handler for a pseudo file in /sys showing the basics of providing the function interfaces the Linux kernel needs to hook the handler for the new pseudo file into the Linux kernel.

    This StackOverFlow posting, How to create proc entry under /proc/driver? , contains a simple example of a handler for a pseudo file in /proc.

    Both of these simple examples have a similar structure to the source code. However these specific examples may be using deprecated Linux kernel interfaces so I provide these links only to illustrate the underlying functionality of a pseudo file handler.

    export and unexport

    Normally the GPIO pins of the underlying hardware on which Linux is running are not exposed to user applications. The pins are used by the Linux kernel using device drivers to interact with devices.

    The purpose of export is to expose selected GPIO pins to user space as pseudo files allowing a user application to perform their own interactions with some hardware. Not all available or possible GPIO pins may be exposed. What pins can be exposed using export will depend on what /sys handlers have been inserted into the Linux kernel and what those handlers allow.

    What pseudo files are actually exposed and how those pseudo files are used will depend on the function of the GPIO pin, e.g. a digital pin versus an analog pin versus a pin that supports PWM or has pullup or pulldown resistors. What files are exposed will also depend on what functionality the handler for /sys/class/gpio/ provides. A GPIO pin may have a pullup or pulldown resistor that could be used but the handler may not provide an interface to manipulate it.

    A request to the export pseudo file will create a pseudo file directory representing the requested GPIO pin. This is done by writing a request to the export pseudo file with a message containing the data the export command needs in order to properly identify the GPIO pin requested. This message is then processed by the GPIO export sysfs handler in the Linux kernel to create the pseudo file folder representing the GPIO pin along with the pseudo files that provide the interface between the user application and the sysfs handler for the specified GPIO pin. The handler provides the layer between the physical GPIO pin and pin device driver and the pseudo file representation or interface.

    The unexport pseudo file removes the GPIO pin pseudo file so that interacting with the represented GPIO pin from a user application is no longer available.

    Note concerning PWM sysfs support: Just as there is support for GPIO pins through the sysfs interface and /sys there is also support for PWM pins. The root folder is /sys/class/pwm and the functionality is similar in architecture to that for GPIO pins. There is a similar export and unexport functionality to make the PWM pins available and using the exported PWM pseudo files are through standard file operations on a set of files associated with a pseudo file folder representing the PWM pin. See Using PMIC PWM on Dragonboard410c which describes the basics of "PWM is exposed via MPP_4 pin, which is pin 28 on the Low Speed Expansion Connector."

    The boot script changes

    The boot script changes use the /sys/class/gpio/export to create the requested GPIO pseudo file. However the created pseudo file has a set of default access permissions that are set when the pseudo file is created. Since the creation is during initialization with root privileges, the chmod command is used to allow any user application to interact with the created pseudo files and not just the user, root, which created them.

    Since the export is being done during boot up and initialization, the intent is to create GPIO pin pseudo files which will stay in place while the device is powered up and to stay in place as long as the device is in use.

    Each GPIO pins on the low power connector of the DragonBoard 410C are represented by several pseudo files, value which is used to communicate the value of the pin (whether it is high or low) and direction which is used to communicate the direction of the pin (whether it is an input pin or an output pin). So we need to do a chmod on each of these pseudo files we want the user application to access including the pseudo file folder in which these pseudo files are located, for example /sys/class/gpio/gpio938 which contains /sys/class/gpio/gpio938/value and /sys/class/gpio/gpio938/direction.