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/export
  • N = 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

IRQF_TRIGGER_RISING

on

IRQF_TRIGGER_FALLING

under

IRQF_TRIGGER_HIGH

IRQF_TRIGGER_LOW

IRQF_SHARED

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.ko LoadModuleafter,Through dmesg View GPIO Read/writeandInterrupt 。

  • GPIO Pin canin dmesg in toInterrupt 。

  • Use rmmod gpio_test UninstallModule,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}