泰山派开发板资料第三章中Buildroot系统使用文档中有各种功能的测试,其中包括GPIO测试,点亮LED需要GPIO引脚输出低电平
LED的正极连接板上的3V3,负极连接电阻然后接到开发板左列倒数第二个引脚上,即GPIO0_B7引脚
以下是使用文档中使用Shell控制GPIO的输出
# 使用root权限
rk3566_tspi:/$ su
# 将引脚号 15 导出为 GPIO 引脚,使其可以被访问和控制。
rk3566_tspi:/$ echo 15 > /sys/class/gpio/export
# 将引脚号 15 的方向设置为输出模式,即设置为输出引脚。
rk3566_tspi:/$ echo out > /sys/class/gpio/gpio15/direction
# 将引脚号 15 的值设置为 1,即将引脚设置为高电平。
rk3566_tspi:/$ echo 1 > /sys/class/gpio/gpio15/value
# 将引脚号 15 的值设置为 0,即将引脚置设置为低电平。
rk3566_tspi:/$ echo 0 > /sys/class/gpio/gpio15/value
# 将引脚号 15 解除导出,即取消对引脚号 15 的 GPIO 控制权。
rk3566_tspi:/$ echo 15> /sys/class/gpio/unexport
其中引脚ID是根据控制器(GPIO0),端口(B),索引序号(7)确定的
使用ls /sys/class/gpio
可以看见有gpiochip0 gpiochip32 gpiochip64 gpiochip96 gpiochip128
分别对应GPIO0-GPIO4
引脚ID的计算公式为:
控制器号32 + 端口号8 + 索引序号*1
所以GPIO0_B7为:32 x 0 + 1 x 8 + 7 x 1 = 15
以下是使用C语言实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
static char gpio_path[100];
static int gpio_config(const char *attr, const char *val);
int main(int argc, char* argv[])
{
int ret;
if(argc != 3)
{
fprintf(stderr, "usage:%s <gpio> <value>\n", argv[0]); //若argc 不为3说明给程序传入的参数不足两个,无法执行程序
exit(-1);
}
sprintf(gpio_path, "/sys/class/gpio/gpio%s", argv[1]); //导出的引脚的路径
if(access(gpio_path, F_OK)) //access函数:如果文件存在返回0,不存在返回-1
{
int fd, len;
fd = open("/sys/class/gpio/export", O_WRONLY);
if(fd < 0)
{
perror("open error");
return -1;
}
len = strlen(argv[1]);
if(write(fd, argv[1], len) != len) //write函数第一个参数为要写入的位置,第二个参数为要写入的内容,第三个参数是内容的字节数,如果执行成功返回值为内容的字节数
{
perror("write error");
close(fd);
exit(-1);
}
close(fd);
}
ret = gpio_config("direction", "out");
if(ret != 0)
{
fprintf(stderr, "gpio_config error1");
exit(-1);
}
ret = gpio_config("active_low", "0");
if(ret != 0)
{
fprintf(stderr, "gpio_config error2");
exit(-1);
}
ret = gpio_config("value", argv[2]);
if(ret != 0)
{
fprintf(stderr, "gpio_config error3");
exit(-1);
}
exit(0);
}
static int gpio_config(const char *attr, const char *val)
{
char file_path[100];
int len, fd;
sprintf(file_path, "%s/%s", gpio_path, attr);
fd = open(file_path, O_WRONLY);
if(fd < 0)
{
perror("open error2");
return -1;
}
len = strlen(val);
if(write(fd, val, len) != len)
{
perror("write error2");
close(fd);
return -1;
}
close(fd);
return 0;
}
交叉编译工具
我是使用ubuntu虚拟机编译后使用scp上传到泰山派执行
ubuntu中下载交叉编译工具可以使用sudo apt install gcc-arm-linux-gnueabihf
安装完成后使用arm-linux-gnueabihf-gcc ./test.c -o test -static
命令交叉编译
注意这里有的要加上-static
我刚开始编译时没有使用-static
,结果上传到泰山派上执行的时候报错No such file or directory
上网查说是由于交叉编译器的差异,不同的交叉编译器链接的动态库内容相同但是路径不同,所以会提示找不到文件
所以使用静态链接编译
在ubuntu上使用gcc来编译后上传到泰山派运行会提示无法执行二进制文件,所以需要使用交叉编译器
Shell命令参考泰山派Buildroot使用文档
C语言代码参考:
正点原子阿尔法控制GPIO输出高低电平
交叉编译参考:
Linux交叉编译
编译报错参考:
交叉编译器差异 - 执行可执行文件提示"No such file or directory"