Duo点个灯(shell和c点灯,开机点灯)

玩板子第一件事情,点灯,点完就可以吃灰了。

在Duo板子上有一个板载的LED,对应的GPIO为440,下面分别使用shell脚本和c语言进行点灯。

1. shell点灯:

用shell脚本点灯,无需任何额外的工具,连接到Duo,使用自带的vi命令即可。

# 使用vi编辑/root/led_blick.sh
vi ~/led_blick.sh
#!/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 1
  echo 0 /sys/class/gpio/gpio$LED/value
  sleep 1
done

echo $LED > /sys/class/gpio/unexport

编写完成后,直接执行,就能点亮了:

chmod a+x /root/led_blick.sh
/root/led_blick.sh

执行上述脚本后,板载的LED蓝灯,就会一闪一闪一会了。

现在的板子,起来后,灯也不亮一下,都不值是死是活的。
那可以点等了,就可以修改一下开机时候的脚本,让开机后,灯闪一会儿,告诉我们板子起来了。

vi /mnt/system/auto.sh

参考下图添加调用led_blink.sh即可:

上面是用shell脚本点灯,可能比较Low,那下面再用C点灯玩玩。

2.C点灯

在duo编译环境中,建立对应的目录,并编写led_blink.c,具体如下:

# 建立工作目录
mkdir ~/duo/projects/blink
cd ~/duo/projects/blink

# 编写led_blink.c文件:
vim 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;
}

编写完成后,使用下面的指令编译:

riscv64-unknown-linux-gnu-gcc -static -o led_blink led_blink.

如果 找不到 riscv64-unknown-linux-gnu-gcc,则运行一下:

source ~/duo/build/cvisetup.sh

然后再次进行编译。

编译后,将会得到 led_blink可执行文件:

论坛上,已经有大佬分享了,如何启用网络,启用后,就可以通过网络,把led_blink传到板子上执行。
如果没有网络,还有非常简单的办法,使用base64,具体步骤如下:

# 主机或者docker环境中
base64 led_blink > led_blink.b64
head led_blink.b64


使用base64指令,直接把二进制文件转为base64文本编码

然后到开发板上(一般为串口连接后的终端),使用系统自带的vi工具,接受文本数据:

# 将上一步生成的base64的文件打开,把内容全部复制到这里来
vi led_blink.b64

# 拷贝完成后,保存上述文件,然后解码
base64 -d led_blink.b64 > led_blink

# 执行:
chmod u+x led_blink
./led_blink

执行后,如同shell脚本部控制一样,板载的LED蓝灯,就会一闪一闪一会了。

参考:

2 Likes

很棒的分享,为其他用户提供了非常好的借鉴 :+1:

请把你的收件地址及论坛身份证明信息(可以是登陆后的截图)发送至邮箱:hoka@milkv.io

我会送你一个小礼品。

如果 gpiobusy

vi /etc/init.d/S99user

注释掉 . $SYSTEMPATH/blink.sh &
重启即可

How is the GPIO value of 440 derived

小的BUG修改一下。echo 1 > /sys/class/gpio/gpio$LED/value