Files
Docs/DevLogs/Day06.md
2026-01-05 18:06:08 +08:00

13 KiB
Raw Permalink Blame History

Avaota F1 开发日志 - Day 6硬件全功能验证与网络库诊断

版本v1.0
日期2025-12-01
主机环境Windows + Ubuntu 24.04 LTS
目标平台Avaota F1 (全志 V821 / 32-bit RISC-V)


📅 今日目标

  1. 硬件功能验证在不依赖网络的情况下验证摄像头、IMU 和音频硬件的完整功能。
  2. 本地测试程序:开发并运行 avaota_test,独立测试各个模块。
  3. 问题诊断:解决麦克风录音报错、扬声器无声以及网络库编译失败的问题。

🏆 核心成就:硬件验证通过

经过今天的调试核心硬件模块摄像头、IMU、麦克风已全部验证通过

1. 📷 摄像头 (GC2083) - 完美工作

  • 测试结果:成功捕获 10 帧 JPEG 图像。
  • 图像质量:文件大小在 21KB - 79KB 之间ISP 自动曝光和白平衡工作正常。
  • 技术细节
    • 使用 Allwinner MPP (Media Process Platform) 框架。
    • VI (Video Input) -> ISP (Image Signal Processor) -> VENC (Video Encoder)。
    • 分辨率1280x720 @ 20fps。

2. 🧭 IMU (ICM-42688-P) - 完美工作

  • 测试结果:成功初始化并读取 100 组数据。
  • 数据准确性
    • WHO_AM_I:读取到 0x47,芯片识别正确。
    • 加速度Z轴/Y轴 接近重力加速度 (9.8 m/s²),符合静止状态。
    • 陀螺仪:静止时数值接近 0噪声极低。
    • 温度:读数稳定在 20.3°C 左右。
  • 连接方式GPIO 模拟 SPI (SCLK=PD3, MOSI=PD2, MISO=PD4, CS=PD5)。

3. 🎤 麦克风 (板载模拟) - 完美工作

  • 测试结果:成功录制 5 秒音频。
  • 关键修复
    • 问题:使用 hw:0,0 报错 read error: I/O error
    • 解决:改用 plughw:0,0 设备ALSA 插件自动处理格式转换。
    • 配置:通过 setup_mic.sh 脚本启用 MIC Switch 并设置 MIC Gain 为 25。
  • 文件验证:录音文件大小约 145KB (5秒 x 16000Hz x 2字节),符合预期。

4. 🔊 扬声器 (MAX98357A) - ⚠️ 硬件配置缺失

  • 现状:软件驱动正常加载 (sndi2s0 存在),播放命令无报错,但无声音输出。
  • 原因诊断
    • 通过 pinmux 检查发现 PD12/PD13/PD15 引脚状态为 UNCLAIMED
    • 结论:当前固件的 Device Tree 中缺失了 I2S 的 pinctrl 配置,导致引脚未复用为 I2S 功能。
  • 后续计划:需要修改 Device Tree 并重新编译烧录固件(暂缓,优先网络集成)。

🛠️ 软件开发成果

1. 本地测试套件

为了隔离网络问题,开发了独立的测试工具链:

  • src/main_test.cpp:多线程测试程序,独立运行 Camera、Audio、IMU 线程。
  • src/Makefile_test:静态链接构建配置,确保在板端无依赖运行。
  • build_test.sh:一键编译脚本。

2. 实用调试脚本

  • setup_mic.sh:一键配置麦克风 Mixer 参数Switch, Gain, ADC Volume
  • fix_speaker.sh:一键配置扬声器 Mixer 参数LINEOUT, DAC Volume
  • diagnose_mic.sh:导出所有 ALSA 控件状态,用于排查音频路由。
  • debug_network_libs.sh:详细诊断 SDK 编译错误。

🐛 问题与解决方案

问题 1麦克风 read error: I/O error

  • 现象arecord -D hw:0,0 报错。
  • 原因:硬件设备对缓冲区或格式有严格限制,直接访问 hw 设备容易出错。
  • 解决:使用 plughw:0,0,利用 ALSA 的 plug 插件进行软件适配。

问题 2扬声器无声

  • 现象aplay 正常运行但无声,白噪音测试也无声。
  • 排查
    1. 检查驱动:lsmod 显示驱动已加载。
    2. 检查 Mixeramixer 显示所有开关已打开,音量最大。
    3. 检查引脚:/sys/kernel/debug/pinctrl/.../pinmux-pins 显示 PD12/13/15 为 UNCLAIMED
  • 结论:固件 Device Tree 缺少 I2S 引脚配置。

问题 3libuwsc 编译失败

  • 现象SDK 中编译 libuwsc 报错。
  • 诊断:运行 debug_network_libs.sh 发现大量依赖缺失警告(如 libtmedia, libcedarx 等)。
  • 原因libuwsc 的 Makefile 可能错误地依赖了全志的多媒体库,或者 SDK 环境未完全准备好。
  • 后续:需要清理 libuwsc 的依赖或寻找替代方案。

📝 下一步计划 (Day 7)

鉴于硬件验证已完成(除扬声器需改固件外),接下来的重点回归网络集成

  1. 解决网络库问题
    • 尝试修复 libuwsc 编译(去除不必要的依赖)。
    • 或者:直接将 libuwsc 源码集成到项目中编译(推荐,更可控)。
  2. 系统集成
    • 将验证通过的 Camera、IMU、Audio 模块与 WebSocket 客户端集成。
    • 实现数据上报和指令接收。
  3. 功能联调
    • 连接服务器,进行端到端测试。

总结Day 6 是里程碑式的一天,我们排除了硬件故障的疑虑,确认了核心传感器的可用性,为最终的系统集成打下了坚实基础。

Day 6 完成报告 - 网络库集成

日期: 2025-12-02
状态: 完成


📝 工作总结

根据 Day6.md 的计划,今天完成了以下核心工作:

1. 解决 libuwsc 编译问题

问题诊断

  • SDK 中 libuwsc 包未编译,无源码包
  • make package/feeds/libs/libuwsc/compile 编译失败
  • 无法访问 GitHub 下载源码

解决方案 采用轻量级自实现方案,完全替换 libuwsc

  • 实现了基于原生 socket 的 WebSocket 客户端
  • 支持 HTTP Upgrade 握手RFC 6455
  • 支持帧的发送和接收TEXT、BINARY、PING/PONG、CLOSE
  • 使用 OpenSSL 进行 Base64 编码

代码修改

  • src/network/ws_client.h - 重写头文件380 行 → 108 行)
  • src/network/ws_client.cpp - 重写实现212 行 → 400 行)
  • src/Makefile - 移除 -luwsc -lev,添加 -lssl -lcrypto
  • build_main.sh - 更新库检查逻辑

优点

  • 零外部依赖(除 OpenSSLSDK 已包含)
  • 代码完全可控,易于调试
  • 针对项目需求优化
  • 接口兼容,main.cpp 无需修改

🔧 技术实现细节

WebSocket 客户端核心功能

1. 连接与握手

// 1. TCP 连接
socket()  connect()

// 2. HTTP Upgrade 请求
GET /ws/camera HTTP/1.1
Host: 192.168.110.188:8081
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: <base64-random>
Sec-WebSocket-Version: 13

// 3. 验证响应
HTTP/1.1 101 Switching Protocols

2. 帧格式实现

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+

3. 线程模型

主线程 → connect() → 启动接收线程
                  ↓
            recv_thread (循环接收帧)
                  ↓
            解析帧 → 放入接收队列
                  ↓
主线程 → poll_messages() → 处理消息

📦 编译与部署

编译步骤

在 Ubuntu 服务器上执行:

# 1. 进入项目目录
cd ~/ProgramFiles/AvaotaF1/avaota_app_demo

# 2. 上传最新代码
# (从 Windows 通过 WinSCP 或 scp 上传)

# 3. 执行编译脚本
./build_main.sh

预期输出

=========================================
AvaotaF1 Client Build Script
=========================================

1. 设置编译环境...
2. 检查依赖库...
  ✓ libssl.so 存在
  ✓ libcrypto.so 存在
  ✓ libcurl.so 存在
  ✓ libasound.so 存在

3. 开始编译...
清理旧的编译文件...
编译 avaota_client...
...
✅ 编译成功!
=========================================

输出文件:
  ../build/bin/avaota_client

部署到设备

# 上传程序
scp build/bin/avaota_client root@192.168.110.100:/root/

# SSH 连接到设备
ssh root@192.168.110.100

# 运行程序
./avaota_client

🧪 功能测试清单

必备前置条件

  1. 服务器端准备

    • WebSocket 服务器运行在 192.168.110.188:8081
    • 提供以下端点:
      • /ws/camera - 接收 JPEG 帧
      • /ws_audio - 接收音频流
      • /stream.wav - 提供 TTS 音频
    • UDP 监听端口 12345 - 接收 IMU 数据
  2. 设备端检查

    # 检查摄像头
    ls /dev/video0
    
    # 检查音频设备
    arecord -l
    
    # 检查网络连接
    ping 192.168.110.188
    

测试步骤

1. 启动测试

./avaota_client

预期日志

========================================
AvaotaF1 Client Starting...
Server: 192.168.110.188:8081
========================================
[CAM] Thread started
[CAM] Camera initialized successfully
[AUD-CAP] Thread started
[AUD-CAP] Microphone initialized
[AUD-PLAY] Thread started
[IMU] Thread started
[IMU] ICM42688 WHO_AM_I: 0x47
[WS] TCP connected to 192.168.110.188:8081
[WS] Handshake successful
[WS] WebSocket connected to ws://192.168.110.188:8081/ws/camera
[CAM] WebSocket connected
...

2. 摄像头测试

  • 服务器接收到 JPEG 帧
  • 帧率在 15-20 fps
  • 图像质量正常

3. 麦克风测试

  • 服务器接收到 PCM 音频数据
  • 数据格式S16_LE, 16kHz, mono
  • 无明显延迟(< 200ms

4. IMU 测试

  • 服务器接收到 UDP JSON 数据
  • 数据格式正确
  • 更新频率约 50 Hz

5. 稳定性测试

  • 运行 10 分钟无崩溃
  • CPU 使用率 < 80%
  • 内存使用 < 100MB

🐛 已知问题

1. 扬声器无声 ⚠️

状态: 预期(硬件配置未完成)
原因: Device Tree 中 I2S 引脚未配置
计划: Day 7 修复

2. WebSocket 重连逻辑

状态: 部分实现
当前: 连接断开后会尝试重连,但无退避策略
优化: 添加指数退避算法


📊 性能指标

指标 目标 预期
摄像头帧率 15-20 fps
音频延迟 < 200ms
IMU 频率 50 Hz
CPU 使用率 < 80% 待测试
内存使用 < 100MB 待测试

📁 文件清单

修改的文件

  • src/network/ws_client.h (重写)
  • src/network/ws_client.cpp (重写)
  • src/Makefile (更新链接库)
  • build_main.sh (更新库检查)

未修改的文件

  • src/main.cpp (接口兼容)
  • src/network/http_client.cpp
  • src/network/udp_sender.cpp
  • src/camera/camera.cpp
  • src/audio/audio_capture.cpp
  • src/audio/audio_player.cpp
  • src/imu/icm42688.cpp

🚀 下一步计划

Day 7 目标

  1. 功能测试: 完整的端到端测试
  2. 性能优化: CPU/内存使用优化
  3. 扬声器修复: 修改 Device Tree 并重新烧录固件
  4. 错误处理: 完善重连和异常恢复逻辑

长期优化

  • 添加配置文件支持
  • 实现自适应帧率
  • 添加日志轮转
  • 实现看门狗机制

📞 编译问题排查

问题1: OpenSSL 库缺失

# 检查
ls -la /home/rongye/ProgramFiles/AvaotaF1/avaota_sdk/tina-v821-release/out/v821/avaota_f1/openwrt/staging_dir/target/usr/lib/libssl.*

# 如果缺失,在 SDK 中编译 OpenSSL
cd ~/ProgramFiles/AvaotaF1/avaota_sdk/tina-v821-release
source build/envsetup.sh
make menuconfig  # 启用 Libraries → SSL → openssl
make package/libs/openssl/compile V=s

问题2: 链接错误

undefined reference to `SHA1'

解决: 确保 Makefile 中 -lssl -lcrypto-lpthread 之前

问题3: 运行时错误

error while loading shared libraries: libssl.so.1.1

解决: 使用静态链接Makefile 中已配置 -static


总结: Day 6 核心任务完成,网络库问题已解决,代码准备就绪,等待上传编译测试。