OpenHarmony 小鸿 AI 开发实战 01:先认对工程,WS63 与 ESP32-P4 路径怎么选

拿到小鸿 AI 源码后,最先要解决的不是"怎样改界面",而是"当前硬件究竟由哪套工程生成固件"。同一棵源码树里同时存在 xiaohongxiaohong-sexiaohong-p4,三个名字很接近,却分别对应不同硬件角色、构建入口和产物格式。选错目录以后,即使代码能编译,也可能根本没有进入正在烧录的镜像。

本文依据当前本地检出的 OpenHarmony-6.1.0.31-Release 分支进行核对。当前业务源码含有未提交修改,因此文章没有把基础提交号冒充完整实现版本,而是在配套的源码快照中记录每个引用文件的 SHA-256。正文中的配置和 C 代码均摘自这些文件;目录树和验证清单属于解释性材料,会明确标注用途。

++先确认这是 OpenHarmony 小型系统项目++

当前小鸿本体不是 ArkTS、Stage 模型或 HAP 应用。vendor/atomgit/xiaohong/config.json 给出的 typeminikernel_typeliteos_m,SoC 第三方目录指向 hisilicon/ws63v100/sdkv106。业务组件由 GN 文件收录,最终生成 WS63 使用的 .fwpkg。因此这套系列文章统一使用 OpenHarmony、开源鸿蒙、LiteOS-M、HB/GN 和 WS63 的术语。

配置文件里还保留了 ohos_version: OpenHarmony 1.0。这个字段是产品配置的一部分,但不能单独代表当前整棵源码的发布版本。版本定位需要同时记录 manifest/检出分支、产品配置、构建日志和源文件快照。当前文章采用的分支是 OpenHarmony-6.1.0.31-Release,这比只截取一个兼容字段更准确。

++三套目录对应三种硬件角色++

vendor/atomgit/xiaohong 面向小鸿本体的 WS63 主线。当前实物调试、240×240 屏、三个顶部按键、CI1302 音频和联网 Agent 都从这条路径继续追踪。

vendor/atomgit/xiaohong-se 是小鸿 SE 的 WS63 侧。其 README 明确写明,SE 板右侧 TTL Type-C 口由 ESP32-P4 与 WS63 复用,需要通过板上的 P4/WS63 按键选择当前调试目标。它仍然是 OpenHarmony mini + LiteOS-M 产品,但增加了与 P4 协作的代码。

vendor/atomgit/xiaohong-p4 是小鸿 SE 的 ESP32-P4 侧,使用 ESP-IDF/CMake 结构。该目录中的启动、分区和 .bin 产物不能交给 WS63 BurnTool。当前小鸿本体也不会因为仓库里存在 P4 工程就自动变成双芯运行。

用于搜索的工程树可以写成下面这样。这是从当前目录结构压缩出的导航图,不是仓库中的一段程序代码。

复制代码
vendor/atomgit/
├─ xiaohong/                 # 小鸿本体:WS63 / OpenHarmony mini / LiteOS-M
│  ├─ config.json
│  └─ xiaohong/
│     ├─ BUILD.gn
│     └─ src/
├─ xiaohong-se/              # 小鸿 SE 的 WS63 侧
│  ├─ config.json
│  └─ xiaohong/src/audio/esp32p4/
└─ xiaohong-p4/              # 小鸿 SE 的 ESP32-P4 侧
   └─ esp32_app/
      ├─ CMakeLists.txt
      ├─ main/
      └─ components/

++用 config.json 锁定产品、内核和 SDK++

下面的 JSON 是当前 vendor/atomgit/xiaohong/config.json 的真实字段摘录,字段名和值没有为文章重新命名。product_nameboard 锁定产品与板级入口,kernel_type 说明内核为 LiteOS-M,third_party_dir 指向当前 WS63 SDK v106,product_adapter_dir 则回到小鸿 HAL 适配目录。

复制代码
{
  "product_name": "xiaohong",
  "type": "mini",
  "ohos_version": "OpenHarmony 1.0",
  "device_build_path": "device/board/atomgit/xiaohong",
  "board": "xiaohong",
  "kernel_type": "liteos_m",
  "third_party_dir": "//device/soc/hisilicon/ws63v100/sdkv106/open_source",
  "product_adapter_dir": "//vendor/atomgit/xiaohong/hals"
}

遇到"改了代码但设备没有变化"时,先返回产品配置,而不是继续堆日志。只要当前 hb set 选中的不是这个产品,后续对 xiaohong/xiaohong/src 的修改就不一定进入当前输出目录。

++BUILD.gn 决定哪些源码真正进入固件++

全仓搜索只能证明"文件存在",不能证明"文件被构建"。当前 vendor/atomgit/xiaohong/xiaohong/BUILD.gn 使用 static_library("xiaohong") 收录业务源码,并定义 SUPPORT_OHOS=1。板级配置为 xiaohong_ws63_v1 时,才加入对应的板级初始化、按键和 W25Q128 驱动。

复制代码
static_library("xiaohong") {
  sources = [
    "src/main.c",
    "src/task_entry.c",
    "src/settings.c",
  ]
  defines = [
    "FW_VERSION=0x010001",
    "SUPPORT_OHOS=1",
  ]

  if (config_board_name == "xiaohong_ws63_v1") {
    defines += [ "BOARD_XH_WS63_V1" ]
    sources += [
      "src/boards/xiaohong_ws63_v1/board_config.c",
      "src/boards/xiaohong_ws63_v1/key_config.c",
      "src/boards/xiaohong_ws63_v1/w25q128.c",
    ]
  }
}

该代码块来自当前文件的连续片段,只省略了与本段无关的后续模块。显示侧还能在同一文件看到 disp_driver.clvgl_task.clvgl_ui_layout.c,音频侧能看到 CI1302 监听、播放、Opus 上行和下行文件,协议侧能看到 mongoose_protocol.c。这就是为什么判断源码归属时要从 BUILD.gn 反向追踪,而不是凭同名文件猜测。

++main.c 展示的是 OpenHarmony LiteOS-M 消息队列入口++

当前 vendor/atomgit/xiaohong/xiaohong/src/main.c 声明了主、音频、显示和 Agent 四类 CMSIS-RTOS2 消息队列。按键回调不会直接执行所有业务,而是把事件送入主队列,再由 MainTask 分发。下面的代码是当前文件中的真实实现。

复制代码
osMessageQueueId_t g_main_event_qid = NULL;
osMessageQueueId_t g_audx_event_qid = NULL;
osMessageQueueId_t g_disp_event_qid = NULL;
osMessageQueueId_t g_agent_event_qid = NULL;

uint32_t key_event_callback_cb(uint8_t event)
{
    if (g_main_event_qid) {
        osMessageQueuePut(g_main_event_qid, (const void *) &event, 0, 0);
    }
    return 0;
}

队列创建也位于同一个任务启动过程:音频队列、显示队列、主队列和 Agent 队列分别设置容量,任一关键队列创建失败都会记录错误并保留早期显示。这个实现说明"小鸿本体按键无响应"至少要核对按键采样、回调、主队列和事件分支四层,不能只盯着 LVGL 页面。

++HB 选择目标时不要复用未知缓存++

WS63 的完整构建从 OpenHarmony 源码根目录执行。官方 README 给出的主流程是先用 hb set 选择 mini 和对应产品,再执行 hb build -f。下面命令适用于已经准备好 OpenHarmony 构建环境的 Linux/WSL Shell;它不是 PowerShell 命令。

复制代码
hb set
hb build -f

# 小鸿本体输出目录
ls -lh out/xiaohong/xiaohong/ws63-liteos-app/

# 小鸿 SE 的 WS63 输出目录
ls -lh out/xiaohong/xiaohong-se/ws63-liteos-app/

第二个输出路径已由 xiaohong-se/README_CN.md 当前内容复核。构建时不能只看到终端出现 success 就结束记录,至少还应保存分支、产品选择、命令、结束状态、输出文件名、字节数和 SHA-256。如果使用增量构建,还要额外说明它不是一次干净全量构建。

++产物格式和芯片决定下载工具++

小鸿本体与小鸿 SE 的 WS63 侧最终都进入 ws63-liteos-app_all.fwpkg,对应 WS63 BurnTool。小鸿 SE 的 P4 侧则由 ESP-IDF 生成 bootloader、partition table 和应用 .bin,需要切换调试口并按 ESP-IDF 生成的 flash 参数写入。

复制代码
xiaohong / WS63
  -> ws63-liteos-app_all.fwpkg
  -> WS63 BurnTool

xiaohong-se / WS63 side
  -> ws63-liteos-app_all.fwpkg
  -> TTL 切到 WS63 -> WS63 BurnTool

xiaohong-p4 / ESP32-P4 side
  -> bootloader.bin + partition-table.bin + application.bin
  -> TTL 切到 P4 -> ESP-IDF 下载链

这里的文本块是工具映射,不是源码。它的依据来自两个 WS63 产品 README 以及 P4 工程的 CMake/ESP-IDF 目录结构。文章刻意不写固定分区地址,因为 P4 的实际地址应读取当前构建生成的 flash 参数,不能从别的版本照抄。

++写入成功不能替代设备功能验证++

BurnTool 显示 All images burn successfullyExecution Successful,只能证明本次选择的镜像走完写入流程。它不能证明 LCD 初始化执行、GPIO 所有权正确、按键产生事件、Wi-Fi 成功连接或 CI1302 音频链路正常。历史上出现过 GPIO14 被误作按键后屏幕黑掉的情况,而 BurnTool 仍然可以完成写入;这正是分层验收的必要性。

一轮修改应分别留下四类结论:源码层确认产品和构建收录;构建层确认命令与产物;写入层确认工具、芯片和本次日志;运行层确认串口版本标识以及本次变更涉及的屏幕、按键、网络或音频。上一层通过只能允许进入下一层,不能自动替代下一层。

++四种常见误判及其排除顺序++

  • 修改了仓库里的显示示例,但该文件没有进入当前产品 BUILD.gn。应从产品目标反向检查 sources,而不是继续修改同名示例。
  • 在小鸿 SE 上没有切换 P4/WS63 调试口。Windows 能看到串口,不代表串口后面就是当前准备烧录的芯片。
  • 把 BurnTool 控制台中上一次操作的错误当成本次结果。应记录本次开始时间、包名和日志时间,先分离历史输出。
  • 看到写入完成后屏幕不亮,立即判断硬件损坏。应先恢复已知良好包,再比较应用镜像、板级初始化和 GPIO 所有权。

这些误判都来自证据链断裂:不知道修改的文件是否进入产物,不知道写入的是哪一包,也不知道设备当前运行哪一版。给固件加入可见版本标识,并记录包哈希,可以显著缩短排查路径。

++本文已经确认和仍未确认的边界++

本文已经从当前文件确认:小鸿本体是 OpenHarmony mini + LiteOS-M 的 WS63 产品;xiaohong-se 是 SE 的 WS63 侧;xiaohong-p4 是 ESP32-P4/ESP-IDF 侧;当前业务库通过 BUILD.gn 收录;主任务使用 CMSIS-RTOS2 消息队列;两个 WS63 产品的标准完整产物都是 .fwpkg

本文没有宣称当前脏工作区完成了新的干净全量构建,也没有用旧官方截图证明本机实测。当前候选固件和实机功能会在对应主题文章中分别记录。下一篇将只从当前板级源码能够支持的范围,梳理 WS63、CI1302、ST7789、外部 W25Q128、按键、电池采样和共享 SPI;没有原理图证据的连接关系不会被包装成原理图级结论。

相关推荐
天空'之城3 小时前
C 语言工业级通用组件手写 15:累加和校验
c语言·嵌入式开发·工业级组件·累加和校验
天空'之城1 天前
C 语言工业级通用组件手写 08:精准软件消抖
c语言·嵌入式开发·工业级组件·软件消抖·按键防抖
天空'之城3 天前
C 语言工业级通用组件手写 09:CRC32 数据校验
c语言·嵌入式开发·数据校验·crc32·工业级组件
天空'之城3 天前
C 语言工业级通用组件手写 06:固定块内存池
c语言·嵌入式开发·内存池·底层优化
天空'之城6 天前
C 语言工业级通用组件手写 04:阻塞队列
c语言·嵌入式开发·阻塞队列·多线程开发
俊基科技6 天前
对话越嘈杂,听得越清晰:A-29P 让每一台通话设备都装上 “AI 听觉大脑”
嵌入式开发·硬件开发·ai降噪·回声消除·定向拾音·拾音降噪·双麦波束
北京麟卓7 天前
卓奕引擎×OrangePi 5B开发板 | 面向开源鸿蒙的一站式安卓兼容验证方案
openharmony·安卓应用兼容
天空'之城7 天前
C 语言工业级通用组件手写 03:双向链表
c语言·嵌入式开发·双向链表
天空'之城7 天前
VS Code Git 工作树:告别频繁切分支,实现多分支并行开发实战方案
git·vscode·版本控制·嵌入式开发·开发效率·worktree·多分支管理