在《玩转DragronBoard 410c系列之三:使用Shell控制GPIO》这篇文章中,我们介绍了如何使用Shell指令去控制GPIO,这一篇我们讲讲用代码控制GPIO,这里以C语言举例说明。
点亮LED
依旧是先易后难的原则,在Linux系统创建一个文件,命名为blink.c,然后打开该文件,输入如下代码。这段代码的含义是对LED4进行点亮、熄灭操作,间隔1s,总计10个循环。
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
//defining the path to the file in the filesystem that controls the LED
#define LED4 "/sys/class/leds/apq8016-sbc:green:user4/brightness"
int main(void)
{
//opening the brightness-file
int led4_fd = open(LED4, O_WRONLY);
if(led4_fd < 0)
{
printf("Could not open File: %s", LED4);
return 0;
}
int i;
for( i=0; i<10;i++)
{
write(led4_fd, "1", 2 ); //Turning the LED ON by writing 1 into the brightness file
sleep(1); // sleep 1 second in linux
write(led4_fd, "0", 2 ); //Turning the LED OFF by writing 0 into the brightness file
sleep(1);
}
close(led4_fd);
printf("OK");
}
然后使用交叉编译器编译这个文件,命令为“aarch64-none-linux-gnu-g++ blink.c -o blink.arm”,接着我们将“blink.arm”通过FTP上传到嵌入式板卡中,使用root权限运行。最后我们就能看到LED4在交替闪烁了。
控制GPIO
下面的代码描述了,读取GPIO-A的状态以及设置GPIO-B的值为1,编译方法同上。
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
void initGpio(int pin)
{
FILE * fp =fopen("/sys/class/gpio/export","w");
if (fp == NULL)
{
perror("export open filed");
}
else
{
fprintf(fp,"%d",pin);
}
fclose(fp);
}
// direction="in" or "out"
void setGpioDirection(int pin,char *direction)
{
char path[100] = {0};
sprintf(path,"/sys/class/gpio/gpio%d/direction",pin);
FILE * fp =fopen(path,"w");
if (fp == NULL)
{
perror("direction open filed");
}
else
{
fprintf(fp,"%s",direction);
}
fclose(fp);
}
int getGpioValue(int pin)
{
char path[128];
char value_str[3];
int fd;
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_RDONLY);
if (fd < 0)
{
perror("Failed to open gpio value!");
return -1;
}
if (read(fd, value_str, 3) < 0)
{
perror("Failed to read value!");
return -1;
}
close(fd);
return (atoi(value_str));
}
void setGpioValue(int pin,int value)
{
char path[128];
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);
FILE * fp =fopen(path,"w");
if (fp != NULL)
{
fprintf(fp,"%d",value);
}
else
{
perror("Failed to open gpio value!");
}
fclose(fp);
}
int main()
{
int gpio_a=36+390;
int gpio_b=12+390;
// read GPIO_A vale
initGpio(gpio_a);
setGpioDirection(gpio_a,"in");
printf("%d\n",getGpioValue(gpio_a));
// set GPIO_B vale=1
initGpio(gpio_b);
setGpioDirection(gpio_b,"out");
setGpioValue(gpio_b,1);
return 0;
}
总结
通过这篇文章,我们可以通过代码的方式控制GPIO,但是我们也发现两个问题。第一,我们习惯使用编译器开发程序,而该文章使用命令行方式编译,不方便,那么有没有合适的编译器呢。我这里推荐两款编译器,一款是Eclipse,另一款是QT Creator。无论哪种编译器,都需要使用交叉编译工具链,下个章节我们介绍下如何交叉编译QT Creator。第二个问题是,控制GPIO需要GPIO的导出号,有没有一个通用库帮我们实现物理引脚与导出号的映射,官方推荐的是MRAA。我也会在以后的博客中介绍。
文章评论