OMI 消费版固件完全解析:基于 nRF Connect SDK 2.9.0 的 nRF5340 双核架构、编译流程与模块开发状态
2026/9/16 16:39:23 网站建设 项目流程

OMI 消费版固件完全解析:基于 nRF Connect SDK 2.9.0 的 nRF5340 双核架构、编译流程与模块开发状态

【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend

OMI 消费版(Consumer Version)固件是这款"看得见屏幕、听得见对话的 AI 可穿戴设备"的硬件大脑,本文以 omi/firmware/omi/README.md 为主线,结合仓库内的构建配置、源码与板级定义,系统讲解其基于 Zephyr RTOS / nRF Connect SDK(NCS)的编译方法、双核 nRF5340 架构、BLE 音频流链路,以及麦克风、蓝牙、按键、LED、SD 卡、触觉马达等模块的生产状态与已知待办。读完本文,你将掌握该固件的完整编译配置、各核心模块的实现原理,以及当前版本的已知问题与演进方向。

一、项目定位与文档概览

omi/firmware/omi/目录下存放的是 OMI 消费版(与开发者使用的 DevKit 版本相对)的固件工程。根目录的 README.md 给出了最核心的三条信息:

  1. 软件栈:基于nRF Connect SDK 2.9.0(NCS,Nordic 基于 Zephyr 的发行版);
  2. 应用与目标板:应用名为omi,目标板为omi/nrf5340/cpuapp(nRF5340 双核 Cortex-M33 的应用核);
  3. 当前状态WIP——已在生产环境运行(running on production),但仍缺少部分增强功能(missing some enhancement)。

该 README 是固件开发与烧录的入口文档:编译步骤以官方文档为参考,而仓库内 CMakePresets.json、omi.conf、Kconfig、sysbuild.conf 等文件则提供了可直接落地的完整配置。

注意:README 强调了一个对新手非常关键的目录陷阱——必须在代码编辑器中打开firmware文件夹,而不是仓库根目录omi文件夹。否则 West 无法识别工程、找不到目标板("otherwise West wouldn't recognize the project and won't find your board")。

二、环境要求与编译方法

2.1 版本与工具链要求

根据 README 及仓库内 BUILD_AND_OTA_FLASH.md,编译该固件需要:

组件要求
nRF Connect SDK2.9.0v2.9.0
目标板omi/nrf5340/cpuapp
构建工具West(Zephyr 元工具)、CMake ≥ 3.20.0、Ninja
其他Python 3.8+、ccache、nrfutil(可选,用于工具链管理)

由于固件基于 Zephyr RTOS 且涉及双核、MCUboot、OPUS 编解码等复杂组件,README 明确它不是 Arduino IDE 能编译的工程,需要完整的 NCS 工具链(见 readme.md)。

2.2 工作区初始化

NCS 通过 West 管理多仓库工作区。仓库中的 BUILD_AND_OTA_FLASH.md 给出了完整流程:先用nrfutil toolchain-manager install --ncs-version v2.9.0安装 SDK,再启动工具链 shell,在v2.9.0目录下执行:

nrfutil toolchain-manager launch --ncs-version v2.9.0 --shell west init -m https://github.com/nrfconnect/sdk-nrf --mr v2.9.0 west update

west update会下载约 1.5GB 的源码,包括 Zephyr RTOS、NCS 模块、MCUboot 引导程序等。

2.3 编译命令与 CMake Presets

README 推荐使用工程自带的 CMakePresets.json 来编译。该文件定义了OMI预设:

{ "version": 2, "cmakeMinimumRequired": { "major": 3, "minor": 20, "patch": 0 }, "configurePresets": [ { "name": "OMI", "displayName": "OMI", "configuration": "Debug", "generator": "Ninja", "binaryDir": "${sourceDir}/build/omi", "cacheVariables": { "CMAKE_EXPORT_COMPILE_COMMANDS": "YES", "CMAKE_BUILD_TYPE": "Debug", "BOARD": "omi/nrf5340/cpuapp", "CACHED_CONF_FILE": "${sourceDir}/omi.conf", "CONF_FILE": "${sourceDir}/omi.conf" } } ] }

从中可以读出三个关键信息:

  • Boardomi/nrf5340/cpuapp,对应仓库中 boards/omi/ 目录下的板级定义(omi_nrf5340_cpuapp_defconfigomi_nrf5340_cpuapp.dts等);
  • 配置文件指向 omi.conf,而非 Zephyr 默认的prj.conf(这也是 BUILD_AND_OTA_FLASH.md 中提示cp omi.conf prj.conf的原因);
  • 输出目录固定在build/omi,采用 Ninja 生成器与 Debug 构建类型。

在 NCS 环境内手动编译的等价命令为:

west build -b omi/nrf5340/cpuapp ../omi --sysbuild -- -DBOARD_ROOT=/path/to/omi/firmware

--sysbuild会串联构建 MCUboot、网络核固件(ipc_radio)与网络核引导(b0n),最终生成经 RSA 签名并打包的 OTA 固件(详见下文第六节)。

三、工程结构与源码组织

3.1 目录布局

readme.md 说明了firmware/的整体结构:

  • omi/:消费版主应用工程(本文主角);
  • devkit/:Omi DevKit1 / DevKit2 开发套件工程;
  • test/:测试工程;
  • boards/:自定义板级定义(nRF5340 双核的分区、引脚、SRAM 共享等);
  • scripts/:构建与工具脚本。

消费版应用内部由 CMakeLists.txt 组织,其源码分为两大块:

  • 应用源码src/顶层):main.cmic.cbattery.cled.chaptic.csd_card.cspi_flash.csettings.cfeedback.cwdog_facade.crtc.cimu.c,以及可选编译的t5838_aad.c(T5838 硬件 AAD 底层驱动);
  • 核心库源码src/lib/core/):config.hcodec.c(编解码)、transport.c(BLE 传输)、button.cmonitor.c,以及可选编译的storage.c(离线存储)。

OPUS 编解码器以源码形式内嵌在src/lib/core/lib/opus-1.2.1/,当CONFIG_OMI_CODEC_OPUS开启时通过add_subdirectory链接进固件。

3.2 主循环与事件流

src/main.c 展示了固件的核心数据流:PDM 麦克风数据经mic_handler进入codec_receive_pcm,由 OPUS 编码后的音频经codec_handler调用broadcast_audio_packets通过 BLE 推送。此外它还实现了复位原因打印(看门狗复位、NFC 唤醒、引脚复位、软件复位、CPU lockup 等)以及开机 LED 反馈序列(蓝色脉冲 = "I'm alive",绿色呼吸 = "Ready!"),这些细节对应 README 中 LED 模块的状态反馈需求。

四、核心配置逐项解读:omi.conf 与 Kconfig

4.1 全局配置骨架(omi.conf)

omi.conf 是消费版固件的完整 Kconfig 配置,按功能域可拆解为:

外设与内核基础:

CONFIG_SERIAL=y / CONFIG_GPIO=y / CONFIG_PWM=y / CONFIG_INPUT=y CONFIG_I2C=y / CONFIG_SPI=y / CONFIG_SPI_NOR=y CONFIG_SETTINGS=y / CONFIG_SETTINGS_NVS=y / CONFIG_NVS=y CONFIG_PM_DEVICE=y / CONFIG_ADC=y / CONFIG_ADC_ASYNC=y CONFIG_AUDIO=y / CONFIG_AUDIO_DMIC=y / CONFIG_FLASH=y CONFIG_MAIN_STACK_SIZE=4096 / CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 CONFIG_HEAP_MEM_POOL_SIZE=40000 CONFIG_WATCHDOG=y / CONFIG_WDT_DISABLE_AT_BOOT=n

音频链路采用 I2S + nRFX PDM:CONFIG_I2S=yCONFIG_I2S_NRFX=yCONFIG_AUDIO_DMIC_NRFX_PDM=yCONFIG_NRFX_PDM0=y。文件系统选用LittleFSCONFIG_FILE_SYSTEM_LITTLEFS=y),配置注释说明这是为 SD NAND 选择的掉电安全方案("power-loss safe, no FAT dirty-bit issues")。此外还挂载了 LSM6DSL 加速度计/陀螺仪(CONFIG_LSM6DSL=y),但生产固件中加速度计功能默认关闭(见下)。

BLE 与音频流关键参数(对应 README 中"音频字节丢失"问题):

CONFIG_BT_L2CAP_TX_MTU=498 CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 CONFIG_BT_CTLR_PHY_2M=y / CONFIG_BT_CTLR_PHY_CODED=y CONFIG_BT_L2CAP_TX_BUF_COUNT=20 / CONFIG_BT_BUF_ACL_RX_SIZE=1024 CONFIG_BT_BUF_ACL_TX_SIZE=2048 / CONFIG_BT_BUF_ACL_TX_COUNT=10 CONFIG_BT_ATT_TX_COUNT=20 # 首选连接参数:7.5ms ~ 15ms CONFIG_BT_PERIPHERAL_PREF_MIN_INT=6 CONFIG_BT_PERIPHERAL_PREF_MAX_INT=12 CONFIG_BT_PERIPHERAL_PREF_LATENCY=0 CONFIG_BT_PERIPHERAL_PREF_TIMEOUT=600

这些参数直接呼应 README 中关于音频字节丢失(约 30%)的修复记录:Android 端通过把 BLE 连接间隔收紧到7msPREF_MIN_INT=6,间隔单位 1.25ms)解决问题;而 iOS 不允许收紧连接间隔,可行间隔约为15msPREF_MAX_INT=12)。README 作者对此的评价是"100 rps、每包 50 字节并不是大事",暗示 Android 上的间隔调整更像是一个临时方案。

设备信息与电池服务:

CONFIG_BT_BAS=y / CONFIG_BT_DIS=y CONFIG_BT_DEVICE_NAME="Omi" CONFIG_BT_DIS_MODEL="Omi CV 1" / CONFIG_BT_DIS_MANUF="Based Hardware" CONFIG_BT_DIS_FW_REV_STR="3.0.21" / CONFIG_BT_DIS_HW_REV_STR="5.0"

OMI 功能开关(生产默认值):

CONFIG_OMI_CODEC_OPUS=y # OPUS 编解码 CONFIG_OMI_ENABLE_OFFLINE_STORAGE=y # 离线存储(SD 卡) CONFIG_OMI_ENABLE_BUTTON=y # 按键 CONFIG_OMI_ENABLE_BATTERY=y # 电池 CONFIG_OMI_ENABLE_HAPTIC=y # 触觉马达 CONFIG_OMI_ENABLE_RFSW_CTRL=y # 射频开关控制 CONFIG_OMI_ENABLE_T5838_AAD=y # T5838 硬件 AAD(超低功耗麦克风休眠) CONFIG_OMI_ENABLE_ACCELEROMETER=n # 加速度计默认关闭 CONFIG_OMI_ENABLE_SPEAKER=n # 扬声器默认关闭 CONFIG_OMI_ENABLE_USB=n # USB 默认关闭 CONFIG_OMI_ENABLE_MONITOR=n # 监控/指标系统默认关闭

4.2 OMI 功能菜单(Kconfig)

Kconfig 定义了上述开关的语义与默认值,其中较有特色的几项:

  • OMI_ENABLE_MONITOR:监控/指标系统,帮助文档明确建议生产环境关闭以省电、省 RAM 和 Flash("Disable in production to save power, RAM, and flash space"),与 omi.conf 中CONFIG_LOG=n、仅保留显式printk()的"最小化发布输出"策略一致;
  • OMI_ENABLE_T5838_AAD(硬件 AAD):静音一段时间后暂停 PDM 时钟,让 T5838 MEMS 麦克风进入内置的声学活动检测模式(约 15µA),由麦克风硬件监听声音并拉高 WAKE 引脚来唤醒。相关三个调参项:
    • OMI_VAD_ABS_THRESHOLD(默认 600,范围 1~32767):判定静音的绝对幅度阈值;
    • OMI_VAD_HOLD_MS(默认 3000,范围 500~30000):进入硬件 AAD 休眠前的持续静音时间;
    • OMI_AAD_SETTLE_MS(默认 800,范围 100~3000):进入 AAD 后、使能 WAKE 中断前的稳定等待时间,用于吞掉入口瞬态防止误唤醒。
    • 生产 omi.conf 中这三个值分别被设为250/10000/800
  • OMI_WATCHDOG_TIMEOUT_MS(默认 30000,范围 5000~300000):看门狗超时,注释提示在启动期存在较长操作(如 SD/LFS 预热)时应调大,避免误复位。

五、双核架构与安全启动(sysbuild)

nRF5340 是双核(双 Cortex-M33)SoC,本固件通过 sysbuild.conf 组织多镜像构建:

SB_CONFIG_BOOTLOADER_MCUBOOT=y SB_CONFIG_BOOT_SIGNATURE_KEY_FILE="${APP_DIR}/../bootloader/mcuboot/root-rsa-2048.pem" SB_CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y SB_CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y SB_CONFIG_SECURE_BOOT_NETCORE=y SB_CONFIG_MCUBOOT_UPDATEABLE_IMAGES=2 SB_CONFIG_MCUBOOT_NRF53_MULTI_IMAGE_UPDATE=y SB_CONFIG_NETCORE_APP_UPDATE=y SB_CONFIG_MCUBOOT_MODE_OVERWRITE_ONLY=y

要点:

  • 启用MCUboot,使用仓库内 bootloader/mcuboot/root-rsa-2048.pem 作为 RSA-2048 签名密钥;
  • 支持双镜像更新(应用核 + 网络核)、网络核安全启动SECURE_BOOT_NETCORE)、多镜像联合升级(NRF53_MULTI_IMAGE_UPDATE);
  • 采用overwrite-only升级模式。

配合 BUILD_AND_OTA_FLASH.md 中的内存布局说明,完整的双核分区为:应用核上 MCUboot(64KB)+ 应用主分区(982KB)+ 应用次分区(982KB,OTA 暂存)+ 设置/NVS;网络核上网络引导(34KB)+ 网络主分区(222KB)+ 网络次分区(222KB)。

板级定义位于 boards/omi/,其中omi_nrf5340_cpuapp_defconfigomi_nrf5340_cpuapp.dtsomi_nrf5340_cpunet.dtsomi-shared_sram.dtsiomi-cpuapp_partitioning.dtsipm_static.yml共同定义了双核各自的引脚、内存分区与共享 SRAM,是"每款硬件版本需要独立构建"(README 与 readme.md 均强调)的底层依据。

六、构建产物与 OTA 升级

6.1 构建产物

编译成功后,build/目录会产出(数据见 BUILD_AND_OTA_FLASH.md):

  • dfu_application.zip(约 440KB):给 nRF Connect 手机 App 用的主 OTA 包;
  • dfu_application.zip_manifest.json:包元数据;
  • merged.hex(约 869KB):完整固件,可直接编程器烧写;
  • signed_by_mcuboot_and_b0_ipc_radio.hex:签名后的应用固件;
  • merged_CPUNET.hex(约 533KB):网络核固件;
  • build_info.ymlpartitions.yml:构建配置摘要与分区布局;
  • 各子组件构建目录(omi/mcuboot/ipc_radio/b0n/)。

参考的编译内存占用(该文档示例数据):FLASH 262908 B / 982528 B(26.76%),RAM 244556 B / 440KB(54.28%)。

6.2 OTA 流程

OTA 升级依赖 omi.conf 中开启的CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=yCONFIG_MCUMGR_GRP_IMG_ALLOW_ERASE_PENDING=y。完整流程为:

  1. dfu_application.zip传输到手机;
  2. 打开 nRF Connect for Mobile,扫描并连接名为 "Omi" 的设备;
  3. 进入 DFU 标签页,选择dfu_application.zip并开始升级;
  4. 固件上传到次分区(约 2~3 分钟),随后校验、交换分区并自动重启。

升级期间设备重启后进入新固件即视为成功。MCUmgr 使用加密的 BLE 传输,配合 RSA-2048 签名实现安全升级与回滚保护。

七、模块开发状态与已知问题(WIP 清单全解)

README 的 WIP 章节是理解当前固件成熟度的核心,逐条解读如下:

7.1 新模块测试进度(7/9 通过)

模块状态说明
麦克风 Mic✅ 完成采集音频字节、激活第二颗麦克风
BLE✅ 完成音频流传输
按键 Buttons✅ 完成开关机(进入 deepsleep)、长按与 OMI 对话
LEDs✅ 完成充电、BLE 连接/断开状态反馈
Wi-Fi⚠️ 部分完成README 标注 "partially"
马达 Motors✅ 完成触觉反馈
QSPI Flash✅ 完成片外 SPI NOR 存储
IMU❌ 未完成惯性测量单元尚未完成测试
SD 卡✅ 完成文件存储 + BLE 传输

7.2 MCUboot 支持

已完成的子项包括:基础 MCUboot 集成、与 OMI App(iOS/Android)联调、以及纯电池供电(不带充电器)设备上的启动测试——这对可穿戴设备至关重要,因为不带充电器时无法通过外接供电掩盖功耗问题。

7.3 流式传输与转写(Streaming and Transcribing)

这是固件的核心业务链路,全部子项完成:

  • 麦克风采集音频字节;
  • 激活第二颗麦克风(双麦降噪/拾音);
  • BLE 传输;
  • OPUS 编码与发送(对应CONFIG_OMI_CODEC_OPUS与内嵌的 opus-1.2.1 源码);
  • 修复音频字节丢失问题(曾约 30% 丢包率):
    • Android:通过提高 BLE 连接间隔(7ms)修复,但作者坦承这并非理想方案("tbh i don't think this is a good solution"),因为 DevKit 在不调整连接间隔时也能正常工作;
    • iOS:系统不允许提高连接间隔(CI),可行的 CI 约为 15ms。

7.4 外围反馈:LED、按键、触觉

  • LED:充电、BLE 连接、BLE 断开三种状态均有反馈;已修复"充电 + 关机状态下只有绿灯、反馈不正确"的问题(充电功能本身正常)。
  • 按键:开关机(进入 deepsleep)、长按与 OMI 对话;deepsleep 模式下的电池耗电已测试。
  • 触觉(Haptic):开关机震动、长按对话震动;待办是复查量产版马达("the current motor is not good")。

7.5 存储与电量

  • SD 卡(2/3 完成):文件存储 ✅、通过 BLE 传输 ✅、通过 Wi-Fi 传输 ❌(未完成)。
  • 电池(1/2 完成):通过 BLE 上报电量百分比 ✅;修复充电时电量不准的问题❌。
  • 充电器:模块本身无未完成子项。

7.6 离线存储机制

readme.md 补充说明了离线存储的完整行为:只要设备与 App 无 BLE 连接,存储即自动激活;每次开机都会新建一个文件并开始写入 OPUS 编码数据;一旦连接 App,存储内容开始向 App 流式传输,传输完成后尝试删除设备上的文件。需要留意的是,离线存储包的格式与实时流式音频包不同。此外,调试文档提示离线存储当前为实验性功能,开启日志会占用 BLE 传输或 SD 卡写入性能(可设置CONFIG_LOG_PROCESS_THREAD_PRIORITY=5CONFIG_LOG_PROCESS_THREAD_CUSTOM_PRIORITY=y缓解)。

八、调试与开发建议

8.1 USB 串口调试

readme.md 给出了 DevKit2 上开启 USB 串口调试的方法,消费版同样适用:在对应.conf中开启CONFIG_CONSOLE=yCONFIG_PRINTK=yCONFIG_LOG=yCONFIG_LOG_PRINTK=yCONFIG_UART_CONSOLE=y,并用 nRF Serial Terminal(VS Code 扩展)查看输出;完整在线调试需要 J-Link 调试器。注意生产版 omi.conf 默认CONFIG_LOG=n,只保留显式printk()输出。

8.2 常见构建问题排查

  • ModuleNotFoundError: No module named 'cryptography':多半是没在 nrfutil 工具链 shell 内构建;
  • No board named 'omi' found:检查BOARD_ROOT是否指向firmware目录;
  • No prj.conf file found:先cp omi.conf prj.conf(或使用 CMakePresets,它会显式指定CONF_FILE=omi.conf);
  • 看门狗误复位:启动期有 SD/LFS 预热等长操作时调大OMI_WATCHDOG_TIMEOUT_MS

九、总结

OMI 消费版固件是一个典型的 Zephyr/NCS 双核可穿戴应用:nRF5340 应用核负责 OPUS 音频编码、BLE GATT 流式传输、离线 SD 存储与各外设管理,网络核承载 BLE 协议栈;MCUboot + RSA-2048 签名保障安全 OTA。README 中"production-ready 但仍有增强空间"的定位,与其 WIP 清单高度一致:核心音频链路(双麦采集 → OPUS 编码 → BLE 发送)已全部打通,Android 丢包问题通过连接间隔调优解决,而 iOS 间隔受限、Wi-Fi 传输、IMU、充电电量精度、量产马达手感等仍是后续迭代的重点方向。对想要深入 Zephyr 可穿戴固件开发或参与 OMI 固件改进的开发者,建议从 omi.conf 与 Kconfig 的 OMI 功能开关入手,配合 src/main.c 的主循环与 src/lib/core/transport.c 的 GATT 音频服务逐步阅读源码。

【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询