12 KiB
12 KiB
Avaota F1 开发与集成
面向仓库根目录的总览文档,整合 Day1–Day9 日志、任务清单与完成总结。
1. 项目简介
本项目面向 Avaota F1 AI 机器人,基于 全志 V821 / 32-bit RISC‑V SoC,目标是在 Tina Linux 固件上实现一套「可量产」的机器人终端固件,集成:
- 音频采集(板载模拟麦克风)与播放(I2S + MAX98357A)
- IMU 六轴姿态传感(ICM‑42688‑P)
- GC2083 MIPI 摄像头 JPEG 图像采集
- UDP / HTTP / WebSocket 网络通讯
- 多线程主程序与静态链接交叉编译流程
文档与代码组织按「Day1–Day9 开发日志 + 任务清单 + 完成总结」推进,可作为以后移植到其他 Tina Linux / 全志平台的模板工程。
目前对话的位置是本地Windows 11系统的主机,用于开发的环境是局域网中的Ubuntu服务器。
2. 硬件与开发环境
2.1 目标硬件(板端)
- SoC:全志 V821,32‑bit RISC‑V 架构
- 板载外设
- 模拟麦克风 → 内置 Audio Codec(audiocodec)
- I2S 数字功放:MAX98357A(BCLK/LRCK/DOUT:PD12/PD13/PD15)
- 摄像头:GC2083,MIPI‑CSI2,典型输出 1280×720 @ 20fps
- IMU:ICM‑42688‑P(GPIO 模拟 SPI)
- 操作系统:Tina Linux(基于 OpenWrt 的 Allwinner SDK)
2.2 主机开发环境(PC)
- 系统:Ubuntu 24.04 LTS(同时也有 Windows + WSL 的混合开发)
- 工具链 & SDK
- Tina SDK:
tina-v821-release /home/rongye/ProgramFiles/AvaotaF1/avaota_sdk/tina-v821-release这是SDK位置- 交叉编译工具链:
- 当前使用:
prebuilt/rootfsbuilt/riscv/nds32le-linux-musl-v5d⭐ musl 工具链(与开发板兼容) - 编译器前缀:
riscv32-linux-musl- 已废弃:out/toolchain/nds32le-linux-glibc-v5d(glibc 工具链,与板端 musl libc 1.2.4 不兼容)
- 当前使用:
/home/rongye/ProgramFiles/AvaotaF1/avaota_app_demo这是交叉编译的位置- Python:通过
python-is-python3或为遗留脚本装 python2 并软链到python
- Tina SDK:
2.3 开发主机准备要点(Ubuntu 24.04)
- 开启 i386 架构以兼容旧版 32 位库
- 手动安装被移除的
libncurses5/libtinfo5 - 安装 bison / flex / 交叉编译依赖,修复
lunch/make时报错 - 注意
make -j一定要限制并行度(如-j8),避免 OOM
3. 仓库结构建议
实际仓库结构可按以下思路组织(示例):
.
├── ../Docs/DevLogs/ # (位于上级目录) 每日开发日志
│ ├── Day1.md … Day18.md
├── docs/ # 本地硬件/SDK文档
│ ├── 1.png … 2.png
│ ├── AvaotaF1.md
│ ├── 引脚.md
│ ├── TinaSDK-Docs/
│ ├── tina_files_clean.csv
├── ESP32S3/ # 可参考的ESP32S3固件
├── src/
│ ├── audio/ # AudioCapture / AudioPlayer
│ ├── camera/ # Camera 类 / MPP 封装
│ ├── imu/ # ICM‑42688 SPI 驱动与测试
│ ├── network/ # UDP / HTTP / WebSocket 客户端
│ ├── utils/
│ ├── main.cpp # 主程序入口(多线程集成)
│ ├── main_test.cpp # 本地硬件自检程序
│ ├── Makefile # 交叉编译配置
│ └── build_*.sh # 构建脚本(main/test/phaseX)
├── build_main.sh
├── logs.md # 编译时的日志(实时填写)
└── README.md # 本文档
你可以直接把 Day1–Day7、任务清单与完成总结放到 ../docs/DevLogs/ 目录,并用当前 README 作为入口索引。
4. 功能模块概览
4.1 音频系统
输入:板载模拟麦克风
- 通过 SoC 内部 Audio Codec (audiocodec) 采集
- ALSA 设备:
hw:audiocodec或hw:0,0(录音推荐plughw:0,0) - 运行时配置:
MIC Switch开启MIC Gain建议值 25(在音量与底噪之间平衡)adc-vol与lineout-gain使用 DTS 默认值或适度调整
- 采样参数:
- 16 kHz, S16_LE, Mono
- 典型链路:
setup_mic.sh→arecord→/tmp/test_mic.wav→aplay/ 上行网络
输出:I2S + MAX98357A
- I2S0 接 MAX98357A,扬声器输出
- Device Tree 为每个引脚创建独立 pinctrl 节点:
i2s0_bclk_pin:PD12i2s0_lrck_pin:PD13i2s0_dout0_pin:PD15
- I2S 平台设备
&i2s0_plat绑定这些引脚,status = "okay" - 通过 ALSA
aplay/ 自己的AudioPlayer类进行播放
4.2 IMU 传感器(ICM‑42688‑P)
- 最终采用 GPIO 模拟 SPI:
- SCLK: PD3
- MOSI: PD2
- MISO: PD4
- CS : PD5
- SPI Mode0,软件 bit‑bang,速率约 500 kHz(可按需提升)
- 主要特性:
- WHO_AM_I = 0x47 识别验证
- 加速度计:±16g,1 kHz ODR
- 陀螺仪:±2000 °/s,1 kHz ODR
- 温度通道:用于环境监控与漂移补偿
- 静止状态验证:
- 合加速度 ≈ 9.8 m/s²
- 陀螺仪接近 0 °/s
- 上层封装:
ICM42688类提供采样与单位转换- 独立
test_imu自检程序 - 在主程序中通过 UDP 周期性上报 JSON/结构体数据
4.3 摄像头系统(GC2083 + MPP)
- 使用 Allwinner Eyesee‑MPP 框架:SYS → VI → ISP → VENC
- 流水线:
- VI(接 MIPI 摄像头)
- ISP(自动曝光、白平衡、降噪)
- VENC(JPEG 编码)
- 关键配置:
- 分辨率:1280×720 @ 20fps(可调)
- JPEG 质量:80(在质量与码率之间折中)
- VI Buffer:5 帧
- VBV Buffer:4 MB,避免
VBV FULL错误
Camera类职责:- 完成 MPP 初始化 / 绑定 / 销毁
- 按需抓拍单帧 JPEG(用于 WebSocket 发送或本地保存)
- 提供阻塞式
capture_frame()接口与重试机制
- 测试程序:
test_camera抓拍多张 JPEG 保存到 SD 卡- 实测成功率 100%,文件大小 20–80 KB 之间,画面曝光正常
4.4 网络通讯
UDP
- 轻量 IMU 数据上报通道
- 使用 POSIX socket,静态链接,无额外依赖
- 典型用法:
UDPSender初始化目标 IP/Port- 周期性发送 IMU/状态数据
HTTP(libcurl 或轻量封装)
- 主要用途:
- 从服务器拉取 TTS 音频流(如
stream.wav) - 拉取配置文件或诊断信息
- 从服务器拉取 TTS 音频流(如
- 流式下载接口已预留,可边下边写入
AudioPlayer播放
WebSocket
- 早期方案:SDK 内置
libuwsc(后期为规避依赖,可用自实现轻量 WS 客户端) - 主要用途:
- 上行:摄像头 JPEG 帧、音频 PCM 片段
- 下行:控制指令 / 状态同步
- 接口设计:
WSClient负责 TCP 连接、握手、帧收发、心跳与重连- 主线程中,每个子模块持有各自的 WSClient 实例或共享连接
5. 编译与构建流程
5.1 Tina SDK 环境准备(概要)
- 解压 SDK:
mkdir -p ~/ProgramFiles/avaota_sdk tar -xvf tina-v821-*.tar.xz -C ~/ProgramFiles/avaota_sdk - 初始化环境:
cd ~/ProgramFiles/avaota_sdk/tina-v821-release source build/envsetup.sh lunch # 选择 avaota_f1 / v821 相关配置 - 全量编译:
make -j8 pack # 需要时打包固件
5.2 应用程序交叉编译
在 src/ 目录中提供一个或多个构建脚本,例如:
#!/bin/bash
set -e
SDK_ROOT=~/ProgramFiles/AvaotaF1/avaota_sdk/tina-v821-release
# ⚠️ 使用 musl 工具链(与开发板兼容)
TOOLCHAIN=${SDK_ROOT}/prebuilt/rootfsbuilt/riscv/nds32le-linux-musl-v5d/bin
export PATH=${TOOLCHAIN}:$PATH
make clean
make all -j4 # 或按目标拆分:make main / make test_audio / make test_imu
Makefile 要点:
- 使用
riscv32-linux-musl-g++编译器(musl 工具链) - 动态链接器:
/lib32/ld.so.1(板端需创建符号链接:ln -s /lib32/ilp32d/libc.so /lib32/ld.so.1) - 链接静态或最小依赖的动态库
- 注意链接顺序:业务库 → MPP/ISP/cedarx →
-lpthread -lrt -lm -ldl -lstdc++
5.3 部署与运行
- 将交叉编译好的可执行文件拷贝到 SD 卡:
cp avaota_client /media/$USER/SDCARD/ - 板端挂载 SD 卡并复制到
/tmp:mount /dev/mmcblk0p1 /mnt/extsd cp /mnt/extsd/avaota_client /tmp/ chmod +x /tmp/avaota_client - 运行:
/tmp/avaota_client
推荐所有测试程序(
test_audio/test_imu/test_camera/avaota_test)都统一走上述流程,避免执行权限与只读分区问题。
6. 主程序(集成)架构示意
主程序建议使用多线程模型,将各个模块解耦:
// 伪代码示例
int main() {
init_logging();
init_network_config(); // 服务器 IP / 端口 / 路径等
init_signal_handler(); // Ctrl+C 安全退出
std::thread cam_thread(run_camera_loop);
std::thread mic_thread(run_audio_capture_loop);
std::thread spk_thread(run_audio_play_loop);
std::thread imu_thread(run_imu_udp_loop);
// 可选:主线程处理下行指令 / 状态机
run_main_control_loop();
// 等待退出
cam_thread.join();
mic_thread.join();
spk_thread.join();
imu_thread.join();
return 0;
}
每个线程内部:
- 初始化各自的硬件和网络客户端
- 进入循环:
- 采集 → 编码(可选) → 通过 UDP/WS 发送
- 或从 HTTP/WS 接收 → 解码(可选) → 播放/控制硬件
- 捕获异常并尝试重连 / 恢复,必要时上报主线程
7. 日志与文档索引
可以在 README 中给出所有开发日志与计划文档的入口,方便回溯:
../Docs/DevLogs/Day1.md:SDK 编译与 32 位环境踩坑../Docs/DevLogs/Day2.md:UDP 通信、网络库编译、libuwsc / libcurl 准备../Docs/DevLogs/Day3.md:音频采集 & 播放模块(ALSA + I2S)../Docs/DevLogs/Day4.md:模拟麦克风配置 + IMU SPI 驱动与验证../Docs/DevLogs/Day5.md:GC2083 摄像头 MPP 集成与 JPEG 捕获../Docs/DevLogs/Day6.md:硬件全功能验证、本地测试程序、网络库诊断../Docs/DevLogs/Day7.md:交叉编译 Makefile 收敛、工具链配置../Docs/DevLogs/Day8.md:整体编译成功、Cedar 库链接完成../Docs/DevLogs/Day9.md:⭐ musl 工具链修复 + 板上测试通过../Docs/task_complete.md:完整任务清单与进度条(97% 完成)../Docs/implementation_plan_complete.md:实现计划 & 各阶段目标拆解
8. 任务完成度与后续工作
8.1 当前完成度(参考任务清单与总结)
- SDK/工具链/固件:✅
- musl 工具链修复:✅ (Day 9 关键突破)
- 音频采集 & 播放:✅
- IMU 采集:✅ (板上测试通过)
- 摄像头采集:✅ (板上测试通过)
- UDP / HTTP / WebSocket 基础:✅(库与客户端实现已完成)
- WiFi 网络配置:✅ (192.168.110.132)
- 板端硬件测试:✅ (所有模块通过)
- 网络服务器通信测试:⏳(服务器已部署,待测试)
- 性能评估与稳定性验证:⏳(待完成)
整体项目 97% 完成,核心功能全部验证通过!🎉
8.2 建议的后续 TODO
- 将服务器 IP / 端口、音频参数、帧率等抽象为配置文件(JSON / INI)
- 丰富错误日志并加上日志轮转
- 对 WebSocket / HTTP 加入重连与指数退避策略
- 若后续量产,考虑:
- 用硬件 SPI 替换 GPIO bit‑bang
- 对功耗与休眠策略进行优化
- 引入简单看门狗机制,防止长期运行卡死
9. 如何使用本 README
- 新成员上手:从本 README 入手,结合
../Docs/DevLogs/DayX.md逐步了解每个子系统的设计与坑点。 - 以后复用到新项目:可以直接复制「编译流程」「外设接线 + DTS 配置」「主程序多线程架构」这几部分,稍作修改即可移植到其他全志 / RISC‑V 设备。
- 代码导航入口:按模块查找
src/audio,src/imu,src/camera,src/network目录,结合对应的 DayX 日志阅读。
祝使用愉快 🎉,也欢迎在后续开发阶段继续补充和更新本 README。