Controlling GPIO from Linux User Space |
This application note shows how to control STM32F7 GPIOs from the user level using the standard Linux GPIOLIB interface.
The generic GPIO interface is controlled by the CONFIG_GPIOLIB kernel option enabled by default in the rootfs project installed to each STM32F7 System-on-Module shipped by Emcraft. Most of the STM32 GPIO pins can be used in different multiplexed I/O roles (for instance, some GPIO pins can be also configured as an SPI interface, etc). Depending on the requirements of your application, you need to configure the pins that you want to use as GPIO for the GPIO role and other pins for an alternative I/O function. In this application note, we configure the following two pins as GPIO:
The pin multiplexing, as well as the GPIO specific configuration, is performed by the Linux kernel drivers using the information from the rootfs.dts.STM32F7 file. Let's edit this file and add the information about the above two GPIOs:
/ { After applying the above changes to the rootfs.dts.STM32F7 file, rebuild the rootfs project (Building Linux) and install it on the target (Installing Linux Images to Flash). Ignore the following error message reported from the resultant rootfs.uImage during the boot: gpio-keys-polled inputs: missing platform data This message is expected due to the following:
Each GPIO is assigned a unique integer GPIO number within the GPIO chip range of 0 to 175 by Linux. To calculate that number for a specific GPIO, use the following formula: gpio = (bank * 16) + pin Bank numbers start with 0 (corresponding to Bank A, etc), pin numbers start with 0 (corresponding to pin 0, etc). For the User Push Button the specific pin is PH2, which corresponds to the following GPIO number: (7 * 16) + 2 = 114 The first step is to add (export) the pin to the GPIO array and define it as an input. This is done as follows: / # echo 114 > /sys/class/gpio/export Now, all is ready to read the value of the User Push Button. First, leave the button unpressed on the board and read the signal. We enabled pull-up for this GPIO in rootfs.dts.STM32F7 (see the S2.but node), so when the User Push Button unpressed this GPIO reads as 1: / # cat /sys/class/gpio/gpio114/value Push the button and make sure the GPIO value reads as 0: / # cat /sys/class/gpio/gpio114/value Release the button and validate that the value has returned to 1: / # cat /sys/class/gpio/gpio114/value For the User LED the specific pin is PG9, which corresponds to the following GPIO number: (6 * 16) + 9 = 105 Export the GPIO and define it as an output: / # echo 105 > /sys/class/gpio/export Now run the following shell commands to turn the User LED on and off at a 1Hz frequency: / # while [ 1 ]; do echo 1 > /sys/class/gpio/gpio105/value; sleep 1; echo 0 > /sys/class/gpio/gpio105/value; sleep 1; done Stop this test by pressing Ctrl-C, and run a composite test: control the User LED with the User Push Button (turn the LED on if the Button is unpressed, and turn the LED off if the Button is pressed): / # while [ 1 ]; do cat /sys/class/gpio/gpio114/value > /sys/class/gpio/gpio105/value; done
In Linux, you may access GPIOs using different approaches, not only the ones described in this application note above. Here are some external links that might be usefull if you decide to try an alternative approach. The following article describes accessing GPIOs from the kernel context: To work with GPIOs from the user space, there are the following possibilities:
|