Controlling GPIO from Linux User Space

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 STM32F429.

The API that is used to control GPIO is the standard Linux GPIOLIB interface. The API is described in the Linux documenation 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 STM32F4 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 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 two pins as GPIO, specifically:

  • PA0 is connected to the User Push button on the STM32F429 Discovery board;
  • PE3 is hand-wired to the User LED (LED_3) on my STM32F429 Discovery board.

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

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

/*
* Pin configuration for the User Push Button and User LEDs
* on the STM32F429 Discovery board.
* !!! That GPIO may have other connections on other boards.
*/
if (platform == PLATFORM_STM32_STM_DISCO) {

/* PA0 = User Push Button */
gpio_dsc.port = 0;
gpio_dsc.pin = 0;
stm32f2_gpio_config(&gpio_dsc, STM32F2_GPIO_ROLE_IN);

/* PE3 = LED_3
* Here, things are tricky. The default hardware routes
* the LED to a pin that interferes with RMII. The config
* below assumes that the RMII signal is disconnected from
* the LED and instead the LED is connected to the PE3 GPIO.
*/
gpio_dsc.port = 4;
gpio_dsc.pin = 3;
stm32f2_gpio_config(&gpio_dsc, STM32F2_GPIO_ROLE_OUT); 
}

If you need to define some other pins as GPIO, add appropriate code to the above section.

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

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

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

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

gpio = (bank * 16) + pin

Bank numbers start with 0 (corresponding to Bank A), pin numbers start with 0 (corresponding to pin 0, etc).

For the User Push Button the specific pin is PA0, which corresponds to the following GPIO number:

(0 * 16) + 0 = 0

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

/sys/class/gpio # echo 0 > export
/sys/class/gpio # echo in > gpio0/direction
/sys/class/gpio #

Now, all is ready to read the value of the User Push button. First, leave the button unpressed on the board and make sure the GPIO value reads as 0:

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

Push the button and make sure the GPIO value reads back as 1:

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

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

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

For the User LED the specific pin is PE3, which corresponds to the following GPIO number:

(4 * 16) + 3 = 67

Export the GPIO and define it as an output:

/sys/class/gpio # echo 67 > export
/sys/class/gpio # echo out > gpio67/direction

Now run the following shell commands to turn the LED on and off at a 1Hz frequency:

/sys/class/gpio # while busybox echo hey > /dev/null
do
> echo 1 > gpio67/value; sleep 1
echo 0 > gpio67/value; sleep 1
done

If you need to control GPIO from C / C++ code, it is probably a good idea to perform 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 asopenreadwrite, etc on gpioxx/value files to control your GPIO from C code.

Note: The GPIO interrupt capability allowing a user application to block on a GPIO IRQ using the POSIX pollinterface is not yet implemented in the STM32F4 BSP. If someone adds this capability to the BSP, we will be happy to review your code and integrate it to the kernel tree.

06-10
### GPIO Usage in Programming and Hardware Control General Purpose Input Output (GPIO) pins are programmable interface lines that allow microcontrollers or System on Chips (SoCs) to interact with external devices[^2]. These pins can be configured as either inputs or outputs, enabling communication between the SoC and peripheral hardware. Below is a detailed explanation of GPIO usage in both programming and hardware control. #### Configuration of GPIO Pins GPIO pins require configuration before they can be used effectively. This involves setting the direction (input or output), pull-up/pull-down resistors, and other attributes depending on the application requirements[^3]. In many embedded systems, this configuration is done through registers within the SoC. ```c // Example of configuring a GPIO pin as output in C #define GPIO_BASE 0x400FD000 // Base address of GPIO controller #define GPIO_DIR_OFFSET 0x00 // Offset for direction register #define GPIO_PIN 1 // Pin number to configure volatile unsigned int *gpio_dir = (unsigned int *)(GPIO_BASE + GPIO_DIR_OFFSET); *gpio_dir |= (1 << GPIO_PIN); // Set pin as output ``` The above code snippet demonstrates how to configure a specific GPIO pin as an output using direct memory access to the GPIO controller's registers[^4]. #### Reading and Writing to GPIO Pins Once configured, GPIO pins can be used to read input signals or write output signals. The following example illustrates reading from and writing to a GPIO pin in a simple embedded system. ```c #define GPIO_DATA_OFFSET 0x04 // Offset for data register volatile unsigned int *gpio_data = (unsigned int *)(GPIO_BASE + GPIO_DATA_OFFSET); // Write to GPIO pin *gpio_data |= (1 << GPIO_PIN); // Set pin high // Read from GPIO pin if (*gpio_data & (1 << GPIO_PIN)) { // Pin is high } else { // Pin is low } ``` This code snippet shows basic operations for controlling a GPIO pin, including setting it high and checking its state[^5]. #### Power Management Considerations for GPIO In low-power designs, such as those mentioned in the context of SoC design, power management plays a crucial role. For GPIO pins, techniques like clock gating and power gating can also apply to reduce unnecessary power consumption when pins are not actively being used[^6]. Ensuring that unused pins are set to a known state (e.g., pulled up or down) helps minimize leakage currents. ```python # Python example for interacting with GPIO via a library import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) pin = 18 GPIO.setup(pin, GPIO.OUT) # Configure pin as output GPIO.output(pin, GPIO.HIGH) # Set pin high state = GPIO.input(pin) # Read pin state print("Pin state:", state) GPIO.cleanup() # Cleanup GPIO settings ``` The provided Python example uses the RPi.GPIO library to interact with GPIO pins on a Raspberry Pi, demonstrating both setup and cleanup processes[^7].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值