ubuntu编译小智AI面包板esp32s3n16r8

作者:Harrandi 发布时间:May 16, 2026 分类:Linux

1.安装依赖

sudo apt update
sudo apt install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build    ccache libffi-dev libssl-dev dfu-util libusb-1.0-0

2.克隆新版本

cd ~/esp
git clone --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
git checkout v5.5.4
git submodule update --init --recursive

3. 安装工具链

./install.sh

4. 设置环境变量(每次新终端需要执行)

. ./export.sh

5. 验证版本

idf.py --version

未来升级

1. 进入旧版 IDF 目录(根据你的实际路径)

cd ~/esp/esp-idf

2. 切换到 v6.x.x

git fetch --all
git checkout v6.x.x
git submodule update --init --recursive

3. 清理并重新安装工具

rm -rf ~/.espressif   # 删除旧工具链
./install.sh

4. 重新设置环境

. ./export.sh

5. 验证

idf.py --version

编译

设置环境(每次新终端都要执行)

source ~/esp/esp-idf/export.sh

或者

cd ~/esp/esp-idf
. ./export.sh

配置开发板型号

idf.py set-target esp32s3   # 改成你的芯片型号

打开配置菜单(选择 Board Type)

idf.py menuconfig

进入 Xiaozhi Assistant → Board Type → 选择你的开发板

编译

idf.py build

烧录(连接开发板后)

idf.py -p /dev/ttyUSB0 flash

查看串口日志(可选)

idf.py -p /dev/ttyUSB0 monitor

记一次出错:
“ - no versions of espressif2022/image_player match ==1.1.0~1

  - project depends on espressif2022/image_player (==1.1.0~1)  ”

解决方法:

找到并打开 main/idf_component.yml

将 espressif2022/image_player: ==1.1.0~1 改为 espressif2022/image_player: ^1.1.1

将 espressif2022/esp_emote_gfx: ==1.0.0~2 改为 espressif2022/esp_emote_gfx: ^1.2.0

重新编译:

rm -rf build managed_components
idf.py fullclean
idf.py build

部署小智AI到公网

作者:Harrandi 发布时间:May 14, 2026 分类:Linux

记录一下,也或许有人用得到。
参考https://github.com/xinnan-tech/xiaozhi-esp32-server/issues/791

1.克隆项目,https://github.com/xinnan-tech/xiaozhi-esp32-server
参考文件夹docs内的Deployment_all.md,
xiaozhi-esp32-server-redis和voiceprint-api我使用了docker其余没 用.
先搞定本地的部署,测试正常后配置公网。
2.去CF增加一个A记录如xiaozhi,地址填当前你服务器公网地址然后获取域名ID(不是ZONE ID)后面用得到:

curl --request GET   --url "https://api.cloudflare.com/client/v4/zones/你的ZONE ID/dns_records?name=xiaozhi.yours.org&type=A"   --header "Authorization: Bearer 你的APItoken"   --header "Content-Type: application/json"



为域名申请letsencrypt证书:
略麻烦,因为我用动态域名,我也尝试了tunnel,工作不正常,只能用动态域名+直接开放端口。
登录 Cloudflare 控制台,进入 My Profile → API Tokens
点击 Create Token → 选择 Create Custom Token
配置权限(如Zone Zone Read; Zone DNS Edit)
选择Specific zone,即要用的域名.
在 TTL (time to live) 区域设置:
Start date (notBefore):可选,设置 Token 何时开始生效。不填则创建后立即生效
End date (notAfter):建议设置,Token 到此时间后自动失效。不填则永不过期

用 DNS-01 申请 SSL 证书:
# 安装 certbot 和 cloudflare dns 插件

sudo apt install certbot python3-certbot-dns-cloudflare

# 创建 API Token 配置文件(把 TOKEN 换成你的)

echo 'dns_cloudflare_api_token = 你的CloudflareAPIToken' | sudo tee /etc/cloudflare.ini
sudo chmod 600 /etc/cloudflare.ini

# 申请证书

sudo certbot certonly \
 --dns-cloudflare \
 --dns-cloudflare-credentials /etc/cloudflare.ini \
 -d xiaozhi.yours.org

创建一个动态IP更新脚本命名cf-ddns.sh:

#!/bin/bash
# ===配置区=============
CLOUDFLARE_API_TOKEN="你的APItoken"
ZONE_ID="你的ZoneID"
DNS_RECORD_ID="你的域名ID"
DNS_RECORD_NAME="xiaozhi.yours.org"
DNS_RECORD_TYPE="A"
# =====下方无需改动======

# curl 和 jq 的完整路径(cron 需要,没有的话需要安装)
CURL="/usr/bin/curl"
JQ="/usr/bin/jq"

# 获取当前公网 IP
IP=$($CURL -s ifconfig.me)

# 获取 Cloudflare 上当前记录的 IP
CURRENT_IP=$($CURL -s -X GET    "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_RECORD_ID" \
 -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
 -H "Content-Type: application/json" | $JQ -r '.result.content')

# 比较是否需要更新
if [[ "$IP" == "$CURRENT_IP" ]]; then
echo "$(date): IP 未变化,跳过更新 ($IP)"
exit 0
fi

# IP 变化了,执行更新
echo "$(date): IP 从 $CURRENT_IP 变为 $IP,开始更新..."

$CURL -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_RECORD_ID" \
 -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
 -H "Content-Type: application/json" \
 --data '{
   "type": "'"$DNS_RECORD_TYPE"'",
   "name": "'"$DNS_RECORD_NAME"'",
   "content": "'"$IP"'",
   "ttl": 120,
   "proxied": false
 }'

 echo "$(date): 更新完成 -> $IP"

将这个脚本加入cron并输出日志注意权限:

chmod +x ~/cf-ddns.sh        # 给执行权限
crontab -e                       # 编辑定时任务

*/5 * * * * /yourpath/cf-ddns.sh >> /home/you/ddns-error.log

3.配置Nginx反代,参考顶部链接内的服务器基础参数。
我的根目录是智控台(必须,我尝试子目录访问总是有小问题),digital-human就是之前的测试页面,为方便使用digital-human所以全部使用https,如需保留http删除nginx配置第一块sever_name下的return行。

登陆修改智控台内server.fronted_url
https://xiaozhi.yours.org:8443
server.websocket 地址wss://xiaozhi.yours.org:8443/xiaozhi/v1/
OTA地址 https://xiaozhi.yours.org:8443/xiaozhi/ota/
部署web:

cd ~/xiaozhi-esp32-server/main/manager-web
npm run build
cp -r dist/* /var/www/manager-web/

权限设置:

sudo chown -R www-data:www-data /var/www/manager-web
sudo find /var/www/manager-web -type d -exec chmod 755 {} \;
sudo find /var/www/manager-web -type f -exec chmod 644 {} \;

# 重载 Nginx
nginx -s reload

我的nginx配置:

server {
listen 8080 ;
server_name yours.org;
return 301 https://$host:8443$request_uri; #如使用http删除此行
  location / {
    root /var/www/manage-web;
    index index.html index.htm;
    try_files $uri $uri/ =404;
}

 location /xiaozhi/v1/ {
    proxy_pass http://192.168.10.12:8000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
  location /xiaozhi/ota/ {
    proxy_pass http://192.168.10.12:8002;
    proxy_http_version 1.1;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

}
server {
listen 8443 ssl;
server_name yours.org;

ssl_certificate /etc/letsencrypt/live/xiaozhi.yours.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xiaozhi.yours.org/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
    
  location / {
    root /var/www/manager-web/;
    index index.html;
    try_files $uri $uri/ =404;
}

  location /digital-human {
    root /var/www/;     
    index index.html index.htm;     
    try_files $uri $uri/ =404;
}   



 location /xiaozhi/v1/ {
    proxy_pass http://192.168.10.12:8000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_read_timeout 3600s;
}
  location /xiaozhi/ota/ {
    proxy_pass http://192.168.10.12:8002;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
  location /xiaozhi/ {
    proxy_pass http://127.0.0.1:8002;
    proxy_set_header Host $host;
    proxy_connect_timeout 15;
    proxy_send_timeout 15;
    proxy_read_timeout 15;
    proxy_set_header   X-Real-IP  $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
} 
}

因为我三个组件不是docker部署,所以用systemctl管理:
打包manager-api:

# 进入 manager-api 项目根目录(有 pom.xml 的地方)
cd /path/to/manager-api

# 用 Maven 打包
mvn clean package -DskipTests

创建systemctl:

sudo nano /etc/systemd/system/manager-api.service

[Unit]
Description=Xiaozhi Manager API Service
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/home/yours/xiao-zhi-server/main/manager-api
ExecStart=/usr/bin/java -jar /home/yours/xiao-zhi-server/main/manager-api/target/xiaozhi-esp32-api.jar
Restart=always
RestartSec=10
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target

创建SERVER的systemctl:

[Unit]
Description=Xiaozhi ESP32 Server
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/home/yours/xiao-zhi-server/main/xiaozhi-server
ExecStart=/home/yours/miniconda3/envs/xiaozhi-esp32-server/bin/python app.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

创建MCP的systemctl:

[Unit]
Description=Xiaozhi MCP Server Service
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/home/yours/xiao-zhi-server/mcp-endpoint-server
ExecStart=/home/yours/miniconda3/envs/mcp-endpoint-server/bin/python main.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

启动或查询或自动它们:

sudo systemctl daemon-reload
sudo systemctl start 服务名
sudo systemctl enable 服务名
sudo systemctl status 服务名

在Radxa Zero 3上运行deepseek

作者:Harrandi 发布时间:March 4, 2025 分类:Linux

在Zero上编译非常痛苦,所以还是交叉编译:

安装步骤
更新包列表:

sudo apt update
安装交叉编译工具链:

sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
//gcc-aarch64-linux-gnu:ARM64架构的C编译器。

//g++-aarch64-linux-gnu:ARM64架构的C++编译器。

验证安装:

aarch64-linux-gnu-gcc --version
aarch64-linux-gnu-g++ --version

  1. 设置交叉编译环境
    在项目目录中创建一个 toolchain.cmake 文件,用于指定交叉编译工具链。

创建 toolchain.cmake 文件
cmake

toolchain.cmake

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)

set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)

set(CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

  1. 交叉编译项目
    使用交叉编译工具链编译项目。

步骤 1:生成构建文件

cmake -B build -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake
步骤 2:编译项目

cmake --build build --config Release -j 2
步骤 3:验证编译结果
检查生成的可执行文件是否为ARM64架构:

file build/my_program
输出示例:

build/my_program: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, not stripped

  1. 将程序复制到RK3566
    使用 scp 或U盘将编译好的程序复制到RK3566上运行。

使用 scp 复制

scp build/my_program user@rk3566_ip:/path/to/destination
在RK3566上运行

./llama-server -m DeepSeek-R1-Distill-Qwen-1.5B-Q4_K_M.gguf --host 0.0.0.0

使用精简蒸馏模型DeepSeek-R1-Distill-Qwen-1.5B-Q4_K_M.gguf

结果还是非常意料之内的,缓慢无比。0.2 t/s

Radxa 3w zero connect wifi before login

作者:Harrandi 发布时间:February 28, 2025 分类:Linux

So here is the thing:
I want to use one of my radxa 3w zero to be a light server, but for some reason their CLI version can not start up, which is insane. And I tried, it just stuck at the beginning.

So I uninstalled the xfce of debian-xfce version. And everything I need were working properly.
Except the Wi-Fi. It only connects when I login.

I have tried several methods. And finally.

At /etc/NetworkManager/system-connections/mywifi.nmconnection

Then disable the line "permissions" and it works.

此内容被密码保护

作者:Harrandi 发布时间:June 28, 2019 分类:Linux

请输入密码访问