2025-03-20
从用户空间访问GPIO也是比较常用的功能。下面的例子就演示了如何在Linux用户空间访问GPIO,并控制其引脚电平。
raspberry pi3b
Linux raspberrypi 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux
// simple.c
#include <assert.h>
#include <fcntl.h>
#include <linux/gpio.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
struct gpiohandle_request led, button;
struct gpiohandle_data data;
int status = 0;
int fd = open("/dev/gpiochip0", O_RDWR);
assert(fd >= 0);
// 设置GPIO 16为输出
led.flags = GPIOHANDLE_REQUEST_OUTPUT;
strcpy(led.consumer_label, "LED");
memset(led.default_values, 0, sizeof(led.default_values));
led.lines = 1; // 设置引脚个数
led.lineoffsets[0] = 16;
assert(ioctl(fd, GPIO_GET_LINEINFO_IOCTL, &led) >= 0);
// 设置GPIO 17为输入
button.flags = GPIOHANDLE_REQUEST_INPUT;
strcpy(button.consumer_label, "BUTTON");
memset(button.default_values, 0, sizeof(button.default_values));
button.lines = 1; // 设置引脚个数
button.lineoffsets[0] = 17;
assert(ioctl(fd, GPIO_GET_LINEINFO_IOCTL, &button) >= 0);
printf("Led fd: %d, Button fd: %d\n", led.fd, button.fd);
// 设置Led GPIO输出高电平
data.values[0] = 1;
if(ioctl(led.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data) < 0) {
perror("ioctl Led error");
status = -1;
goto end;
}
// 获取Button GPIO电平
if(ioctl(button.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data) < 0) {
perror("ioctl Button error");
status = -1;
goto end;
}
printf("Buttion is %s\n", (data.values[0] > 0) ? "pressed" : "not pressed");
sleep(2);
end:
close(fd);
close(led.fd);
close(button.fd);
return status;
}
#!/bin/sh
all: simple.c
gcc -g -o simple simple.c
clean:
-rm simple