本帖最后由 damiaa 于 2024-2-15 12:50 编辑
【 正点原子瑞芯微RV1126测评】 4 GPIO篇之led
一、嵌入式应用程序交叉编译开发与板上运行
我们先从一个hello程序开始吧。
大部分嵌入式linux开发板都安装有adb功能程序(包括android手机)。那我们就用
Adb吧。
- 安装电脑的adb,这个这里就不介绍了。很多帖子包括我前面有个的帖子里面也介绍过。
- 安装交叉编译工具(在上一篇文章介绍了)
- 虚拟机建一个目录为hello编写一个hello.c 和hello.sh
Hello.c内容
#include <stdio.h>
void main(){
printf("Hello rv1126!!!\n");
}
保存退出
hello.sh内容:
/opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf-gcc -o hello hello.c
cp hello /mnt/hgfs/share/
保存,退出修改执行功能chmod +x hello.sh
执行hello.sh 然后在共享目录里面就有了hello文件
- 连接好板子的OTG usb线到电脑。
- 进入电脑命令行
运行adb devices查看是否有设备连接到了。
运行 adb -s xxxxxxxxxx shell 或者如果只一台adb设备直接 adb -s shell可以直接进入设备的shell里面执行命令。exit退出。
在没有进入shell里面但知道有一台adb设备连接好了就可以用adb push adb pull命令推送数据到设备和从设备拉取数据。具体如图所示。
修改一下hello文件为可执行,然后运行就可以了。如下:
到此,交叉编译和在板运行程序就ok了。
二、GPIO的在linux系统的命令行的操作
Linux有一个输入子系统专门用来管理输入设备,比如鼠标,键盘,按键等。还有一个led子系统驱动框架。具体大家可以看有关资料。
由上篇文章可以看出,这个板子专门为我们做了gpio测试的按键,4个和两个led 一个红的一个绿的。我们可以就这两个led展开测试。
- Led的测试 我们这次用串口连接rv1126板子,记得波特率等参数为1500000 n 8 1
我们查看sys/class/leds 里面有sys-led和user-led
他们里面也有些文件,这些个文件就是为了我们操作led用的。
echo 1 > /sys/class/leds/sys-led/brightness 点亮led
echo 0 > /sys/class/leds/sys-led/brightness 灭led
echo 1 > /sys/class/leds/user-led/brightness 点亮led
echo 0 > /sys/class/leds/user-led/brightness 灭led
为了使用定时器的延时,我们可以使用
echo timer > /sys/class/leds/sys-led/trigger
让定时器功能可以使用
然后
echo 100 > /sys/class/leds/sys-led/delay_on
echo 100 > /sys/class/leds/sys-led/delay_off
记得两个同时使用
灭就用echo 0 > /sys/class/leds/sys-led/delay_on
或者echo 0 > /sys/class/leds/sys-led/brightness
三、GPIO的在linux系统的C语言编程
上篇文章介绍过Ubuntu已经安装了交叉编译工具在/opt/atk-dlrv1126/bin目录里面。
编译就如下图所示:
../../../bin/arm-linux-gnueabihf-gcc -o xxx xxx.c
开始编写一个sh文件方便编译 和一个c文件测试led的on off功能
ledtest.sh内容如下(记得修改它的执行属性):
/opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf-gcc -o ledtest ledtest.c
cp ledtest.* /mnt/hgfs/share/
cp ledtest /mnt/hgfs/share/
ledtest.c 内容如下:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define SYS_LED_TRIGGER "/sys/class/leds/sys-led/trigger"
#define SYS_LED_BRIGHTNESS "/sys/class/leds/sys-led/brightness"
#define USER_LED_TRIGGER "/sys/class/leds/user-led/trigger"
#define USER_LED_BRIGHTNESS "/sys/class/leds/user-led/brightness"
#define USAGE() fprintf(stderr, "usage:\n" \
" %s <on|off>\n" \
" %s <trigger> <type>\n", argv[0], argv[0])
int main(int argc, char *argv[])
{
int fd_user_tr, fd_user_br;
/* 校验传参 */
if (2 > argc) {
USAGE();
exit(-1);
}
/* 打开文件 */
fd_user_tr = open(USER_LED_TRIGGER, O_RDWR);
if (0 > fd_user_tr) {
perror("open error");
exit(-1);
}
fd_user_br = open(USER_LED_BRIGHTNESS, O_RDWR);
if (0 > fd_user_br) {
perror("open error");
exit(-1);
}
/* 根据传参控制USER-LED */
if (!strcmp(argv[1], "on")) {
write(fd_user_tr, "none", 4); //先将触发模式设置为none
write(fd_user_br, "1", 1); //点亮LED
}
else if (!strcmp(argv[1], "off")) {
write(fd_user_tr, "none", 4); //先将触发模式设置为none
write(fd_user_br, "0", 1); //LED灭
}
else if (!strcmp(argv[1], "trigger")) {
if (3 != argc) {
USAGE();
exit(-1);
}
if (0 > write(fd_user_tr, argv[2], strlen(argv[2])))
perror("write error");
}
else
USAGE();
exit(0);
}
我们使用adb把编译好的程序推送到板子的/home/test/目录,记得推送后要修改加执行属性。chmod +x xxxx程序,后面就可以查看板子的led变化了
关于led的timer的delay功能,程序修改为:
leddelay.sh内容如下(记得修改它的执行属性):
/opt/atk-dlrv1126-toolchain/bin/arm-linux-gnueabihf-gcc -o leddelay leddelay.c
cp leddelay.* /mnt/hgfs/share/
cp leddelay /mnt/hgfs/share/
leddelay.c 内容如下:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define SYS_LED_TRIGGER "/sys/class/leds/sys-led/trigger"
#define SYS_LED_BRIGHTNESS "/sys/class/leds/sys-led/brightness"
#define USER_LED_TRIGGER "/sys/class/leds/user-led/trigger"
#define USER_LED_BRIGHTNESS "/sys/class/leds/user-led/brightness"
#define USER_LED_DELAYON "/sys/class/leds/user-led/delay_on"
#define USER_LED_DELAYOFF "/sys/class/leds/user-led/delay_off"
#define USAGE() fprintf(stderr, "usage:\n" \
" %s <delayon> <times>\n" \
" %s <delayoff> <times>\n" \
" %s <trigger> <type>\n", argv[0], argv[0], argv[0])
int main(int argc, char *argv[])
{
int fd_user_tr1, fd_user_br;
int fd_user_delayon,fd_user_delayoff;
/* 校验传参 */
if (2 > argc) {
USAGE();
exit(-1);
}
/* 打开文件 */
fd_user_tr1 = open(USER_LED_TRIGGER, O_RDWR);
if (0 > fd_user_tr1) {
perror("open error");
exit(-1);
}
//fd_user_br = open(USER_LED_BRIGHTNESS, O_RDWR);
//if (0 > fd_user_br) {
// perror("open error");
// exit(-1);
//}
fd_user_delayon = open(USER_LED_DELAYON,O_RDWR);
if(0 >fd_user_delayon) {
perror("open error");
exit(-1);
}
fd_user_delayoff = open(USER_LED_DELAYOFF,O_RDWR);
if(0 > fd_user_delayoff){
perror("open error");
exit(-1);
}
/* 根据传参控制USER-LED */
if (!strcmp(argv[1], "delayon")) {
write(fd_user_delayon, argv[2], strlen(argv[2])); //delay LED times
}
else if (!strcmp(argv[1], "delayoff")) {
write(fd_user_delayoff,argv[2], strlen(argv[2])); //delay LED灭 times
}
else if (!strcmp(argv[1], "trigger")) {
if (3 != argc) {
USAGE();
exit(-1);
}
if (0 > write(fd_user_tr1, argv[2], strlen(argv[2])))
perror("write error");
}
else
USAGE();
exit(0);
}
同样编译,用adb推送到板子修改执行属性后运行,就可以看到led的闪烁,并能修改它的闪烁间隔时间了。
实验先到这里,谢谢。