7. GPIOOperation Guide¶
7.1. Preparation¶
UseSDK ofkernelKernel
7.2. Operation Flow¶
GPIORelatedModuleDefaultalready Kernel,No need toExecuteLoadCommands
Through ExecuteGPIORead/writeCommands,orinKernel space/User space GPIOOperationProgram can
7.3. Operation Example¶
7.3.1. GPIOCommand-Line Operation Example¶
- Steps1:ExportGPIO
echo N > /sys/class/gpio/exportN = GPIO Value + Value
Example:GPIO1_2Pin(GPIO1 448 + 2 → N=450)
GPIO Table:
GPIO
Linux Value
GPIO0 (GPIOA)
480
GPIO1 (GPIOB)
448
GPIO2 (GPIOC)
416
GPIO3 (GPIOD)
384
PWR_GPIO (GPIOE)
352
- Steps2:ConfigurationGPIO
# SettingsisInputMode echo in > /sys/class/gpio/gpioN/direction # SettingsisOutputMode echo out > /sys/class/gpio/gpioN/direction
- Steps3:GPIORead/writeOperation
# ReadInputValue cat /sys/class/gpio/gpioN/value # Output echo 0 > /sys/class/gpio/gpioN/value # Output echo 1 > /sys/class/gpio/gpioN/value
- Steps4:ReleaseGPIOResources
echo N > /sys/class/gpio/unexport
Note
CONFIG_DEBUG_FSOptionafter,canThroughfollowingCommandsViewGPIO :
cat /sys/kernel/debug/gpio
7.3.2. Kernel-Space GPIO Operation Example¶
followingisCompleteofKernel space GPIO Operation Example,withcanLoadKernelModule Implementation。Examplewith
GPIO1_2( 448 + 2 = 450)as an example,ActualUse Please GPIO TableModify
GPIO_TEST_NUM MacroDefinition。ModuleLoadafter Execute GPIO Read/writeTestsandInterrupt ,
Uninstall ReleaseResources。
7.3.2.1. Header Files and Macro Definitions¶
#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
/* Example GPIO:GPIO1_2 = 448 + 2 */
#define GPIO_TEST_NUM 450
/* request_irq / free_irq of dev_id */
#define GPIO_IRQ_DEV_ID ((void *)GPIO_TEST_NUM)
7.3.2.2. Interruptcallback function¶
GPIO Kernel , before 。
static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
{
int val = gpio_get_value(GPIO_TEST_NUM);
printk(KERN_INFO "GPIO%d IRQ triggered, current value: %d\n",
GPIO_TEST_NUM, val);
return IRQ_HANDLED;
}
7.3.2.3. Module Initialization (GPIO Read/Write + Interrupt Registration)¶
insmod LoadModule Execute, stage: GPIO Output/InputRead/writeTests,
ConfigurationisInputModeand Interrupt。
static int __init gpio_drv_init(void)
{
int ret, irq_num, val;
/*
* stage :GPIO Read/writeTests
*/
/* Please GPIO Resources */
ret = gpio_request(GPIO_TEST_NUM, "gpio_test");
if (ret < 0) {
printk(KERN_ERR "gpio_request(%d) failed: %d\n",
GPIO_TEST_NUM, ret);
return ret;
}
/* ConfigurationisOutputMode, */
gpio_direction_output(GPIO_TEST_NUM, 0);
printk(KERN_INFO "GPIO%d set to output, initial value: 0\n",
GPIO_TEST_NUM);
/* Output and 1 seconds */
gpio_set_value(GPIO_TEST_NUM, 1);
mdelay(1000);
printk(KERN_INFO "GPIO%d set to HIGH\n", GPIO_TEST_NUM);
/* isInputModeandRead before */
gpio_direction_input(GPIO_TEST_NUM);
val = gpio_get_value(GPIO_TEST_NUM);
printk(KERN_INFO "GPIO%d switched to input, current value: %d\n",
GPIO_TEST_NUM, val);
/*
* stage :InterruptConfiguration
*/
/* will GPIO is IRQ Interrupt */
irq_num = gpio_to_irq(GPIO_TEST_NUM);
if (irq_num < 0) {
printk(KERN_ERR "gpio_to_irq(%d) failed: %d\n",
GPIO_TEST_NUM, irq_num);
gpio_free(GPIO_TEST_NUM);
return irq_num;
}
printk(KERN_INFO "GPIO%d mapped to IRQ %d\n",
GPIO_TEST_NUM, irq_num);
/* Interrupt:on + under */
ret = request_irq(irq_num, gpio_irq_handler,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
"gpio_test_irq", GPIO_IRQ_DEV_ID);
if (ret < 0) {
printk(KERN_ERR "request_irq(%d) failed: %d\n", irq_num, ret);
gpio_free(GPIO_TEST_NUM);
return ret;
}
printk(KERN_INFO "IRQ %d registered, waiting for trigger...\n",
irq_num);
return 0;
}
InterruptType Refer to:
|
Description |
|---|---|
|
on |
|
under |
|
|
|
|
|
Interrupt |
7.3.2.4. Module Unload (Resource Release)¶
rmmod UninstallModule Execute, ReleaseInterruptand GPIO Resources。
static void __exit gpio_drv_exit(void)
{
int irq_num = gpio_to_irq(GPIO_TEST_NUM);
/* ReleaseInterrupt */
free_irq(irq_num, GPIO_IRQ_DEV_ID);
/* Release GPIO */
gpio_free(GPIO_TEST_NUM);
printk(KERN_INFO "GPIO test driver unloaded\n");
}
7.3.2.5. Module Declaration¶
module_init(gpio_drv_init);
module_exit(gpio_drv_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Kernel GPIO read/write and interrupt example");
MODULE_AUTHOR("Test");
Note
Use
insmod gpio_test.koLoadModuleafter,ThroughdmesgView GPIO Read/writeandInterrupt 。GPIO Pin canin
dmesgin toInterrupt 。Use
rmmod gpio_testUninstallModule,Resources Release。
7.3.3. User-Space GPIO Operation Example¶
followingisCompleteofUser space GPIO Operation ExampleProgram,Through sysfs InterfaceImplementation GPIO ofExport、 Configuration、
Read/writeandRelease。Examplewith GPIO1_2( 448 + 2 = 450)as an example,ActualUse Please
GPIO TableModify GPIO_NUM MacroDefinition。
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5
6#define GPIO_NUM 450 /* Example GPIO:GPIO1_2 = 448 + 2 */
7
8/* Export GPIO,in /sys/class/gpio/ under gpioN Node */
9int gpio_export(int gpio)
10{
11 FILE *fp = fopen("/sys/class/gpio/export", "w");
12 if (fp == NULL) {
13 perror("open export failed");
14 return -1;
15 }
16 fprintf(fp, "%d", gpio);
17 fclose(fp);
18 /* Wait sysfs Node Complete, after Access direction/value Failure */
19 usleep(100000);
20 return 0;
21}
22
23/* Release GPIO,Delete /sys/class/gpio/gpioN Node */
24int gpio_unexport(int gpio)
25{
26 FILE *fp = fopen("/sys/class/gpio/unexport", "w");
27 if (fp == NULL) {
28 perror("open unexport failed");
29 return -1;
30 }
31 fprintf(fp, "%d", gpio);
32 fclose(fp);
33 return 0;
34}
35
36/* Settings GPIO :dir Valueis "in" or "out" */
37int gpio_set_direction(int gpio, const char *dir)
38{
39 char path[64];
40 snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", gpio);
41
42 FILE *fp = fopen(path, "w");
43 if (fp == NULL) {
44 perror("open direction failed");
45 return -1;
46 }
47 fprintf(fp, "%s", dir);
48 fclose(fp);
49 return 0;
50}
51
52/* Settings GPIO Output :value is 0( ) or 1( ) */
53int gpio_set_value(int gpio, int value)
54{
55 char path[64];
56 snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", gpio);
57
58 FILE *fp = fopen(path, "w");
59 if (fp == NULL) {
60 perror("open value for write failed");
61 return -1;
62 }
63 fprintf(fp, "%d", value);
64 fclose(fp);
65 return 0;
66}
67
68/* Read GPIO Input ,ReadResultThrough value Return */
69int gpio_get_value(int gpio, int *value)
70{
71 char path[64];
72 snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", gpio);
73
74 FILE *fp = fopen(path, "r");
75 if (fp == NULL) {
76 perror("open value for read failed");
77 return -1;
78 }
79 /* sysfs value File Return '0' or '1' */
80 char buf[2];
81 fread(buf, 1, 1, fp);
82 *value = atoi(buf);
83 fclose(fp);
84 return 0;
85}
86
87int main(void)
88{
89 int ret, value;
90
91 /* Steps1:Export GPIO */
92 ret = gpio_export(GPIO_NUM);
93 if (ret < 0)
94 exit(1);
95 printf("GPIO%d exported\n", GPIO_NUM);
96
97 /* Steps2:SettingsisOutputMode */
98 ret = gpio_set_direction(GPIO_NUM, "out");
99 if (ret < 0) {
100 gpio_unexport(GPIO_NUM);
101 exit(1);
102 }
103 printf("GPIO%d set to output\n", GPIO_NUM);
104
105 /* Steps3:Output and 1 seconds */
106 ret = gpio_set_value(GPIO_NUM, 1);
107 if (ret < 0) {
108 gpio_unexport(GPIO_NUM);
109 exit(1);
110 }
111 printf("GPIO%d output HIGH\n", GPIO_NUM);
112 usleep(1000000);
113
114 /* Steps4: isInputMode */
115 ret = gpio_set_direction(GPIO_NUM, "in");
116 if (ret < 0) {
117 gpio_unexport(GPIO_NUM);
118 exit(1);
119 }
120 printf("GPIO%d set to input\n", GPIO_NUM);
121
122 /* Steps5:ReadInput */
123 ret = gpio_get_value(GPIO_NUM, &value);
124 if (ret < 0) {
125 gpio_unexport(GPIO_NUM);
126 exit(1);
127 }
128 printf("GPIO%d input value: %d\n", GPIO_NUM, value);
129
130 /* Steps6:Release GPIO Resources */
131 ret = gpio_unexport(GPIO_NUM);
132 if (ret < 0)
133 exit(1);
134 printf("GPIO%d unexported\n", GPIO_NUM);
135
136 return 0;
137}