7. GPIO操作指南

7.1. GPIO的操作准备如下:

  • 使用SDK发布的kernel

7.2. 操作过程

  • 默认GPIO相关模块已全部编入内核,不需要再执行加载命令。

  • 在控制台下运行GPIO读写命令或者自行在内核态或者用户态编写GPIO读写程序,就可以对GPIO进行输入输出操作。

7.3. 操作示例

7.3.1. GPIO操作命令示例:

步骤1: 在控制台使用echo命令, 指定待操作的GPIO编号N:

echo N > /sys/class/gpio/export

N为待操作的GPIO编号,GPIO编号 = GPIO组号值 + 偏移值.

以原理图中GPIO1_2管脚为例, GPIO1对应GPIO组号值448, 偏移值为2.

因此GPIO编号N为448 + 2 = 450

组号值对应如下:

GPIO0 对应linux组号值为 480
GPIO1 对应linux组号值为 448
GPIO2 对应linux组号值为 416
GPIO3 对应linux组号值为 384
PWR_GPIO 对应linux组号值为 352

echo N > /sys/class/gpio/export 之后, 生成/sys/class/gpio/gpioN目录

步骤2: 在控制台使用echo命令设置GPIO方向:

设置为输入:echo in > /sys/class/gpio/gpioN/direction

设置为输出:echo out > /sys/class/gpio/gpioN/direction

例: 设置GPIO1_2 (即编号450)方向为输入:
echo in > /sys/class/gpio/gpio450/direction
设置GPIO1_2 (即编号450)方向为输出:
echo out > /sys/class/gpio/gpio450/direction

步骤3: 在控制台使用cat命令查看GPIO输入值, 或使用echo命令设置GPIO输出值:

查看输入值: cat /sys/class/gpio/gpioN/value

输出低:echo 0 > /sys/class/gpio/gpioN/value

输出高:echo 1 > /sys/class/gpio/gpioN/value

步骤4: 使用完毕后, 在控制台使用echo命令释放资源:

echo N > /sys/class/gpio/unexport

注:可以通过打开 CONFIG_DEBUG_FS 选项开启gpio的sysfs debug功能,在操作前通过如下命令查看gpio pin具体对应的组号值:

cat /sys/kernel/debug/gpio

7.3.2. 内核态GPIO操作程序示例:

内核态GPIO读写操作程序示例:

步骤1: 注册GPIO:

gpio_request(gpio_num, NULL);

gpio_num为要操作的GPIO编号,该编号等于”GPIO组号 + 组内偏移号”

步骤2: 设置GPIO方向:

对于输入:gpio_direction_input(gpio_num)
对于输出:gpio_direction_output(gpio_num, gpio_out_val)

步骤3: 查看GPIO输入值或设置GPIO输出值:

查看输入值: gpio_get_value(gpio_num);
输出低:gpio_set_value(gpio_num, 0);
输出高:gpio_set_value(gpio_num, 1);

步骤4: 释放注册的GPIO编号:

gpio_free(gpio_num);

内核态GPIO中断操作程序示例:

步骤1: 注册GPIO:

gpio_request(gpio_num, NULL);

gpio_num为要操作的GPIO编号,该编号等于”GPIO组号 + 组内偏移号”

步骤2: 设置GPIO方向:

gpio_direction_input(gpio_num);

对于要作为中断源的GPIO引脚,方向必须配置为输入对于输出

步骤3: 映射操作的GPIO编号对应的中断号:

irq_num = gpio_to_irq(gpio_num);

中断号为gpio_to_irq(gpio_num)的返回值

步骤4: 注册中断:

request_irq(irq_num, gpio_dev_test_isr, irqflags, "gpio_dev_test",&gpio_irq_type))

Irqflags为需要注册的中断类型,常用类型为:

IRQF_SHARED :共享中断;

IRQF_TRIGGER_RISING :上升沿触发;

IRQF_TRIGGER_FALLING :下降沿触发;

IRQF_TRIGGER_HIGH :高电平触发;

IRQF_TRIGGER_LOW :低电平触发

步骤5: 结束时释放注册的中断和GPIO编号:

free_irq(gpio_to_irq(gpio_num), &gpio_irq_type);
gpio_free(gpio_num);

7.3.3. 用户态GPIO操作程序示例:

用户态GPIO读写操作程序示例:

步骤1: 将要操作的GPIO编号export:

fp = fopen("/sys/class/gpio/export", "w");
fprintf(fp, "%d", gpio_num);
fclose(fp);

gpio_num为要操作的GPIO编号,该编号等于”GPIO组号 + 组内偏移号”

步骤2: 设置GPIO方向:

fp = fopen("/sys/class/gpio/gpio%d/direction", "rb+");
对于输入:fprintf(fp, "in");
对于输出:fprintf(fp, "out");

fclose(fp);

步骤3: 查看GPIO输入值或设置GPIO输出值:

fp = fopen("/sys/class/gpio/gpio%d/direction", "rb+");
查看输入:fread(buf, sizeof(char), sizeof(buf) - 1, fp);
输出低:
   strcpy(buf, “0”);
   fwrite(buf, sizeof(char), sizeof(buf) - 1, fp);
输出高:
   strcpy(buf,“1”);
   fwrite(buf, sizeof(char), sizeof(buf) - 1, fp);

步骤4: 将操作的GPIO编号unexport:

fp = fopen("/sys/class/gpio/unexport", "w");
fprintf(fp, "%d", gpio_num);
fclose(fp);