拿到小鸿 AI 源码后,最先要解决的不是“怎样改界面”,而是“当前硬件究竟由哪套工程生成固件”。同一棵源码树里同时存在xiaohong、xiaohong-se和xiaohong-p4,三个名字很接近,却分别对应不同硬件角色、构建入口和产物格式。选错目录以后,即使代码能编译,也可能根本没有进入正在烧录的镜像。
本文依据当前本地检出的OpenHarmony-6.1.0.31-Release分支进行核对。当前业务源码含有未提交修改,因此文章没有把基础提交号冒充完整实现版本,而是在配套的源码快照中记录每个引用文件的 SHA-256。正文中的配置和 C 代码均摘自这些文件;目录树和验证清单属于解释性材料,会明确标注用途。
先确认这是 OpenHarmony 小型系统项目
当前小鸿本体不是 ArkTS、Stage 模型或 HAP 应用。vendor/atomgit/xiaohong/config.json给出的type是mini,kernel_type是liteos_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按键选择当前调试目标。它仍然是 OpenHarmonymini + 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_name和board锁定产品与板级入口,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.c、lvgl_task.c和lvgl_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 successfully或Execution Successful,只能证明本次选择的镜像走完写入流程。它不能证明 LCD 初始化执行、GPIO 所有权正确、按键产生事件、Wi-Fi 成功连接或 CI1302 音频链路正常。历史上出现过 GPIO14 被误作按键后屏幕黑掉的情况,而 BurnTool 仍然可以完成写入;这正是分层验收的必要性。
一轮修改应分别留下四类结论:源码层确认产品和构建收录;构建层确认命令与产物;写入层确认工具、芯片和本次日志;运行层确认串口版本标识以及本次变更涉及的屏幕、按键、网络或音频。上一层通过只能允许进入下一层,不能自动替代下一层。
四种常见误判及其排除顺序
- 修改了仓库里的显示示例,但该文件没有进入当前产品
BUILD.gn。应从产品目标反向检查sources,而不是继续修改同名示例。 - 在小鸿 SE 上没有切换
P4/WS63调试口。Windows 能看到串口,不代表串口后面就是当前准备烧录的芯片。 - 把 BurnTool 控制台中上一次操作的错误当成本次结果。应记录本次开始时间、包名和日志时间,先分离历史输出。
- 看到写入完成后屏幕不亮,立即判断硬件损坏。应先恢复已知良好包,再比较应用镜像、板级初始化和 GPIO 所有权。
这些误判都来自证据链断裂:不知道修改的文件是否进入产物,不知道写入的是哪一包,也不知道设备当前运行哪一版。给固件加入可见版本标识,并记录包哈希,可以显著缩短排查路径。
本文已经确认和仍未确认的边界
本文已经从当前文件确认:小鸿本体是 OpenHarmonymini + LiteOS-M的 WS63 产品;xiaohong-se是 SE 的 WS63 侧;xiaohong-p4是 ESP32-P4/ESP-IDF 侧;当前业务库通过BUILD.gn收录;主任务使用 CMSIS-RTOS2 消息队列;两个 WS63 产品的标准完整产物都是.fwpkg。
本文没有宣称当前脏工作区完成了新的干净全量构建,也没有用旧官方截图证明本机实测。当前候选固件和实机功能会在对应主题文章中分别记录。下一篇将只从当前板级源码能够支持的范围,梳理 WS63、CI1302、ST7789、外部 W25Q128、按键、电池采样和共享 SPI;没有原理图证据的连接关系不会被包装成原理图级结论。