在milk-v duo上有一个板载LED,与XGPIOC24连接。
默认GPIO相关模块已全部编入内核,不需要再执行加载命令。
在控制台下运行GPIO读写命令或者自行在内核态或者用户态编写GPIO读写程序,就可以对GPIO进行输入输出操作。
其中XGPIOC的组号值为:416,则GPIO编号为416+24=440。
命令行和脚本sysfs方式点亮LED】:
使用命令行点亮LED:
在duo启动,进入命令行之后,输入以下命令:
echo 440 > /sys/class/gpio/export #此时生成/sys/class/gpio/gpio440目录
echo out > /sys/class/gpio/gpio440/direction #再配置IO方向为输出:
echo 1 > /sys/class/gpio/gpio440/value #点亮LED
echo 0 > /sys/class/gpio/gpio440/value #熄灭LED
echo 440 > /sys/class/gpio/unexport #释放GPIO资源
使用shell脚本实现LED闪烁:
上述可以再bash中操作led的亮灭状态,现在用shell脚本在上述命令的基础上实现led定时闪烁的功能:
创建一个.sh文件,名为led_blink.sh
在官方提供的镜像中使用自带的vi编辑器见下列代码写入:
#!/bin/bash
LED=440
# 激活GPIO-LED
echo $LED > /sys/class/gpio/export
# 设置GPIO-LED
echo out > /sys/class/gpio/gpio$LED/direction
# 循环10次:点亮LED,延时1秒,在关闭LED,再延时1秒
for i in $(seq 1 30)
do
echo 1 > /sys/class/gpio/gpio$LED/value
sleep 0.4
echo 0 > /sys/class/gpio/gpio$LED/value
sleep 0.4
done
# cleanup gpio
echo $LED > /sys/class/gpio/unexport
编写完保存退出(:wq)即可直接运行该脚本:/root/led_blink.sh
如果希望让该LED在开机后自启闪烁(作为系统的状态灯),则可使用vi在/mnt/system/auto.sh脚本文件中加上/root/led_blink.sh &;如下所示:
交叉编译C语言sysfs方式实现LED闪烁】:
进入电脑的ubuntu系统,下载工具链:
wget https://sophon-file.sophon.cn/sophon-prod-s3/drive/23/03/07/16/host-tools.tar.gz
然后解压:
tar xvf host-tools.tar.gz
编译器确认:
进入MIlk V Duo系统,cat /proc/version
由此可见官方Duo的系统镜像使用的是riscv64-unknown-linux-musl-gcc编译器(在电脑ubuntu的编译时要指定该编译器否则编译的代码无法在Duo开发板实现功能)
编写C语言代码:
在电脑ubuntu的duo编译环境中,建立对应的目录,并编写led_blink.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h> //define O_WRONLY and O_RDONLY
// LED 引脚
#define SYSFS_GPIO_EXPORT "/sys/class/gpio/export"
#define SYSFS_GPIO_UNEXPORT "/sys/class/gpio/unexport"
#define SYSFS_GPIO_RST_PIN_VAL "440"
#define SYSFS_GPIO_RST_DIR "/sys/class/gpio/gpio440/direction"
#define SYSFS_GPIO_RST_DIR_VAL "OUT"
#define SYSFS_GPIO_RST_VAL "/sys/class/gpio/gpio440/value"
#define SYSFS_GPIO_RST_VAL_H "1"
#define SYSFS_GPIO_RST_VAL_L "0"
int main()
{
int fd;
int count = 30;
// 打开端口/sys/class/gpio# echo 440 > export
fd = open(SYSFS_GPIO_EXPORT, O_WRONLY);
if (fd == -1)
{
printf("ERR: export open error.\n");
return EXIT_FAILURE;
}
write(fd, SYSFS_GPIO_RST_PIN_VAL, sizeof(SYSFS_GPIO_RST_PIN_VAL));
close(fd);
// 设置端口方向/sys/class/gpio/gpio440# echo out > direction
fd = open(SYSFS_GPIO_RST_DIR, O_WRONLY);
if (fd == -1)
{
printf("ERR: direction open error.\n");
return EXIT_FAILURE;
}
write(fd, SYSFS_GPIO_RST_DIR_VAL, sizeof(SYSFS_GPIO_RST_DIR_VAL));
close(fd);
// 输出复位信号: 拉高>100ns
fd = open(SYSFS_GPIO_RST_VAL, O_RDWR);
if (fd == -1)
{
printf("ERR: gpio open error.\n");
return EXIT_FAILURE;
}
while (count)
{
count--;
write(fd, SYSFS_GPIO_RST_VAL_H, sizeof(SYSFS_GPIO_RST_VAL_H));
usleep(1000000);
write(fd, SYSFS_GPIO_RST_VAL_L, sizeof(SYSFS_GPIO_RST_VAL_L));
usleep(1000000);
}
close(fd);
// 打开端口/sys/class/gpio# echo 440 > unexport
fd = open(SYSFS_GPIO_UNEXPORT, O_WRONLY);
if (fd == -1)
{
printf("ERR: unexport open error.\n");
return EXIT_FAILURE;
}
write(fd, SYSFS_GPIO_RST_PIN_VAL, sizeof(SYSFS_GPIO_RST_PIN_VAL));
close(fd);
return 0;
}
在电脑ubuntu查找对应的编译器:sudo find / | grep riscv64-unknown-linux-musl-gcc
编译生成可执行文件led_blink:sudo
/home/jw/duo/cvi_mmf_sdk/host-tools/gcc/riscv64-linux-musl-x86_64/bin/riscv64-unknown-linux-musl-gcc -static -o led_blink led_blink.c
使用ssh将led_blink可执行文件传输到Duo开发板:
(前提是你使用的镜像带有RNDIS功能才能用这种方法把文件传输到Duo开发板;官方系统镜像milkv-duo-20230519-1809.img以上的版本自带RNDIS功能)
sudo scp ./led_blinkv2 root@192.168.42.1:/root/
在Duoi开发板给可执行文件led_bink给足权限chmod u+x led_blink,并且执行代码
执行后板载的LED灯闪烁
交叉编译C语言使用wiringX库实现LED闪烁】:
未完待续……
Duo终端python使用pinpong库实现LED闪烁】:
以下程序在 Duo-V1.0.4镜像下使用
首先让开发板的自带的系统指示灯停止工作
mv /mnt/system/blink.sh /mnt/system/blink.sh_backup && sync
reboot
编辑led闪烁的.py文件 vi ./test_led.py
输入以下代码:
#实验效果:控制UNIHIKER板载LED灯一秒闪烁一次
#接线:使用电脑连接一块UNIHIKER主控板
import time
from pinpong.board import Board,Pin
Board("MILKV-DUO").begin() #初始化,选择板型,不输入板型则进行自动识别
led = Pin(Pin.D0, Pin.OUT) #引脚初始化为电平输出
while True:
led.value(1) #输出高电平
print("1") #终端打印信息
time.sleep(0.5) #等待1秒 保持状态
led.value(0) #输出低电平
print("0") #终端打印信息
time.sleep(0.5) #等待1秒 保持状态
运行python程序
python3 ./test_led.py