Search This Blog

Access GPIO from Linux user space

GPIO mean "General Purpose Input/Output" and is a special pin present in some chip that can be set as input or output and used to move a signal high or low (in output mode) or to get the signal current status (in input mode). Usually these pin are directly managed by kernel modules but there are an easy way to manage these pins also from user space.

Standard Linux kernel have inside a special interface allow to access to GPIO pins. Once executed kernel menuconfig you can easily verify is this interface is active in your kernel and, in case, enable them. The kernel tree path is the following:

If not, enable this feature and recompile the kernel before continue to read. The interface to allow working with GPIO is at the following filesystem path:

/sys/class/gpio/

Basically if you want to work with a particular GPIO you must first to reserve it, set the input/output direction and start managing it. Once you reserved the GPIO and finished to use you need to free it for allow other modules or process to use them. This rule is valid in both cases you want to use GPIO from kernel level or user level.

Manage GPIO from command line or script

From the user level side this "operation" for reserve the GPIO is called "export" the GPIO. For make this export operation you simply need to echo the GPIO number you are interested to a special path as follow (change XX with the GPIO number you need):

echo XX > /sys/class/gpio/export

If operation successful (the possible case of operation failed is explained below) a new "folder" will show up in the GPIO interface path as example below:

/sys/class/gpio/gpioXX/

This new "folder" will allow you to work with the GPIO you just reserved. In particular if you want to set the in/out direction you simply need to execute the following echo commands:

echo "out" > /sys/class/gpio/gpioXX/direction

or

echo "in" > /sys/class/gpio/gpioXX/direction

In case you set out direction you can directly manage the value of GPIO. You can make this operation by executing additional echo commands like:

echo 1 > /sys/class/gpio/gpioXX/value

or

echo 0 > /sys/class/gpio/gpioXX/value

Since GPIO is a single pin the possible states allowed are high (1) and low (0). In case you set in direction you can read the current pin value by using the following command:

cat /sys/class/gpio/gpioXX/value

Once finished to use your GPIO you can free it by make the same echo command but to different path:

echo XX > /sys/class/gpio/unexport

In case of GPIO folder not showed after export operation is very likely that the GPIO is already reserved by some module. For verify the current reserved GPIO map you must first verify if in your kernel is enabled the following feature:

Kernel configuration ---> Kernel hacking ---> Debug FS

As usual, if not enabled, enable it and recompile the kernel. The next step is to launch the following command line for mount debugfs:

mount -t debugfs none /sys/kernel/debug

and dump the current GPIO configuration by using:

cat /sys/kernel/debug/gpio

The output will show you the current list og reserved GPIO.

Manage GPIO from application

All these same operations can be made using a software application. Follow short lines of C code showing how the reproduce the same steps as above (remember to change XX with the GPIO number you want to use).

An important note you have to keep in mind if you plan to set or, more important, get the value of a GPIO through this way in continous mode. If you open the "value" file for get the current GPIO status (1 or 0) remember that, after the fist read operation, the file pointer will move to the next position in the file. Since this interface was made to be read from cat command the returned string will be terminated by the new line character (\n). This mean after the first "valid" read all the next read operation will return always the last character in the file, in this case only the new line '\n'. For obtain a correct status value for each read operation you simply have to set the file pointer at the beginning of the file before read by using the command below:

lseek(fp, 0, SEEK_SET);

You will not have this problem if you open and close GPIO value file every time you need to read but, as you can know, for continuous read introduce a short delay. Since these short lines of codes are only an example if you want to use
them in your code remember add the control for error in open GPIO file.

Surely not at user level. You need to develop your own module running at kernel level for manage interrupt. Regarding the possibilty to have interrupt connected to gpio it depends from your hardware. If the cpu will allow it you'll have to configure it as indicated by datasheet.

can you help me?i have a raspberry pi b + as a webserver, i can remotely get to it, push the button and i get 2 errors in the apache log files, permissions denied and premature end of script. i dont know if i have a httpd.conf file and i dont know if i need to change something in .htaccess but also please tell me real fast, if this set01.cgi script looks ok

httpd.conf and .htaccess doesn't seem to be connected to the gpio access. The error "permission denied" mean your script is executed under some user that doesn't have enough privileges to access gpio fields. The easiest solution in this case is to "extened" permission of "/sys/class/gpio/gpio4/value" to the user or the group you currently run your script (using chmod command in server side).

@Russ M: this post explain the standard direct interface for access GPIO from user space. PWM, for what I know, is another type of interface so I guess you need to manage the GPIO internally to kernel if you want to use PWM interface (but I'm not expert in using it than I'm not sure about that).

Hi,Excellent article. How can I find out which module has reserved a reserved gpio.I executed "cat /sys/kernel/debug/gpio". I have posted a portion of the output below.GPIOs 148-178, GPH: gpio-162 (? ) in lo gpio-163 (? ) in lo gpio-164 (? ) in lo gpio-165 (? ) in lo

Sorry, don't understand the question, what does it mean "how they are enabled here"? Remeber GPIO export operation can be "requested" not only by user space as described in this post but also internally by some kernel module itself...

The problem here is only to know how to "calculate" the correct GPIO number based to your hardware. I don't know if your calculation is correct since it depends by the chipset you are working on. You have to check the datasheet of the chipset for know if the GPIO number is correct. Once got the correct number the export procedure is the same.

Teorically you can't since usually GPIO are physically harware mapped and the kernel report this mapping status. The only way I can see is to patch the kernel GPIO driver to make an "software inversion" but it would not be a good idea in any case. Please note if you want to manage an I2C bus communication from user space using kernel GPIO interface the communication will be really slow...

The kernel is "customized" to work on your hardware. Maybe it will be possible to find some general tutorial (however I don't know) but the only way you have is to look into your kernel sources for find the module involved in GPIO communication with your hardware. Once found work on it.

thanks for this valuable articlei used the following commands to access the gpio on SAM9G25 microcontroller:#echo 66 > /sys/class/gpio/export#echo in > /sys/class/gpio/gpio66/direction#cat /sys/class/gpio/gpio66/value----------------these commands run successfully on a linux with kernel version 3.6.9BUTit doesn't work on the same development kit when I run emdebian with kernel version 3.11.6I got#echo in > /sys/class/gpio/gpio66/direction-bash: /sys/class/gpio/gpio66/direction: No such file or directory

Kernel need to be "configured" to manage correctly specific board GPIO and expose them through gpio module interface. Required configuration can come from kernel board pinmuxing map, gpio module configuration and so on, I can not know the reasons, you have to check and configure correctly the kernel you plan to use for your project based to your hardware...

Thank you for the comment. About i2c didn't write anything because is already possible to found some good aricle around than I thought there was no need. Maybe I'll write something in the future... ^_^

Great article.... helped me a lot for lemaker board. Recently only i started working on linux on lemaker board. now i am trying for interrupts, but i am not getting ..please guide me for complete interrupt part. led blinking need to do with switch in interrupt method.

This article explain how to manage with GPIO from user space but infortunately is not possible manage interrupts from user space. The only way is to develop a kernel driver. There is a free book titled "Linux device drivers" that you can read about develop your driver.

i found your article very helpful thanks for writing it. I want to blink the leds on the zed board, so when i tried the method the gpioxx folder is not created for me so i tried mount -t debugfs none /sys/kernel/debug but found that there is no debud folder in the kernel....any help will be appreciated.

Unfortunately linux kernel continuously change in structure based on distribution and so on. If you don't get your GPIO probably mean some driver reserved it or the use of that GPIO is not configured in your kernel. Kernel for ARM have to be configured through specific configuration files instructing the kernel itself about available devices in specific hardware. I can not help you in this case since variants can be infinite, you have to look into your kernel sources for try to understand why this specific GPIO is not allowed to be exported...

Why "mount -t sysfs sysfs /sys"? The correct path for mount is "mount -t debugfs none /sys/kernel/debug". However keep in mind that you'll probably have to change something in the kernel code to have your GPIO available from user space...

Post a Comment

Popular posts from this blog

If you want to launch an Android app from shell command line terminal there is a simply command allow to do that but you have to know some info about the app you want to execute. The command is named am and is basically a command line interface to the system ActivityManager.

Once finished to develop your application using the great Qt libraries the next step will be release phase. Here you need to provide in addition of the main executable all the dll libraries dependencies required by your application to run. Basically, since the application was developed using Qt, the dependencies will be only Qt dll and some few dll connected to the compiler used.