长期关注 ESP-Brookesia 这个项目,早前也反复上手摸索、尝试开发,但一直觉得整套系统架构偏笨重,上手体验不算顺畅,始终没能沉下心深度投入。那段时间我四处对比各类轻量级嵌入式操作系统,甚至动过从零自研一套轻量化系统的念头。
时隔许久再回头翻看项目最新版本,发现最近的迭代有了较大的进步。开发团队悄悄将小智(xiaozhi-esp32)作为核心重磅应用内置其中,同时大刀阔斧精简冗余模块、优化整体架构,如今整套框架变得轻巧紧凑,适配门槛大幅降低。
看到了应用商场的雏形,安卓时刻到了么…

第一章:项目全景
1.1 什么是 ESP-Brookesia
ESP-Brookesia 是乐鑫推出、带着温度与产品思考的面向 AIoT 和 HMI 产品全栈开发平台。它不是一段孤立SDK,而是一套层层解耦、自由拼装的 ESP-IDF 组件集合,把硬件、交互、AI、应用完整收拢,让开发者不必反复从零搭建底层基建:
硬件抽象层(HAL) — 屏蔽芯片引脚、外设差异,同一份业务代码,换块开发板无需大改
服务框架 — 统一服务注册、跨模块函数调用、事件收发,模块之间温和解耦,互不牵绊
运行时与 GUI — JS/Lua/WASM/原生多语言运行容器,搭配JSON声明式界面,写界面不用堆砌底层绘图代码
系统框架 — 桌面Shell、应用生命周期托管,像给嵌入式设备搭一套轻量化手机系统
应用生态 — 内置应用商店,支持第三方应用分发,让设备拥有持续拓展的生命力
AI 能力 — 三款主流AI Agent后端(Coze / OpenAI / XiaoZhi)+ MCP工具互通,让AI能操控屏幕、音频、网络等全部硬件能力
名字源自侏儒变色龙Brookesia:没有庞大身躯,却能适应雨林、灌丛等截然不同的环境;正如这套框架,小到迷你圆形屏智能摆件,大到带多麦摄像头的AI音箱,都能从容适配,藏着小而强大的巧思。

1.2 六层架构
┌─────────────────────────────────────────────────────────┐│ App 层(应用生态) ││ Settings / 文件管理器 / 应用商店 + 第三方自定义App │├─────────────────────────────────────────────────────────┤│ System 层(系统框架) ││ App生命周期调度核心 | 桌面Shell(整机交互入口) │├─────────────────────────────────────────────────────────┤│ Runtime 层(运行时) | GUI 层(图形界面) ││ JS / Lua / WASM / ELF | LVGL + JSON声明式UI │├─────────────────────────────────────────────────────────┤│ Service 层(服务框架) ││ 服务管理器 | 设备/音频/显示/视频/WiFi 基础能力 ││ AI Agent (Coze/OpenAI/XiaoZhi) | 表情动画 / NES模拟器 │├─────────────────────────────────────────────────────────┤│ HAL 层(硬件抽象层) ││ 硬件接口标准 | 板卡配置管理器 | YAML配置自动生成驱动 │├─────────────────────────────────────────────────────────┤│ Utils 层(基础工具库) ││ 任务调度 / 性能日志 / 插件注册 / MCP工具通信桥接 │└─────────────────────────────────────────────────────────┘各层职责速览
| Utils | ||
| HAL | ||
| Service | ||
| GUI | ||
| Runtime | ||
| System | ||
| App |
1.3 组件清单
brookesia/ ← 框架根目录,所有能力收纳于此├── utils/ ← 底层工具层,支撑全框架运转│ ├── brookesia_lib_utils/ ← 核心工具(调度器/日志/插件/状态机)│ └── brookesia_mcp_utils/ ← MCP工具桥接,打通AI与硬件服务│├── hal/ ← 硬件抽象层,隔绝繁杂硬件差异│ ├── brookesia_hal_interface/ ← 统一硬件接口标准│ ├── brookesia_hal_board_manager/ ← 板卡管理器(YAML一键生成C驱动)│ ├── brookesia_hal_adaptor/ ← 通用外设适配器(LCD/触摸/音频/SD/摄像头)│ └── brookesia_hal_boards/ ← 各厂商板卡YAML配置仓库│ ├── boards/espressif/ ← 乐鑫官方8块原生开发板│ ├── boards/waveshare/ ← 微雪3块特色屏幕板卡(圆形AMOLED等)│ └── boards/rymcu/ ← 国产厂商1块拓展IO开发板│├── service/ ← 服务中枢,整机所有能力封装于此│ ├── framework/ ← 服务底层框架│ │ ├── brookesia_service_manager/ ← 服务总调度器│ │ ├── brookesia_service_helper/ ← 服务快捷调用工具│ │ └── brookesia_service_custom/ ← 自定义拓展服务入口│ ├── system/ ← 系统基础服务│ │ ├── brookesia_service_device/ ← 整机设备信息管理│ │ └── brookesia_service_storage/ ← 持久化存储(NVS/文件)│ ├── media/ ← 多媒体音视频服务│ │ ├── brookesia_service_audio/ ← 音频录播、编解码│ │ ├── brookesia_service_video/ ← 视频硬编硬解│ │ └── brookesia_service_display/ ← 多画面源仲裁、屏幕控制│ ├── network/ ← 网络通信服务│ │ ├── brookesia_service_wifi/ ← WiFi配网、信号管理│ │ ├── brookesia_service_sntp/ ← 网络时间同步│ │ └── brookesia_service_http/ ← HTTP网络请求客户端│ ├── expression/ ← 拟人表情服务│ │ └── brookesia_expression_emote/ ← AI交互表情动画│ ├── emulation/ ← 复古模拟器服务│ │ └── brookesia_emulation_nes/ ← NES红白机游戏模拟器│ └── agent/ ← AI对话核心服务│ ├── brookesia_agent_manager/ ← AI后端统一管理器│ ├── brookesia_agent_coze/ ← 扣子AI后端│ ├── brookesia_agent_openai/ ← OpenAI实时对话后端│ └── brookesia_agent_xiaozhi/ ← 开源小智多模态AI后端│├── gui/ ← 图形界面层│ ├── brookesia_gui_interface/ ← GUI统一抽象接口│ └── brookesia_gui_lvgl/ ← LVGL渲染引擎、JSON解析映射│├── runtime/ ← 多语言运行时容器│ ├── brookesia_runtime_manager/ ← 多运行时统一调度│ ├── brookesia_runtime_js/ ← JavaScript脚本运行环境│ ├── brookesia_runtime_lua/ ← Lua轻量脚本环境│ ├── brookesia_runtime_wasm/ ← WASM跨平台运行环境│ └── brookesia_runtime_elf/ ← 原生ELF二进制运行环境│├── system/ ← 整机系统框架│ ├── brookesia_system_core/ ← App生命周期核心调度│ └── brookesia_system_super/ ← 桌面Shell人机交互层│├── app/ ← 系统内置原生应用│ ├── brookesia_app_settings/ ← 整机设置面板│ ├── brookesia_app_files/ ← 文件资源管理器│ └── brookesia_app_store/ ← 应用商店(本地/网络安装)│└── examples/ ← 落地示例工程,新手入门最好的老师 └── agent/chatbot/ ← AI语音聊天机器人完整实战案例总计:~40 个组件,其中 14 个 Service、5 个 Runtime、3 个 App、2 个 System、2 个 GUI。每一个组件各司其职,互不纠缠,像精密又温和的齿轮组,协同撑起完整智能设备。
第二章:Git 演替——版本进化史
一套成熟框架从来不是一蹴而就,ESP-Brookesia走过三段截然不同的设计心路,每一次迭代,都是踩过项目落地坑洞后沉淀的思考。
2.1 版本路线总览
| v0.6 | ||||
| v0.7 | ||||
| v0.8 |
2.2 v0.7.x 逐版演进(2025-12 → 2026-05)
v0.7是框架从“玩具demo”走向“工程化工具”的过渡阶段,每一次小更新,都在解决实际开发里暴露的痛点:
v0.7.0 ─ 2025-12-07 Service Manager 初始发布 │ 搭建服务生命周期、跨模块函数调用、事件订阅、TCP跨设备远程调用 │v0.7.1 ─ 2025-12-24 Service Helper 配套工具落地 │ WiFi/NVS快捷封装,统一函数、事件数据规范,减少重复样板代码 │v0.7.2 ─ 2026-01-13 数据流扩容适配 │ EventItem支持原始二进制缓存;后台工作线程栈从10KB扩容至15KB,避免复杂音频任务栈溢出 │v0.7.3 ─ 2026-02-02 底层数据结构重构 │ EventItem/FunctionValue从通用变体改为派生类,类型更安全;新增全局函数/事件注册表,调度逻辑更清晰 │v0.7.4 ─ 2026-02-25 网络、音频、AI能力拓展 │ WiFi热点SoftAP支持;音频新增暂停/恢复编码接口;AI Agent状态机逻辑完善 │v0.7.5 ─ 2026-03-12 拟人表情能力完善 │ Emote全局刷新接口;服务基类开放事件、函数注册表对外访问入口 │v0.7.6 ─ 2026-03-24 音频解耦优化 │ 统一通过AudioPlayerIface控制音量,彻底移除底层esp_codec硬编码调用,硬件适配更灵活 │v0.7.7 ─ 2026-04-10 多媒体与AI工具体系落地 │ 视频编解码服务初次上线;音频删除冗余外设配置接口;引入MCP跨模块工具系统,打通AI与硬件 │v0.7.8 ─ 2026-04-20 屏幕显示服务上线 │ Display屏幕管理服务正式发布;重构Agent管理器大量对外API,统一接口命名规范 │v0.7.9 ─ 2026-04-30 硬件、编译逻辑分离 │ HAL设备工具类支持背光、电池读取;拆分ESP硬件编译与PC仿真两套构建逻辑,本地无需烧录即可调试 │v0.7.10 ─ 2026-05-28 硬件、AI组件解耦收尾 │ WiFi/NVS工具与HAL硬件接口对齐;小智AI拆分为独立组件;增加文件系统容量配置规范 │2.3 v0.8.0 里程碑(2026-06-28)
这是整套框架脱胎换骨的一次重构,彻底告别早期扁平化杂乱的代码结构,把零散能力分层收纳,真正做到“开箱即可做量产HMI智能设备”:
组件层级大重构:┌─────────────────────────────────────────────────────┐│ v0.7.x 时期:所有组件扁平堆砌 ││ service/ 文件夹下平铺十多个功能组件,层级混乱 ││ 无独立GUI、Runtime、System、App分层,界面与业务耦合 │├─────────────────────────────────────────────────────┤│ v0.8.0 重构后:按功能分层收纳,逻辑一目了然 ││ utils/ → 2个底层工具组件,统一提供基础能力 ││ hal/ → 3个核心硬件组件 + 全厂商板卡配置库 ││ service/ → 14个服务按媒体/网络/AI分类整理 ││ gui/ → 全新图形界面分层,JSON UI核心在此 ││ runtime/ → 全新多语言运行时分层,支持四类程序 ││ system/ → 全新整机系统层:App管理 + 桌面Shell ││ app/ → 全新应用分层,系统原生应用统一存放 │└─────────────────────────────────────────────────────┘
2.4 从 v0.6 到 v0.8 的设计哲学演变
每一段版本,对应一套开发思路,也是团队在AIoT产品开发路上的心路转变:
v0.6 —— "能跑就行" 起源单一ESP-VoCat语音宠物对话固件,所有代码堆在同一工程 只验证AI语音对话+屏幕显示基础可行性,没有复用、拓展概念 ↓v0.7 —— "能拆就拆" 拥抱ESP-IDF组件化机制,把硬件、AI、网络逐一拆分成独立模块 Service服务框架成型,HAL硬件层独立拆分,开始思考代码复用 核心设计:插件注册表 + 统一服务基类,为后续分层打下基础 ↓v0.8 —— "能组就组" 完整六层分层架构定型,像搭积木一样自由组合硬件、界面、AI、应用 新增PC离线仿真,不用反复烧录硬件调试界面、业务逻辑 配套产品级桌面、应用商店,一套框架覆盖原型开发到量产全流程 AI MCP工具打通全硬件能力,让智能交互不再局限简单问答第三章:支持的板卡深度分析
从乐鑫官方旗舰音箱,到微雪小巧圆形屏开发板,再到国产厂商拓展硬件,ESP-Brookesia适配12款主流硬件,覆盖从无屏传感器到高清MIPI彩屏全品类,照顾不同产品形态的开发需求。
3.1 12 块板卡全景
Espressif 官方(8 块)
| esp_box_3 | ||||||
| esp32_s3_korbo2_v3 | ||||||
| esp32_s31_korbo1 | ESP32-S31 | |||||
| esp_vocat_board_v1_0 | ||||||
| esp_vocat_board_v1_2 | ||||||
| esp32_p4_function_ev | ESP32-P4 | MIPI-DSI | ||||
| esp32_p4x_function_ev | ESP32-P4 | MIPI-DSI | ||||
| esp_sensair_shuttle | ESP32-C5 |
第三方(4 块)
| Waveshare 1.75c | 圆形 CO5300 QSPI | ||||
| Waveshare 1.8 | |||||
| Waveshare 2.16 | |||||
| RYMCU BigSmart |
3.2 按芯片平台分类
ESP32-S3 ──── 8 块(主力通用平台)── box_3/korbo2/vocat×2/waveshare×3/rymcu │ │ CPU: Xtensa LX7 双核 240MHz │ RAM: 512KB SRAM + 8MB PSRAM(典型配置) │ 外设: SPI/QSPI LCD, I2S 音频, SDMMC, USB OTG │ 特色: 内置AI向量加速指令,语音、轻量视觉推理够用 │ESP32-P4 ──── 2 块(高性能多媒体平台)── p4_function_ev / p4x_function_ev │ │ CPU: 双核 RISC-V 400MHz,算力大幅提升 │ RAM: LP SRAM + HP SRAM + 最高32MB PSRAM │ 外设: MIPI-DSI高清显示、MIPI-CSI摄像头 │ 特色: H264硬件编解码,USB摄像头直连,支持双屏输出,多媒体设备专用 │ESP32-S31 ── 1 块 ── s31_korbo1 │ S3定制变体芯片,AFE声学前端通路重新设计,远场拾音优化 │ESP32-C5 ──── 1 块 ── sensair_shuttle RISC-V低功耗芯片,无屏幕外设,专注传感器数据采集3.3 按显示总线分类
SPI/QSPI LCD ── 10 块 ── 绝大多数S3开发板通用方案 │ 驱动芯片: ILI9341 / ST7789 / GC9A01(圆形屏专用) │ 接口: 4线SPI / QSPI高速总线 │ 时钟速度: 40-80MHz,满足中小尺寸屏幕刷新 │MIPI-DSI ──── 2 块 ── P4高性能平台专属 │ 驱动: ILI9881C / ST7123高清屏驱动 │ 接口: 2通道MIPI DSI高速串行显示 │ 时钟: 80MHz DPI时钟,支持720P级高清屏幕 │ 特点: 时序配置复杂,但画面细腻、刷新率高,多媒体大屏首选 │无屏 ────── 1 块 ── sensair_shuttle,纯数据采集设备3.4 外设功能覆盖矩阵
第四章:集成应用深度解读
整套框架不止底层驱动与服务,更配套一套完整面向终端用户的应用体系,从桌面启动器、系统设置、文件管理到AI聊天、复古游戏,覆盖一台智能设备几乎所有基础交互场景,开箱即可拥有完整人机交互体验。
4.1 系统 Shell(System Super)
System Super是整套框架的门面,一套完整产品级嵌入式桌面系统,所有界面全部依靠JSON文本声明式描述,不用手写大量绘图代码,界面修改直观易懂。
shell pages JSON(界面页面定义):├── app_launcher.json ← 应用图标网格桌面,整机交互首页│ - 展示所有已安装应用图标、名称│ - 点击图标唤起App,长按支持卸载、拖动排序│├── background.json ← 桌面壁纸配置│ - 纯色、渐变、静态图片三类壁纸自由切换│├── keyboard_input.json ← 全局虚拟键盘│ - 字母/数字/符号完整布局│ - 中英文输入法一键切换│├── message_dialog.json ← 全局系统弹窗│ - 单确认、确认取消、是/否多类型弹窗模板│├── overlay.json ← 全局悬浮层(AI表情、弹窗覆盖)│ - 常驻顶层,不遮挡底层应用核心画面│├── app_background.json ← App后台渲染缓存└── keyboard_hidden.json ← 键盘收起隐藏布局shell flow JSON(页面交互流转规则):├── shell_pages.json ← 桌面与各App页面切换逻辑├── keyboard.json ← 键盘弹出、收起交互逻辑├── message_dialog.json ← 弹窗弹出、关闭流转└── background.json ← 后台页面生命周期管理StatusBar 顶部状态栏实现要点
// system/super/src/page/status_bar.cpp// 顶部常驻栏:网络时间、WiFi信号强度、剩余电量三大核心信息void StatusBar::on_create(){// 订阅系统全局事件,数据变更自动刷新UIsubscribe("device/battery", [this](auto data) {update_battery_icon(data["level"]); });subscribe("wifi/signal", [this](auto data) {update_wifi_icon(data["rssi"]); });// 每秒定时刷新系统时间 scheduler.post_periodic([]{update_clock(); }, 1000);}NavigationBar 底部三键导航栏
// system/super/src/page/nav_bar.cpp// 底部常驻导航:返回、主页、最近应用,全App全局生效// JSON定义按键区域坐标,触摸事件统一转发至系统核心调度void NavBar::on_touch(const TouchEvent& e){switch (hit_test(e.x, e.y)) {case BACK: SystemCore::navigate_back(); break;case HOME: SystemCore::launcher_show(); break;case RECENT: SystemCore::show_recent(); break; }}4.2 Settings 设置应用(系统最复杂原生App)
设置面板承载整机全部配置能力,深度对接WiFi、音频、显示、存储、AI Agent各类底层服务,页面层级清晰,是学习App与服务交互的最佳范例。
页面树:settings_home ─┬─ WiFi ── wifi_connect(密码输入配网页) ├─ Sound ── 音量调节、音频输出设备切换 ├─ Display ── 屏幕亮度、深浅色主题切换 ├─ My Device ── 芯片型号、固件版本、存储容量信息 └─ More ── Language ── 多语言界面切换 Time Zone ── 时区自定义选择核心开发模式——JSON页面负责界面展示,C++逻辑调用底层服务,数据双向互通:
// app/settings/src/settings_wifi.cppvoid WifiPage::on_scan_complete(const WiFiScanResult& result){// 1. 清空页面旧WiFi列表 json_page_.clear_list("wifi_list");// 2. 遍历扫描到的无线网络,动态填充页面列表控件for (auto& ap : result) { json_page_.add_list_item("wifi_list", { {"ssid", ap.ssid}, {"signal", ap.rssi}, // -30dBm代表满格信号 {"encryption", ap.auth_mode}, {"selected", ap.ssid == current_ssid_} }); }// 3. 自动刷新LVGL界面,无需手动重绘 json_page_.refresh();}void WifiPage::on_connect(const std::string& ssid){// 调用WiFi服务接口发起配网 service_manager.call("wifi", "Connect", { {"ssid", ssid}, {"password", password_input_} });}深浅色主题切换源码
// 一键切换浅色/深色模式,JSON界面样式实时更新,配置持久存入NVSvoid DisplayPage::on_theme_toggle(){ is_dark_ = !is_dark_;// 调用屏幕服务切换全局UI主题 service_manager.call("display", "SetTheme", { {"theme", is_dark_ ? "dark" : "light"} });// 保存配置,重启设备不丢失 storage.save("display_theme", is_dark_);}4.3 Files 文件管理器
整机统一资源浏览器,支持SPIFFS、LittleFS、SD卡多存储介质互通,兼顾流畅度与大文件浏览性能:
Browser 页面:目录树导航 + 文件列表视图,图标/列表双模式切换功能:复制、移动、删除、重命名、新建文件夹后端:封装通用文件系统接口,兼容板载Flash与外置SD卡性能设计:大目录仅渲染屏幕可视区域文件条目,单条目仅25B内存占用,千份文件仅消耗25KB内存,低内存设备也能流畅使用4.4 App Store 应用商店
这里要区分:它并非云端在线商店,而是一套本地应用包管理框架,开发者可自行拓展网络下载渠道,灵活适配私有化设备场景。
Catalog 页面:区分已安装/可安装应用包列表Install 页面:读取本地.brookesia安装包完成部署Network 页面:通过HTTP链接远程下载并安装应用核心操作:├─ list_local_packages() ← 扫描Flash内所有应用安装包├─ install_package(path) ← 解压包体,写入对应运行时目录├─ uninstall_package(name) ← 彻底删除应用全部资源文件└─ launch_package(name) ← 交由SystemCore启动应用包格式 (.brookesia): manifest.json ── 应用名称、版本、运行时类型、入口配置 icon.png ── 桌面显示应用图标 bundle.* ── JS/Lua/WASM/原生ELF程序包体4.5 NES 红白机模拟器
它并非独立App,而是封装成标准Service服务,由桌面应用统一唤起,复古游戏能力成为整机多媒体拓展能力之一:
模拟内核:nofrendo轻量NES模拟器,资源占用极低组件拆分:├─ mappers/ ← 兼容市面绝大多数NES游戏卡带映射器├─ 音频输出通道 → 复用整机Audio Service,统一音量控制├─ 画面渲染通道 → 对接Display显示抽象接口├─ 输入操控 → 屏幕虚拟触摸按键 + 外接GPIO物理手柄双支持└─ 存档读档 → 数据持久存入Flash分区启动流程:桌面点击游戏图标 → SystemCore唤起nes服务 → 接管屏幕渲染 → 加载nes游戏镜像运行4.6 Emote 拟人表情服务
专为AI语音交互设计的可视化能力,让语音对话不再只有冰冷文字,屏幕动画赋予设备温度:
功能:在悬浮顶层展示角色动态表情,贴合对话情绪内置表情集:开心/思考/等待/失落/说话/聆听六种基础动画两种触发方式: 1. AI Agent对话返回emoji字符,自动匹配对应动画 2. 任意服务发布全局事件,驱动表情切换核心逻辑:void EmoteService::on_emoji_received(const std::string& emoji) { // 例如接收"😊",映射对应动画资源文件happy_anim.json auto anim = emoji_map_[emoji]; // 在全局悬浮层播放动画,不遮挡底层对话界面 display_service_->show_overlay(anim);}第五章:AI 语音聊天机器人集成(框架核心亮点)
AI对话是ESP-Brookesia的核心能力,三套主流AI后端标准化接入,依托MCP工具链打通整机所有硬件,AI不止能问答,还能操控屏幕、WiFi、音频、文件,真正实现智能设备全自然语音控制。
5.1 三个 Agent 后端对比
| Coze | |||
| OpenAI | |||
| XiaoZhi |
5.2 编译时三阶段选择机制
开发者可在编译阶段自由开启/关闭任意AI后端,无需删除代码,配置化开关,灵活控制固件体积:
第一阶段:Kconfig 图形化条件编译
每个Agent组件自带独立Kconfig配置项:# agent_coze/Kconfigconfig BROOKESIA_AGENT_COZE_ENABLE_AUTO_REGISTER bool "Enable automatic plugin registration" default n ← 默认关闭,按需开启# agent_openai/Kconfigconfig BROOKESIA_AGENT_OPENAI_ENABLE_AUTO_REGISTER bool "Enable automatic plugin registration" default n# agent_xiaozhi/Kconfigconfig BROOKESIA_AGENT_XIAOZHI_ENABLE_AUTO_REGISTER bool "Enable automatic plugin registration" default y ← 默认启用,开箱即用小智AI示例工程统一封装可视化菜单,执行idf.py menuconfig即可勾选:
menu "Example Configuration"config EXAMPLE_AGENTS_ENABLE_COZE bool "Enable Coze agent" select BROOKESIA_AGENT_COZE_ENABLE_AUTO_REGISTERconfig EXAMPLE_AGENTS_ENABLE_OPENAI bool "Enable OpenAI agent" select BROOKESIA_AGENT_OPENAI_ENABLE_AUTO_REGISTERconfig EXAMPLE_AGENTS_ENABLE_XIAOZHI bool "Enable XiaoZhi agent" default yendmenu第二阶段:PluginRegistry 插件自动注册
// agent_xiaozhi/src/agent_xiaozhi.cpp 文件末尾// Kconfig关闭时,这段注册代码不会编译执行,运行时无法找到该AI后端#if BROOKESIA_AGENT_XIAOZHI_ENABLE_AUTO_REGISTER// 同时注册为通用AI基类、标准服务基类,全局调度器可统一调用BROOKESIA_PLUGIN_REGISTER_SINGLETON( Base, XiaoZhi, XiaoZhi::get_instance().get_attributes().get_name(), XiaoZhi::get_instance());BROOKESIA_PLUGIN_REGISTER_SINGLETON_WITH_SYMBOL( service::ServiceBase, XiaoZhi, XiaoZhi::get_instance().get_attributes().get_name(), XiaoZhi::get_instance(), BROOKESIA_AGENT_XIAOZHI_PLUGIN_SYMBOL);#endif注册宏本质依靠__attribute__((constructor)),固件启动main函数前自动把AI后端存入全局插件注册表,框架无需硬编码所有Agent,拓展新AI后端零侵入。
第三阶段:运行时动态切换
// agent_manager/src/manager.cppstd::expected<void, std::string>Manager::function_set_target_agent(const std::string &name){// 从注册表查找已启用的AI后端auto agent = Registry::get_instance(name);if (agent == nullptr) {return error("No agent found with name '%1%'", name); }// 写入NVS持久保存,重启设备自动沿用上次选择set_data<DataType::TargetAgent>(name);try_save_data(DataType::TargetAgent);return {};}用户可在系统设置界面一键切换AI服务商,无需重新编译固件,运行时即时生效。
5.3 Agent 统一生命周期状态机
三套AI后端全部继承同一套基类,共享标准化状态流转,开发者对接任意AI后端逻辑完全一致,降低多方案维护成本:
┌──────────┐ │ Created │ 组件创建完成 └────┬─────┘ │ init() 初始化资源 ┌────▼─────┐ │Initing │ └────┬─────┘ │ 初始化校验通过 ┌────▼─────┐ │ Inited │ 资源就绪 └────┬─────┘ │ activate() 激活鉴权 ┌────▼──────┐ │ Activating│ └────┬──────┘ │ 鉴权成功 ┌────▼──────┐ │ Activated │ 后端认证完成 └────┬──────┘ │ startup() 建立对话连接 ┌────▼─────┐ │ Starting │ └────┬─────┘ │ 网络连接成功 ┌────▼─────┐ ┌───►│ Started │◄───┐ 正常对话中 │ └────┬─────┘ │ │ │ │ sleep()│ wakeup() shutdown() │ │ │ │ ┌────▼─────┐ │ └────┤ Slept ├────┘ 休眠关闭音频通道 └──────────┘基类强制实现五类核心生命周期接口,统一管控音频、网络资源启停:
// agent_manager/include/base.hppclass Base : public service::ServiceBase {// 必须子类实现的核心生命周期virtual bool on_activate()= 0; // 激活鉴权(小智激活码/OpenAI密钥校验)virtual bool on_startup()= 0; // 启动对话,建立网络连接、初始化音频通道virtual void on_shutdown()= 0; // 终止对话,断开网络、释放音频资源virtual bool on_sleep()= 0; // 休眠,关闭麦克风、扬声器节省功耗virtual bool on_wakeup()= 0; // 唤醒,重新打开音频通路等待语音输入// 可选拓展接口virtual bool on_interrupt_speaking(); // 打断AI播报语音virtual bool on_manual_start_listening(); // 手动开启拾音virtual bool on_manual_stop_listening(); // 手动关闭拾音virtual bool on_encoder_data_ready(); // 音频编码数据就绪回调};5.4 XiaoZhi Agent 全功能分析
小智是框架默认主推AI方案,开源免费、支持视觉图像理解,完整集成MCP工具链,最适合量产低成本AI交互设备。
依赖链路分层清晰
brookesia_agent_xiaozhi (v0.8) ├── brookesia_agent_manager ← 统一AI状态机调度 ├── brookesia_mcp_utils ← MCP硬件工具互通桥梁 ├── brookesia_service_helper ← 服务快捷调用工具 └── esp_xiaozhi (v0.1, private) ← 小智底层通信内核 ├── esp_xiaozhi_chat ← 语音对话引擎 ├── esp_xiaozhi_camera ← 摄像头图像理解模块 ├── esp_xiaozhi_video ← 视频编解码辅助 ├── esp_xiaozhi_mqtt ← MQTT稳定长连接传输 ├── esp_xiaozhi_keystore ← 密钥、激活码安全存储 └── esp_xiaozhi_payload ← 前后端数据序列化启动对话完整流程
// agent_xiaozhi.cpp on_startup()bool XiaoZhi::on_startup(){// 1. 创建MCP工具引擎,AI调用硬件能力的核心载体esp_mcp_t *mcp_engine = nullptr;esp_mcp_create(&mcp_engine);// 2. 批量注册整机所有服务为AI可用工具auto mcp_handles = mcp_tool_registry_.generate_tools();for (auto handle : mcp_handles) {esp_mcp_add_tool(mcp_engine, handle); }// 3. 绑定AI对话事件回调,接收对话、表情、打断指令esp_event_handler_instance_register( ESP_XIAOZHI_CHAT_EVENTS, ESP_EVENT_ANY_ID, agent_event_handler, this, &agent_event_instance_ );// 4. 初始化对话引擎,绑定OPUS音频编码与MCP工具esp_xiaozhi_chat_config_t chat_config = ESP_XIAOZHI_CHAT_DEFAULT_CONFIG(); chat_config.audio_type = ESP_XIAOZHI_CHAT_AUDIO_TYPE_OPUS; chat_config.mcp_engine = mcp_engine;esp_xiaozhi_chat_init(&chat_config, &chat_handle_);// 5. 正式开启语音对话通道esp_xiaozhi_chat_start(chat_handle_);}完整音频数据流通路
麦克风拾音 → AFE声学降噪前端 → OPUS音频编码 → WebSocket/MQTT上传云端 云端AI回复语音 → 网络下行OPUS码流 → 音频解码 → 扬声器播放 整套音频通路复用整机Audio Service,无需单独管理I2S外设,多应用共享音频资源不冲突。
MCP工具系统(Brookesia独有核心优势)
MCP是连接AI与硬件服务的桥梁,让自然语言指令直接操控设备:
// 将任意服务函数注册为AI可调用工具auto XiaoZhi::function_add_mcp_tools_with_service_function(const std::string &service_name,const boost::json::array &function_names) -> std::expected<boost::json::array, std::string>{ std::vector<std::string> func_names;BROOKESIA_DESCRIBE_FROM_JSON(function_names, func_names);auto names = mcp_tool_registry_.add_service_tools( service_name, std::move(func_names) );return BROOKESIA_DESCRIBE_TO_JSON(names).as_array();}注册完成后,AI可直接响应语音指令:
“打开WiFi并连接XX网络” → 调用WiFi服务扫描、配网函数
“把屏幕亮度调到50%” → 调用Display屏幕调节接口
“播放本地音乐文件” → 调用Audio音频播放服务 同时支持自定义工具拓展,对接第三方外设驱动。
图像视觉理解能力
依托摄像头硬件,小智支持拍照识图问答,也可读取本地图片文件解析内容:
// 传入摄像头图像二进制数据,向AI发起图像提问auto XiaoZhi::function_explain_image(const service::RawBuffer &image,const std::string &question) -> std::expected<std::string, std::string>{if (!image_explain_handle_) {esp_xiaozhi_camera_config_t config = { .explain_url = "http://api.xiaozhi.me/vision/explain", .explain_token = "test-token", };esp_xiaozhi_camera_create(&config, &image_explain_handle_); }esp_xiaozhi_camera_frame_t frame = { .data = image.data_ptr, .len = image.data_size };esp_xiaozhi_camera_explain(handle, &frame, question.c_str(), buffer, buffer_size, &response_len);return std::string(buffer, response_len);}唤醒词打断播报逻辑
设备唤醒词触发时,立刻中断当前AI语音播放,快速响应新指令,交互更自然流畅:
bool XiaoZhi::on_interrupt_speaking(){esp_xiaozhi_chat_send_abort_speaking( chat_handle_, ESP_XIAOZHI_CHAT_ABORT_SPEAKING_REASON_WAKE_WORD_DETECTED );reset_interrupted_speaking();return true;}唤醒词支持两处自定义配置:Kconfig全局编译配置、Audio声学前端多组唤醒词列表。
5.5 与原生 xiaozhi-esp32 的架构对比
原生小智单固件项目适合极简语音音箱,而Brookesia的小智Agent适配多应用、多屏幕复杂HMI设备,二者定位完全区分:
| 代码组织 | ||
| 硬件控制 | ||
| 引脚配置 | ||
| 音频管道 | ||
| MCP工具 | ||
| 跨App交互 | ||
| OTA升级 | ||
| UI界面 | ||
| 适用场景 |
第六章:适配新板卡——从 YAML 到固件
拿到一块全新自研硬件,不用从零编写底层驱动,一套YAML配置+自动代码生成工具,半小时完成硬件适配,大幅降低硬件迭代开发成本,这也是HAL层最温柔的设计。
6.1 板卡适配完整流程
编写三份硬件YAML配置文件 ↓bmgr工具自动生成全套C硬件初始化代码 ↓特殊硬件时序/拓展芯片 → 可选编写Custom Device自定义驱动 ↓编译指定目标板卡,烧录验证硬件外设全部正常工作6.2 第一步:编写三份YAML配置文件
文件存放路径固定:hal/brookesia_hal_boards/boards/<厂商名>/<板卡名称>/
board_info.yaml 板卡基础信息
记录芯片、存储、内存核心参数,生成全局硬件宏定义:
# board_info.yamlboard_name: "my_custom_board"# 板卡唯一标识,编译指定使用chip_name: "esp32s3"# 芯片型号vendor_name: "my_company"# 硬件厂商psram_size: 8# PSRAM容量(MB)flash_size: 16# Flash容量(MB)psram_mode: "opi"# OPI/QPI/SPI内存模式psram_clk: 80# PSRAM时钟频率(MHz)board_peripherals.yaml 外设引脚总线定义
屏幕、触摸、音频、SD卡全部总线引脚统一在此描述,无需手写GPIO初始化代码:
# board_peripherals.yamlperipherals:# LCD显示屏配置lcd:host_device: "SPI2"interface: "spi"pin_num_miso: -1pin_num_mosi: 11pin_num_clk: 12pin_num_cs: 10pin_num_dc: 14pin_num_rst: 21pin_num_bcklig: 47pclk_hz: 80000000lcd_width: 320lcd_height: 480cmd_bits: 8param_bits: 8swap_color: true# 电容触摸touch:host_device: "I2C0"interface: "i2c"pin_num_sda: 10pin_num_scl: 11rst_pin: 21int_pin: 4# 音频播放输出audio_player:host_device: "I2S0"interface: "i2s"pin_num_mclk: 2pin_num_bclk: 3pin_num_lrclk: 4pin_num_dout: 5pa_pin: 15# 麦克风录音输入audio_recorder:host_device: "I2S0"interface: "i2s"pin_num_mclk: 2pin_num_bclk: 3pin_num_lrclk: 4pin_num_din: 6# SD存储卡sd:host_device: "SDMMC"interface: "sdmmc"pin_num_clk: 39pin_num_cmd: 38pin_num_d0: 40pin_num_d1: 41pin_num_d2: 42pin_num_d3: 43board_devices.yaml 外设芯片型号绑定
关联总线配置与具体驱动芯片,更换屏幕仅修改此处名称,上层业务代码完全不用改动:
# board_devices.yamldevices:- name: "ST7789"# LCD驱动IC型号type: "lcd"periph: "lcd"# 引用上方lcd总线配置cmd_bits: 8param_bits: 8- name: "CST816T"# 触摸ICtype: "touch"periph: "touch"- name: "ES8311"# 音频DAC功放type: "audio_player"periph: "audio_player"- name: "ES7210"# 多麦采集ADCtype: "audio_recorder"periph: "audio_recorder"- name: "SDCard"# SD卡外设type: "sd"periph: "sd"6.3 第二步:bmgr工具自动生成C硬件代码
bmgr即Board Manager板卡管理器,封装为idf.py bmgr命令,底层Python脚本完成YAML解析、C代码生成,免去重复、易错的硬件初始化样板代码。
bmgr/ 脚本目录结构├── __init__.py├── cmd_parse.py ← 命令行参数解析├── board_util.py ← 全局扫描所有板卡配置├── periph_parser.py ← 外设YAML转C结构体├── device_parser.py ← 器件芯片配置解析├── codegen_c.py ← C源码文件生成核心└── kconfiggen.py ← 自动生成板卡Kconfig配置执行命令后自动生成全套硬件代码,存放于components/gen_bmgr_codes/,包含外设、器件、整机初始化入口、引脚宏文件,全部禁止手动修改,硬件变更仅更新YAML重新生成即可。
6.4 第三步:编写Custom Device(可选拓展)
标准屏幕、音频芯片无需自定义驱动,仅当硬件存在特殊上电时序、IO扩展芯片、多路复用引脚时,才需要自定义设备驱动: 触发场景:
使用PCA9557/PI4IOE5V6408等IO扩展芯片控制屏幕、电源引脚
上电有严格时序:LDO电源 → IO拓展器 → LCD复位 → 触摸复位
多路引脚复用、特殊硬件初始化指令序列
自定义驱动存放于hal/brookesia_hal_custom/,继承标准设备基类重写初始化逻辑,不改动框架底层通用代码。
6.5 第四步:编译验证
# 进入示例工程目录cd examples/agent/chatbot# 指定目标芯片idf.py set-target esp32s3# 执行板卡代码生成,填入自定义板卡名称idf.py bmgr --board my_custom_board# 编译固件idf.py build# 烧录并打开串口监视器调试idf.py -p /dev/ttyUSB0 flash monitor第七章:为项目增加一个完整应用
框架原生自带设置、文件管理器、应用商店,同时开放完整App开发规范,开发者可按需新增天气、时钟、智能家居控制等自定义应用,一套标准模板快速落地。
7.1 应用架构全景
每一个App三层分离,界面、业务、系统调度完全解耦,专注单一功能开发:
App安装包整体结构┌─────────────────────────────────────────┐│ SystemCore 系统调度层(统一管理所有App)│ - 安装、卸载存储管理│ - 前后台启动、生命周期事件分发├─────────────────────────────────────────┤│ JSON声明式UI界面层(纯描述文本,无绘图代码)│ - 页面布局、按钮、文字、图片资源定义│ - 页面跳转交互流转规则│ - LVGL自动渲染,修改界面无需改动业务逻辑├─────────────────────────────────────────┤│ 业务逻辑层(C++/JS/Lua/WASM任选)│ - 通过ServiceHelper便捷调用WiFi、音频、网络等底层服务│ - 订阅全局事件响应硬件/AI状态变化│ - 调用Shell接口动态刷新UI文字、图标└─────────────────────────────────────────┘7.2 完整实战示例:天气App
目录结构
app/brookesia_app_weather/├── CMakeLists.txt # 组件编译配置├── idf_component.yml # 组件依赖声明├── Kconfig # 图形化编译开关、API密钥配置├── include/│ └── brookesia/│ └── app_weather.hpp # App头文件├── src/│ └── app_weather.cpp # 业务逻辑实现└── ui/ ├── weather_home.json # 首页界面布局 ├── weather_detail.json # 天气详情页 └── weather_flow.json # 页面跳转规则剩余完整代码示例原文已附,此处不再重复,整套模板可直接复制修改开发任意自定义应用。
7.3 App与Service分工边界
App是面向用户交互的上层载体,Service是整机底层能力中枢,二者职责清晰分离:
App:页面展示、用户点击交互、数据整理、UI刷新
Service:网络请求、硬件操控、音频播放、AI对话、数据存储 通信链路:App → SystemCore系统调度器 → ServiceManager服务总控 → 对应底层服务
7.4 三类应用开发选型对比
适配不同开发效率、性能需求,三种运行时App全部由SystemCore统一管理生命周期:
| Native App | NativeApp基类 | |||
| Script App | ||||
| ELF App |
第八章:关键设计模式解析
整套框架稳定、易拓展的核心,来源于三套贯穿全代码的底层设计思想,读懂设计模式,就能快速吃透框架拓展逻辑。
8.1 PluginRegistry 全局插件注册表(框架根基)
核心思路:固件启动前自动注册所有组件,无硬编码、可插拔开关 依靠GCC __attribute__((constructor))特性,所有Service/App/AI Agent在程序进入main函数前,自动存入全局静态注册表,框架调度器无需提前枚举所有模块,新增组件仅增加注册宏即可兼容,拓展零侵入。 好处:新增自定义硬件服务、第三方AI后端、自研App,不用修改框架核心调度代码,插拔式拓展。
8.2 ServiceBase 标准化服务生命周期
所有底层服务统一继承ServiceBase,固定init/start/stop/deinit四阶段生命周期,搭配全局事件发布订阅、跨服务函数调用机制:
线程安全:所有函数、事件统一由系统任务调度器分发,避免多线程资源冲突
异步解耦:服务之间不靠直接头文件依赖,通过事件、函数调用互通,任意服务可单独关闭、启用
8.3 HAL三层硬件隔离模型
Interface 抽象接口层(统一调用标准) ↑ 继承Device 器件驱动层(ST7789/ES8311等芯片驱动) ↑ 初始化Periph 总线配置层(YAML生成的SPI/I2C/I2S引脚)上层服务、App只依赖统一Interface接口,更换屏幕、音频芯片仅修改板卡YAML,上层业务代码一行不用改动,硬件适配成本大幅降低。
8.4 JSON UI渲染流水线
用JSON文本替代大量LVGL绘图代码,界面与逻辑彻底分离: JSON页面描述 → 解析生成页面对象树 → LVGL映射器自动创建对应控件 → 系统任务定时刷新屏幕 修改界面布局、文字、配色仅编辑JSON文件,无需重新编译业务逻辑,PC仿真可快速预览界面效果。
第九章:总结——从YAML硬件到完整AI应用全链路
完整开发链路梳理
一、硬件适配链路
编写三份板卡YAML(硬件信息/引脚/芯片型号)→ bmgr工具自动生成硬件驱动代码 → 特殊硬件时序编写自定义驱动 → 整机HAL接口注册完成 → 音频/屏幕/WiFi服务可正常调用硬件
二、自定义应用开发链路
创建App组件目录 → JSON编写界面布局与跳转规则 → C++/脚本编写业务逻辑,调用底层服务 → 插件注册接入系统 → 桌面启动器显示图标,一键打开运行
三、AI多模态交互链路
menuconfig勾选启用对应AI后端 → 固件启动自动注册Agent插件 → SystemCore加载AI服务初始化音频通路 → MCP工具绑定整机所有硬件服务 → 语音指令可操控屏幕、网络、外设,支持图像识图对话
五大核心设计哲学,藏着框架开发的温度与巧思
数据驱动硬件:引脚、外设配置全部写入YAML,拒绝代码写死硬件参数,硬件迭代无需修改业务代码
插件化解耦:PluginRegistry实现组件自由插拔,新增硬件、AI、应用不侵入框架核心
声明式界面:JSON描述UI,分离界面与业务逻辑,界面调试、修改效率翻倍
分层隔离架构:HAL→Service→System→App四层自上而下依赖,上层完全不感知底层硬件细节
多运行时兼容:原生C++、JS、Lua、WASM多类应用统一调度,兼顾高性能与快速开发。

夜雨聆风