ARM40-A5D27应用程序——GPIO输出
Linux内核4.8版本后,提供了新的GPIO字符驱动接口gpiod;若内核版本不支持gpiod的方式,则需要使用GPIO sysfs interface接口,见《ARM40-A5应用程序——GPIO输出高低电平》的示例。
更本文测试板为ARM40-A5D27.
一、在shell中测试
//Set PB13 output high:
# gpioset gpiochip0 45=1
//Set PB13 output low:
# gpioset gpiochip0 45=0
二、 设置GPIO的值
文件名为 test_gpio_output.c,代码见本文附录(1)。
测试DO1~DI10等10个gpio的状态。
三、交叉编译
arm-linux-gnueabihf-gcc -o test_gpio_output test_gpio_output.c
四、执行程序
将交叉编译得到的 test_gpio_output 文件拷贝到ARM40-A5D27板中,执行程序:
./test_gpio_output
用示波器可观察对应IO上的电平是否每2s改变一次。
参考文章:
https://cybertale.github.io/2018/08/15/ELCE-2017-新的用户空间GPIO接口.html
https://microchipdeveloper.com/32mpu:apps-gpio
http://wiki.i2som.com/pages/viewpage.action?pageId=29655687
http://bluequiet.blogspot.com/2019/09/gpio-gpiohandlerequest-gpiochip.html
http://www.dydata.cc/Admin/ShowFile/%60Linux%60kernel%60linux-5%7C0%60tools%60gpio%60gpio-event-mon%7Cc
https://cregit.linuxsources.org/code/4.8/tools/gpio/gpio-hammer.c.html
http://tomoyo.osdn.jp/cgi-bin/lxr/source/tools/gpio/lsgpio.c?v=linux-4.7.10
https://framagit.org/cpb/ioctl-access-to-
gpio/commit/bbde7780f1ae12fba3836c21062baea4b0546e85
荟聚计划:共商 共建 共享 Grant
附:
(1)test_gpio_output.c代码:
// test for gpio input
// 128 gpio in gpiochip0
// 0 ~ 31 PA0 -> PA31
// 32 ~ 63 PB0 -> PB31
// 33 ~ 95 PC0 -> PC31
// 96 ~ 127 PD0 -> PD31
#define DO_LINES 10
#define DO1 45 //PB13
#define DO2 46 //PB14
#define DO3 47 //PB15
#define DO4 48 //PB16
#define DO5 49 //PB17
#define DO6 50 //PB18
#define DO7 51 //PB19
#define DO8 52 //PB20
#define DO9 53 //PB21
#define DO10 54 //PB22
#define DEV_GPIO "/dev/gpiochip0"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <linux/gpio.h>
#include <sys/ioctl.h>
int main(int argc, char *argv[])
{
int fd;
int ret;
struct gpiohandle_request req;
struct gpiohandle_data data;
/* open gpio */
fd = open(DEV_GPIO, 0);
if (fd < 0) {
printf("ERROR: open %s ret=%d\n", DEV_GPIO, fd);
return -1;
}
req.lineoffsets[0] = DO1;
req.lineoffsets[1] = DO2;
req.lineoffsets[2] = DO3;
req.lineoffsets[3] = DO4;
req.lineoffsets[4] = DO5;
req.lineoffsets[5] = DO6;
req.lineoffsets[6] = DO7;
req.lineoffsets[7] = DO8;
req.lineoffsets[8] = DO9;
req.lineoffsets[9] = DO10;
req.lines = DO_LINES;
req.flags = GPIOHANDLE_REQUEST_OUTPUT; // Request lines as output
strcpy(req.consumer_label, "do-output");
ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
if (ret < 0) {
printf("Failed to issue GPIO_GET_LINEHANDLE_IOCTL(%d)\n", ret);
close(fd);
return -1;
}
for(int i=0; i < DO_LINES; i++)
data.values[i] = 0;
ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
if (ret < 0) {
printf("Failed to issue GPIOHANDLE_GET_LINE_VALUES_IOCTL(%d)\n", ret);
close(fd);
return -1;
}
while (1) {
// set DOx low
for(int i=0; i < DO_LINES; i++)
data.values[i] = 0;
ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
sleep(2);
// set DOx high
for(int i=0; i < DO_LINES; i++)
data.values[i] = 1;
ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
sleep(2);
}
close(fd);
return 0;
}