D1开发板操作gpio端口的简单方法以及ADB的连接方法
-
准备操作
作为一名萌新,在如何操作gpio端口上,历经千辛万苦,查阅各种资料。
首先是根据同样是发布在平头哥开发社区的博文,链接如下 https://bbs.aw-ol.com/topic/349/ 是文件操作gpio端口,代码易读懂,但是代码量太大了。对有些部分,像是打开文件,进行读写操作的一块进行,可以简化一些,但是要控制多个gpio端口,还要多次复用,实在是不好用。所以在写完小车动起来的程序后,就想着有没有更简单的方式。
找到了官方提供的gpio开发指南,利用的是设备树和Pinctrl和gpio子系统操作gpio,花了两天时间终于弄了个大概明白,想上手开始做,发现没找到一个完整的案例,不知如何入手。
于是搜搜查查,最后回归了简单的终端操作,将终端操作用命令和shell脚本来操作方便同时操作多个gpio端口。更简单了,但是没学过脚本语言,准备开始学习基本知识的时候,发现了一篇博文,什么都解决了。
链接如下:点这个理
C语言代码里操作gpio
此文里面有一个板块为C语言代码里操作gpio,代码短短几行,用了system()函数来操作echo等,很类似终端操作,但又更方便了。 于是操作gpio变成了这样
- 将大部分操作宏定义
#define EXPORT_GPIO2 "echo 2020 > /sys/class/gpio/export" #define EXPORT_GPIO3 "echo 2021 > /sys/class/gpio/export" #define EXPORT_GPIO4 "echo 2022 > /sys/class/gpio/export" #define UEXPORT_GPIO1 "echo 2027 > /sys/class/gpio/unexport" #define UEXPORT_GPIO2 "echo 2020 > /sys/class/gpio/unexport" #define UEXPORT_GPIO3 "echo 2021 > /sys/class/gpio/unexport" #define UEXPORT_GPIO4 "echo 2022 > /sys/class/gpio/unexport" #define GPIO1_OUTPUT "echo out > /sys/class/gpio/gpio2027/direction" #define GPIO2_OUTPUT "echo out > /sys/class/gpio/gpio2020/direction" #define GPIO3_OUTPUT "echo out > /sys/class/gpio/gpio2021/direction" #define GPIO4_OUTPUT "echo out > /sys/class/gpio/gpio2022/direction" #define LOWGPIO1 "echo 0 > /sys/class/gpio/gpio2027/value" #define LOWGPIO2 "echo 0 > /sys/class/gpio/gpio2020/value" #define LOWGPIO3 "echo 0 > /sys/class/gpio/gpio2021/value" #define LOWGPIO4 "echo 0 > /sys/class/gpio/gpio2022/value"
- 一些操作语句,简单明了
void INIT() { system(EXPORT_GPIO1); system(EXPORT_GPIO2); system(EXPORT_GPIO3); system(EXPORT_GPIO4); system(EXPORT_HW1); system(EXPORT_HW2); system(EXPORT_HW3); system(EXPORT_HW4); system(GPIO1_OUTPUT); system(GPIO2_OUTPUT); system(GPIO3_OUTPUT); system(GPIO4_OUTPUT); system(HW1_INPUT); system(HW2_INPUT); system(HW3_INPUT); system(HW4_INPUT); } void RUN() { system(LOWGPIO1);//0 system(HIGHGPIO2);//1 system(HIGHGPIO3);//1 system(LOWGPIO4);//0 }
- 但是由于没有办法system(cat...),得到value的值只能用文件方式来读出,但也将代码简化了很多。
int GETHW(int gpio) { char in[3] = {0, 0, 0}; char buf[50]; int nread, gpiofd; sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio); gpiofd = open(buf, O_RDWR); if(gpiofd < 0) { fprintf(stderr, "Failed to open gpio %d value\n", gpio); perror("gpio failed"); } do { nread = read(gpiofd, in, 1); } while (nread == 0); if(nread == -1){ perror("GPIO Read failed"); return -1; } close(gpiofd); return atoi(in); }
D1开发板的gpio引脚
我们项目的小车选用的是gpio2020~gpio2027这八个gpio引脚,其中四个引脚用来控制车轮的运动,四个引脚用来接收红外传感器传送过来的信号。这八个引脚分别对应的是pp0~pp7,
根据这两张图片结合,我们就知道了gpio2020~gpio2027这四个分别在什么位置。
查看gpio引脚值,对gpio引脚操作分为简单的几步:
- 导出gpio值,命令:echo 2020 > export
- 设置方向,输入为:echo in > direction输出为:echo out > direction
- 查看value值:cat value ( 注意工作目录 )
- 设置value值,如果gpio口被定义为输出时,可以设置gpio值为1或者0,1为高电平,0为低电平 echo 1 > value
- 不用就 echo 2020 > unexport
ADB使用和编译程序
设备连接
我们在将已经编译好的程序代码传送到哪吒开发板上时,使用的ADB工具。设备连接正常后,桌面上有显示图标:
那个对勾表示已经连接上ADB,如果有Allwinner Technology Inc. Tina ADB但是前面没有对勾,就点一下,要是没有这个选项,就重插一下开发板。
交叉编译
- ADB安装好以后,先在Ubuntu下新建一个.c文件,然后编译:
编译是交叉编译,交叉编译就是编译和运行是分开的,即编译在电脑的Ubuntu上,运行在哪吒开发板上进行。
根据全志社区中的提示:编译工具链在
tina/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702
中编译命令是:
/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/riscv64-unknown-linux-gnu-gcc -o car1 car1.c
- 其中编译命令可以根据编译工具链存放的位置进行调整,我们编译工具链存放的位置是:
tina-D1-H/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702
所以编译命令略微调整为:
tina-D1-H/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/riscv64-unknown-linux-gnu-gcc -o car car.c
我们一开始遇到的问题提示为找不到目录。后来发现是因为一开始目录不对。
- 编译好.c文件后,执行adb push car ./.就将编译好的程序下载到开发板上
进入开发板:用adb shell命令
进入开发板以后,在/root目录下找到car程序,赋予文件可执行权限chmod +x car,然后运行 ./car,见下图:
最后希望哪吒开发板也能拥有专门的操作gpio的函数和接口,方便大家使用。
本文内容为【玄铁杯第二届RISC-V应用创新大赛】作业
作者:智航追迹队
原文链接:https://occ.t-head.cn/community/post/detail?spm=a2cl5.14300636.0.0.429d180fqgpDV3&id=4094212597694402560
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号