Controlling GPIO from Linux User Space Print

 

 

This application note explains how to drive GPIO outputs and read the state of GPIO inputs from the Linux user-space on the LPC4357.

The API that is used to control GPIO is the standard Linux GPIOLIB interface. The API is described in the Linux documentation available in the kernel tree from the following file: linux/Documentation/gpio.txt.

Alternatively, the same document can be found in the Internet, for instance here:

http://lxr.free-electrons.com/source/Documentation/gpio/sysfs.txt


To enable the generic GPIO interface in the kernel, you need to enable certain build-time configuration options. Specifically, from the kernel configuration menu, go to Device Drivers, enable GPIO Support (CONFIG_GPIOLIB), and then from the GPIO Support menu enable the sysfs interface item (CONFIG_GPIO_SYSFS):

Now, most of the LPC4357 GPIO pins can be used in different multiplexed I/O roles (for instance, some GPIOs can be also configured as an UART interface, etc). Depending on specific requirements of your applications, you need to configure those pins that you want to use as GPIO for the GPIO role and other pins as an alternative I/O function.

For the purposes of this application note, we want to configure the following pin as GPIO:

  • GPIO4[8] is connected to the central key of the 5-key joystick push-button (SW7 on the LPC4357 Dev Kit).

In the LPC4357 kernel, the I/O functions of the LPC4357 pins are defined in the following file:
linux/arch/arm/mach-lpc18xx/iomux.c.

Here is the code that is responsible for configuring the above pin for the GPIO function:

#if defined(CONFIG_GPIOLIB) && defined(CONFIG_GPIO_SYSFS)
/* 5-key joystick (SW7) */
/* GPIO4[8] */
lpc18xx_pin_config(0xA, 1, LPC18XX_IOMUX_CONFIG_IN(0));
#endif

Having configured the kernel as described above, build the Linux image and load it to the LPC4357.

On the Linux running on the LPC4357 target, each GPIO is assigned a unique integer GPIO number within the GPIO chip range of 0 to 256:

~ # cd /sys/class/gpio
/sys/class/gpio # ls
export gpiochip0 unexport
/sys/class/gpio # cat gpiochip0/ngpio
256
/sys/class/gpio #

To calculate the GPIO number for a specific GPIO, use the following formula:

gpio = (bank * 32) + pin

Bank numbers start with 0, pin numbers start with 0.

For the joystick Push Button the specific pin is GPIO4[8], which corresponds to the following GPIO number:

(4 * 32) + 18 = 136

First step is to add (export) the pin to the GPIO array and define it as an input. This is done as follows:

/sys/class/gpio # echo 136 > export
/sys/class/gpio # echo in > gpio136/direction
/sys/class/gpio #

Now, all is ready to read the value of the joystick push-button. There is an external pull-up resistor on the joystick push-button GPIO so when unpressed the GPIO reads as 1:

/sys/class/gpio # cat gpio136/value
1
/sys/class/gpio # cat gpio136/value
1
/sys/class/gpio #

Push the button and make sure GPIO value reads as 0:

/sys/class/gpio # cat gpio136/value
0
/sys/class/gpio # cat gpio136/value
0
/sys/class/gpio #

Release the button and validate that the value has returned to 1:

/sys/class/gpio # cat gpio136/value
1
/sys/class/gpio # cat gpio136/value
1
/sys/class/gpio #

If you need to control GPIO from C / C++ code, it is probably a good idea to do the GPIO setup (export, define direction, etc) from a start-up script (eg. in /etc/rc). You can then use the standard POSIX APIs such as open, read, write, etc on gpioxx/value files to control your GPIO from C code.

Note: The GPIO interrupt capability allowing to block on a GPIO IRQ using the POSIX poll interface is not yet implemented in the LPC4357 BSP. If someone adds this capability to the BSP, we will be happy to review a patch and integrate it to the kernel tree.