Echo机器人环境配置

WSL2中的Echo机器人环境安装

1.WSL2内Ubuntu安装

首先命令窗口cmd(PowerShell)内输入

wsl --list --online

这样可以看到微软官方支持的所有 Linux 发行版列表

像这样

NAME                            FRIENDLY NAME
Ubuntu                          Ubuntu
Ubuntu-24.04                    Ubuntu 24.04 LTS
openSUSE-Tumbleweed             openSUSE Tumbleweed
openSUSE-Leap-16.0              openSUSE Leap 16.0
SUSE-Linux-Enterprise-15-SP7    SUSE Linux Enterprise 15 SP7
SUSE-Linux-Enterprise-16.0      SUSE Linux Enterprise 16.0
kali-linux                      Kali Linux Rolling
Debian                          Debian GNU/Linux
AlmaLinux-8                     AlmaLinux OS 8
AlmaLinux-9                     AlmaLinux OS 9
AlmaLinux-Kitten-10             AlmaLinux OS Kitten 10
AlmaLinux-10                    AlmaLinux OS 10
archlinux                       Arch Linux
FedoraLinux-43                  Fedora Linux 43
FedoraLinux-42                  Fedora Linux 42
eLxr                            eLxr 12.12.0.0 GNU/Linux
Ubuntu-20.04                    Ubuntu 20.04 LTS
Ubuntu-22.04                    Ubuntu 22.04 LTS
OracleLinux_7_9                 Oracle Linux 7.9
OracleLinux_8_10                Oracle Linux 8.10
OracleLinux_9_5                 Oracle Linux 9.5
openSUSE-Leap-15.6              openSUSE Leap 15.6
SUSE-Linux-Enterprise-15-SP6    SUSE Linux Enterprise 15 SP6

之后选择版本命令进行安装

wsl --install -d <换成你想安装的版本名称>

示例:

wsl --install -d Ubuntu-22.04
# 更新软件包列表
sudo apt-get update
# 升级已安装的软件包(可选,但推荐)
sudo apt-get upgrade -y

1.安装依赖环境

sudo apt-get install repo git ssh make gcc gcc-multilib g++-multilib module-assistant expect g++ gawk texinfo libssl-dev bison flex fakeroot cmake unzip gperf autoconf device-tree-compiler libncurses5-dev pkg-config

2.下拉完整项目(SDK和软件demo)

git clone https://github.com/No-Chicken/Echo-Mate.git
cd Echo-Mate
git submodule update --init --recursive

3.如果要递归更新所有子模块,请执行:

git submodule update --remote --merge --recursive

4.由于子仓库有大文件LFS,需要执行:

# 下拉lfs
git lfs pull
# 下拉所有lfs
git submodule foreach --recursive 'git lfs pull'

2.获取SDK

#进入到SDK的目录
cd Echo-Mate
cd ./SDK/rv1106-sdk

首先需要在SDK文件夹选择板级配置,这里选择对应的开发板,选择echo mate的配置即可。如果使用[7]custom,会弹出所有的.mk文件

./build.sh lunch

一键自动编译(会自动下载交叉编译的工具链及相关配置)

./build.sh 

如果PATH环境变量的目录出错,则换一个临时的PATH目录

清理缓存

./build.sh clean    # 清理编译产物(如果失败则先清理一下缓存)

3. 使用开发板demo的修改

打开DeskBot_demo目录

cd Echo-Mate/Demo/DeskBot_demo

① 把conf文件夹中的dev_conf.h中的内容更换

#define LV_USE_SIMULATOR 0    (把这个宏定义的1改成0)

② 把里面的toolchain.cmake的SDK_PATH目录换一下

set(SDK_PATH "/home/arthur/Echo-Mate/SDK/rv1106-sdk")    #换成自己的目录
# 把这个sysroot也换成自己的目录
# Specify the sysroot (if available)
set(CMAKE_SYSROOT ${SDK_PATH}/sysdrv/source/buildroot/buildroot-2023.02.6/output/host/arm-buildroot-linux-uclibcgnueabihf/sysroot)

③ 把CMakeLists.txt

# Option to choose target architecture
option(TARGET_ARM "Build for ARM architecture" ON)    // OFF改成ON

4. 烧录进开发板

之后安装教程进入

cd ./Demo
cd ./DeskBot_demo
mkdir ./build
cd ./build
cmake ..
make
make -j4

rm -rf *   # 清理缓存

把编译好的bin文件使用ADB传输进开发板

在Windows的CMD/PowerShell中操作:

adb push F:\bin /root/
# 推送整个 bin 文件夹到 /root 目录
adb push C:\Users\Arthur\Downloads\bin /root/
# 前面windows的目录换成自己的,这里是把WSL内编译好的放到了windows中
adb push C:\Users\Arthur\Downloads\bin /root/
adb shell chmod +x /root/bin/main
reboot
# 文件传进开发板
scp -r ./bin root@192.168.0.6:/root/

scp -r ./bin root@172.32.0.93:/root/
# 开发板传出文件,注意是传到当前目录下了
scp -r root@192.168.0.6:/root/test ./

scp -r root@172.32.0.93:/root/test ./
# 进入开发板
adb shell

ssh root@192.168.0.6    

ssh root@172.32.0.93

运行

adb shell     # 进入开发板系统
cd ../bin
chmod +x main     #加入可执行操作
./main            # 进入bin文件后运行这个main可执行程序

5. 开机自启动

解决需要执行指令才能运行的问题

修改启动脚本

# 编辑脚本
vi /etc/init.d/S99main

添加上这些:

#!/bin/sh
cd /root/bin && ./main &
/etc/init.d/S99main    # 重启脚本
chmod +x /etc/init.d/S99main

6.开机联网

# 1. 配置 WiFi 信息
cat > /etc/wpa_supplicant.conf << EOF
ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
network={
    ssid="your name"
    psk="your password"
}
EOF

# 2. 恢复网络接口配置(保持干净)
cat > /etc/network/interfaces << EOF
# interface file auto-generated by buildroot
auto lo
iface lo inet loopback
EOF

# 3. 创建 WiFi 自启动脚本
cat > /etc/init.d/S95wifi << 'EOF'
#!/bin/sh
(
    sleep 10
    ifconfig wlan0 up
    wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf
    sleep 5
    udhcpc -i wlan0 -q > /dev/null 2>&1
) &
EOF
chmod +x /etc/init.d/S95wifi

# 4. 确保 main 自启动脚本正确
cat > /etc/init.d/S99main << 'EOF'
#!/bin/sh
cd /root/bin && ./main &
EOF
chmod +x /etc/init.d/S99main

# 5. 重启测试
reboot

7. 解决双进程问题

加入自启动之后,这看不了这个调试信息,再次手动启动main可执行文件会导致双进程切换卡顿的问题

main.c 开头添加了 自动杀旧进程 的机制:

// 1. 查找所有 main 进程
FILE *fp = popen("pidof main", "r");

// 2. 如果找到其他 main 进程
if (找到其他进程) {
    kill(其他进程PID, SIGTERM);  // 杀掉它
    usleep(100000);  // 等它彻底退出
}

// 3. 设置调试输出
if (isatty(STDOUT_FILENO)) {
    // 手动运行 → 输出调试信息
} else {
    // 自启动 → 静默运行
    freopen("/dev/null", "w", stdout);
}
//示例:
static void kill_other_main_processes(void)
{
    // 获取当前进程PID
    pid_t my_pid = getpid();
    
    // 执行命令查找所有 main 进程
    FILE *fp = popen("pidof main", "r");
    if (!fp) {
        return;  // 无法执行命令,直接返回
    }
    
    char line[128];
    if (fgets(line, sizeof(line), fp)) {
        // 解析出所有PID(可能多个,用空格分隔)
        char *token = strtok(line, " \n");
        while (token) {
            pid_t other_pid = atoi(token);
            // 如果是其他进程(不是自己),杀掉它
            if (other_pid > 0 && other_pid != my_pid) {
                // 手动运行时才显示调试信息
                if (isatty(STDOUT_FILENO)) {
                    printf("[Main] Killing old process: PID=%d\n", other_pid);
                }
                kill(other_pid, SIGTERM);  // 发送终止信号
                usleep(50000);  // 等50ms
            }
            token = strtok(NULL, " \n");
        }
    }
    pclose(fp);
    
    // 再等一会儿确保旧进程完全退出
    usleep(100000);  // 100ms
}


//在main函数中:
  // ===== 第一步:杀死其他 main 进程 =====
    // 这个函数会杀掉已经存在的 main 进程(包括开机自启动的那个)
    kill_other_main_processes();
    
    // ===== 第二步:设置调试输出 =====
    if (isatty(STDOUT_FILENO)) {
        // 有终端 = 手动运行 = 调试模式
        printf("\n================================\n");
        printf("System Monitor (Manual Debug Mode)\n");
        printf("================================\n");
        // 保持正常输出
    } else {
        // 无终端 = 后台自启动 = 静默模式
        // 重定向所有输出到 /dev/null
        freopen("/dev/null", "w", stdout);
        freopen("/dev/null", "w", stderr);
    }
    

添加新评论