Linux GPIO 子系统
GPIO 子系统
From the hardware point of view, a GPIO is a functionality, a mode in which a pin can operate. From a software point of view, a GPIO is nothing but a digital line, which can operate as an input or output, and can have only two values: (1 for high or 0 for low). Kernel GPIO subsystems provide every function you can imagine to set up and handle GPIO line from within your driver:
从硬件的角度来看,GPIO 是一种功能,一种引脚可以操作的模式。 从软件的角度来看,GPIO 只不过是一条数字线,可以作为输入或输出操作,并 且只能有两个值:(1 表示高或 0 表示低)。 内核 GPIO 子系统提供了您可以想象的所有功能,可以在您的驱动程序中设置和处理 GPIO 线:
- Prior to using a GPIO from within the driver, one should claim it to the kernel. This is a way to take the ownership of the GPIO, preventing other drivers from accessing the same GPIO. After taking the ownership of the GPIO, one can:
- Set the direction
- Toggle its output state (driving line high or low) if used as output
- Set the debounce-interval and read the state, if used as input. For GPIO lines mapped to IRQ, one can define at what edge/level the interrupt should be triggered, and register a handler that will be run whenever the interrupt occurs.
There are actually two different ways to deal with GPIO in the kernel, as follows:
- The legacy and depreciated integer-based interface, where GPIOs are represented by integer
- The new and recommended descriptor-based interface, where a GPIO is represented and described by an opaque structure, with a dedicated API
The integer-based GPIO interface: legacy
The integer-based interface is the most well-known. The GPIO is identified by an integer, which is used for every operation that needs to be performed on the GPIO. The following is the header that contains legacy GPIO access functions:
#include
There are well known functions to handle GPIO in kernel.
Claiming and configuring the GPIO
One can allocate and take the ownership of a GPIO using the gpio_request() function:
static int gpio_request(unsigned gpio, const char *label)
gpio represents the GPIO number we are interested in, and label is the label used by the kernel for the GPIO in sysfs, as we can see in /sys/kernel/debug/gpio . You have to check the value returned, where 0 mean success, and negative error code on error. Once done with the GPIO, it should be set free with the gpio_free() function:
void gpio_free(unsigned int gpio)
If in doubt, one can use gpio_is_valid() function to check whether this GPIO number is valid on the system prior to allocate it:
static bool gpio_is_valid(int number)
Once we own the GPIO, we can change its direction, depending on the need, and whether it should be an input or output, using the gpio_direction_input() or gpio_direction_output() functions:
static int gpio_direction_input(unsigned gpio)
static int gpio_direction_output(unsigned gpio, int value)