MILK V GPIO控制LED教程

在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