小智AI xiaozhi-esp32 自定义开发板移植指南:从管脚映射到固件编译的完整实战
【免费下载链接】xiaozhi-esp32An MCP-based chatbot | 一个基于MCP的聊天机器人项目地址: https://gitcode.com/GitHub_Trending/xia/xiaozhi-esp32
小智AI(xiaozhi-esp32)是一个基于 MCP 的 ESP32 系列 AI 语音聊天机器人项目,内置对 70 多种 ESP32 开发板的支持。本指南以仓库 docs/custom-board_zh.md 为核心,完整讲解如何为项目新增一块自定义开发板:从创建板级目录、编写config.h管脚映射与config.json构建配置,到实现板级初始化 C++ 类、接入 Kconfig 与 CMake,最后用scripts/build.py一键编译出可烧录固件。读完本文,你将掌握一套可直接复制执行的开发板移植方法论,并理解固件上报标识与 OTA 升级通道的耦合关系。
一、重要提示:为什么不能直接覆盖现有开发板配置
在开始动手前,必须理解一个关键约束。当自定义开发板的 IO 配置与某个已有开发板不同时,切勿直接覆盖原有开发板的配置去编译固件。正确做法是创建全新的开发板类型,或者通过config.json中builds数组配置不同的name与 sdkconfig 宏定义来区分。
原因在于 OTA 升级机制:每个开发板有唯一的标识和对应的固件升级通道,固件上报的type/name直接决定了设备未来从哪个通道拉取升级包。如果直接覆盖原有配置,OTA 升级时自定义固件可能被原有开发板的标准固件覆盖,导致设备无法正常工作。保持开发板标识的唯一性至关重要。
二、开发板目录结构与文件职责
每个开发板在main/boards/下拥有独立目录,通常包含四类文件:
| 文件 | 职责 |
|---|---|
xxx_board.cc | 主要的板级初始化代码,实现板子相关的初始化和功能 |
config.h | 板级配置文件,定义硬件管脚映射和其他配置项 |
config.json | 上报开发板类型及发布配置,供 CMake 和scripts/build.py使用 |
README.md | 开发板相关的说明文档 |
仓库中大量真实示例遵循这一约定,例如 bread-compact-wifi 目录 下同时存在config.h、config.json、compact_wifi_board.cc;带厂商子目录的板卡则按厂商/板型两级组织,如 waveshare/esp32-s3-touch-amoled-1.8 目录。
三、定制开发板完整六步流程
第 1 步:创建新的开发板目录
在main/boards/下创建新目录,命名采用[品牌名]-[开发板类型]形式:
mkdir main/boards/my-custom-board若你的板卡归属于某个厂商,应放入main/boards/<厂商>/<板型>/两级目录。从 scripts/build.py 的校验逻辑(_collect_variants)可以看出:板卡位于厂商子目录时,config.json中的manufacturer必须与目录名一致,否则构建脚本会直接报错拒绝。
第 2 步:编写 config.h(硬件管脚映射)
config.h定义全部硬件配置,包括音频采样率与 I2S 管脚、编解码芯片 I2C 地址与管脚、按钮与 LED 管脚、显示屏参数与管脚等。以下示例来自 lichuang-c3-dev(与文档一致):
#ifndef _BOARD_CONFIG_H_ #define _BOARD_CONFIG_H_ #include <driver/gpio.h> // 音频配置 #define AUDIO_INPUT_SAMPLE_RATE 24000 #define AUDIO_OUTPUT_SAMPLE_RATE 24000 #define AUDIO_I2S_GPIO_MCLK GPIO_NUM_10 #define AUDIO_I2S_GPIO_WS GPIO_NUM_12 #define AUDIO_I2S_GPIO_BCLK GPIO_NUM_8 #define AUDIO_I2S_GPIO_DIN GPIO_NUM_7 #define AUDIO_I2S_GPIO_DOUT GPIO_NUM_11 #define AUDIO_CODEC_PA_PIN GPIO_NUM_13 #define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_0 #define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_1 #define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR // 按钮配置 #define BOOT_BUTTON_GPIO GPIO_NUM_9 // 显示屏配置 #define DISPLAY_SPI_SCK_PIN GPIO_NUM_3 #define DISPLAY_SPI_MOSI_PIN GPIO_NUM_5 #define DISPLAY_DC_PIN GPIO_NUM_6 #define DISPLAY_SPI_CS_PIN GPIO_NUM_4 #define DISPLAY_WIDTH 320 #define DISPLAY_HEIGHT 240 #define DISPLAY_MIRROR_X true #define DISPLAY_MIRROR_Y false #define DISPLAY_SWAP_XY true #define DISPLAY_OFFSET_X 0 #define DISPLAY_OFFSET_Y 0 #define DISPLAY_BACKLIGHT_PIN GPIO_NUM_2 #define DISPLAY_BACKLIGHT_OUTPUT_INVERT true #endif // _BOARD_CONFIG_H_要点说明:
AUDIO_INPUT/OUTPUT_SAMPLE_RATE通常为 24000(项目音频管线的默认采样率)。- 若板卡使用无编解码芯片的直连方案,可在板级
.cc中改用NoAudioCodec(参考 compact_wifi_board.cc 中的NoAudioCodecDuplex/NoAudioCodecSimplex用法)。 - 显示屏相关宏会直接影响
esp_lcd_panel_swap_xy、esp_lcd_panel_mirror与背光输出极性,DISPLAY_BACKLIGHT_OUTPUT_INVERT控制背光电平是否反相。
第 3 步:编写 config.json(上报标识与构建配置)
config.json定义兼容性上报类型与自动化编译配置:
{ "type": "my-custom-board", // 固件上报的开发板类型,发布后应保持稳定 "target": "esp32s3", // 目标芯片型号: esp32, esp32s3, esp32c3, esp32c6, esp32p4等 "builds": [ { "name": "my-custom-board", // 开发板名称,用于生成固件包 "sdkconfig_append": [ // 特别 Flash 大小配置 "CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y", // 特别分区表配置 "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\"" ] } ] }配置项说明:
manufacturer: 厂商子目录名称;使用厂商目录时必须填写,并作为board.manufacturer上报。平铺社区板可以省略,上报为空字符串。真实示例见 waveshare/esp32-s3-touch-amoled-1.8/config.json。type: 固件上报的开发板系列类型,发布后应保持稳定。target: 目标芯片型号,必须与硬件匹配。name: release 构建上报的固件变体名称,通常与type一致。sdkconfig_append: 额外的 sdkconfig 配置项数组,会追加到默认配置中。
命名约束(与源码校验对应):type和name只能包含小写字母、数字、点(.)和连字符(-),不允许使用下划线、空格或大写字母。这条规则在 scripts/build.py 的_validate_reported_identifier中有硬性校验(正则^[a-z0-9.-]+$),build.py在列出板卡或编译前会检查所有板卡的type/name合法性,违规板卡会被整体拒绝。
常用的 sdkconfig_append 配置:
// Flash 大小 "CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y" // 4MB Flash "CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y" // 8MB Flash // 分区表 "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/4m.csv\"" // 4MB 分区表 "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\"" // 8MB 分区表 // 音频处理 "CONFIG_USE_DEVICE_AEC=y" // 启用设备端 AEC分区表 CSV 文件均位于仓库 partitions/v2/(含 4m、8m、16m、32m 及 esp32c3 专用表)。
两条重要约定:
- 不要重复默认值:对于适用的目标芯片,项目默认使用 16MB Flash 和
partitions/v2/16m.csv。若板卡配置与项目及目标芯片的有效默认值相同,不要在sdkconfig_append中重复填写,只保留板卡确实需要的覆盖项。各芯片的默认配置见仓库根目录的 sdkconfig.defaults 及sdkconfig.defaults.esp32s3等系列文件。 - 不要选语言和唤醒词:这些属于用户构建选项,应统一通过
menuconfig或构建脚本参数配置,方便 CLI、Agent 和在线编译接口共用同一套参数。
多变体(Multi-build)机制:一个目录可以在builds数组下声明多个变体,每个变体拥有独立的name与sdkconfig_append。典型示例见 bread-compact-wifi/config.json:它同时声明了bread-compact-wifi(SSD1306 128x32)与bread-compact-wifi-128x64(SSD1306 128x64)两个固件变体,编译时通过--name选择。这正是文档强调的"通过 config.json 中的 builds 配置不同 name 来区分"的落地方式。
第 4 步:编写板级初始化代码
创建my_custom_board.cc,实现开发板的所有初始化逻辑。一个基本的开发板类包含四部分:
- 类定义:继承自
WifiBoard或Ml307Board - 初始化函数:包括 I2C、显示屏、按钮、IoT 等组件的初始化
- 虚函数重写:如
GetAudioCodec()、GetDisplay()、GetBacklight()等 - 注册开发板:使用
DECLARE_BOARD宏注册开发板
完整示例(与文档一致):
#include "wifi_board.h" #include "codecs/es8311_audio_codec.h" #include "display/lcd_display.h" #include "application.h" #include "button.h" #include "config.h" #include "mcp_server.h" #include <esp_log.h> #include <driver/i2c_master.h> #include <driver/spi_common.h> #define TAG "MyCustomBoard" class MyCustomBoard : public WifiBoard { private: i2c_master_bus_handle_t codec_i2c_bus_; Button boot_button_; LcdDisplay* display_; // I2C初始化 void InitializeI2c() { i2c_master_bus_config_t i2c_bus_cfg = { .i2c_port = I2C_NUM_0, .sda_io_num = AUDIO_CODEC_I2C_SDA_PIN, .scl_io_num = AUDIO_CODEC_I2C_SCL_PIN, .clk_source = I2C_CLK_SRC_DEFAULT, .glitch_ignore_cnt = 7, .intr_priority = 0, .trans_queue_depth = 0, .flags = { .enable_internal_pullup = 1, }, }; ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &codec_i2c_bus_)); } // SPI初始化(用于显示屏) void InitializeSpi() { spi_bus_config_t buscfg = {}; buscfg.mosi_io_num = DISPLAY_SPI_MOSI_PIN; buscfg.miso_io_num = GPIO_NUM_NC; buscfg.sclk_io_num = DISPLAY_SPI_SCK_PIN; buscfg.quadwp_io_num = GPIO_NUM_NC; buscfg.quadhd_io_num = GPIO_NUM_NC; buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t); ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO)); } // 按钮初始化 void InitializeButtons() { boot_button_.OnClick([this]() { auto& app = Application::GetInstance(); if (app.GetDeviceState() == kDeviceStateStarting) { EnterWifiConfigMode(); return; } app.ToggleChatState(); }); } // 显示屏初始化(以ST7789为例) void InitializeDisplay() { esp_lcd_panel_io_handle_t panel_io = nullptr; esp_lcd_panel_handle_t panel = nullptr; esp_lcd_panel_io_spi_config_t io_config = {}; io_config.cs_gpio_num = DISPLAY_SPI_CS_PIN; io_config.dc_gpio_num = DISPLAY_DC_PIN; io_config.spi_mode = 2; io_config.pclk_hz = 80 * 1000 * 1000; io_config.trans_queue_depth = 10; io_config.lcd_cmd_bits = 8; io_config.lcd_param_bits = 8; ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI2_HOST, &io_config, &panel_io)); esp_lcd_panel_dev_config_t panel_config = {}; panel_config.reset_gpio_num = GPIO_NUM_NC; panel_config.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB; panel_config.bits_per_pixel = 16; ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel)); esp_lcd_panel_reset(panel); esp_lcd_panel_init(panel); esp_lcd_panel_invert_color(panel, true); esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY); esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); // 创建显示屏对象 display_ = new SpiLcdDisplay(panel_io, panel, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY); } // MCP Tools 初始化 void InitializeTools() { // 参考 MCP 文档 } public: // 构造函数 MyCustomBoard() : boot_button_(BOOT_BUTTON_GPIO) { InitializeI2c(); InitializeSpi(); InitializeDisplay(); InitializeButtons(); InitializeTools(); GetBacklight()->SetBrightness(100); } // 获取音频编解码器 virtual AudioCodec* GetAudioCodec() override { static Es8311AudioCodec audio_codec( codec_i2c_bus_, I2C_NUM_0, AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE, AUDIO_I2S_GPIO_MCLK, AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN, AUDIO_CODEC_PA_PIN, AUDIO_CODEC_ES8311_ADDR); return &audio_codec; } // 获取显示屏 virtual Display* GetDisplay() override { return display_; } // 获取背光控制 virtual Backlight* GetBacklight() override { static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT); return &backlight; } }; // 注册开发板 DECLARE_BOARD(MyCustomBoard);源码级补充解读:
DECLARE_BOARD宏定义在 main/boards/common/board.h 中,展开后生成全局工厂函数void* create_board(),返回new BOARD_CLASS_NAME();Board::GetInstance()通过static_cast<Board*>(create_board())获取单例。每个固件只能注册一个板级类。Board基类(board.h)声明的关键纯虚函数包括GetBoardType()、GetAudioCodec()、GetNetwork()、StartNetwork()、GetNetworkStateIcon()、SetPowerSaveLevel()、GetBoardJson()等;GetDisplay()、GetLed()、GetBacklight()等为可选的默认实现(默认返回nullptr)。WifiBoard(wifi_board.h)在Board之上封装了 Wi-Fi 连接管理、EnterWifiConfigMode()配网模式、网络事件回调等能力;如果你使用 4G 模组(如 ML307),则应继承Ml307Board或DualNetworkBoard。- 按钮回调中
app.GetDeviceState() == kDeviceStateStarting表示设备处于启动配网状态,此时单击进入 Wi-Fi 配网模式(EnterWifiConfigMode()),否则切换对话状态(app.ToggleChatState())。真实项目中的更复杂按钮(触摸对讲、音量加减、长按最大/静音)可参考 compact_wifi_board.cc 的InitializeButtons()。 InitializeTools()用于注册 MCP 工具(如灯控LampController),可参考 MCP 协议文档 与 MCP 使用指南。
第 5 步:接入构建系统(Kconfig + CMakeLists)
在 main/Kconfig.projbuild 中添加开发板选项
打开 main/Kconfig.projbuild,在choice BOARD_TYPE中添加新配置项:
choice BOARD_TYPE prompt "Board Type" default BOARD_TYPE_BREAD_COMPACT_WIFI help Board type. 开发板类型 # ... 其他开发板选项 ... config BOARD_TYPE_MY_CUSTOM_BOARD bool "My Custom Board (我的自定义开发板)" depends on IDF_TARGET_ESP32S3 # 根据你的目标芯片修改 endchoice注意事项:
BOARD_TYPE_MY_CUSTOM_BOARD是配置项名称,需要全大写,使用下划线分隔。depends on指定目标芯片类型(如IDF_TARGET_ESP32S3、IDF_TARGET_ESP32C3等)。仓库真实示例见 Kconfig.projbuild 中BOARD_TYPE_BREAD_COMPACT_WIFI等配置的写法(默认项带if IDF_TARGET_ESP32S3约束)。- 描述文字可以使用中英文。
在 main/CMakeLists.txt 中添加开发板配置
打开 main/CMakeLists.txt,在板型判断链中添加分支:
# 在 elseif 链中添加你的开发板配置 elseif(CONFIG_BOARD_TYPE_MY_CUSTOM_BOARD) set(BOARD_DIR "my-custom-board") # 相对于 main/boards 的完整路径 set(BUILTIN_TEXT_FONT font_puhui_basic_20_4) # 根据屏幕大小选择合适的字体 set(BUILTIN_ICON_FONT font_awesome_20_4) set(DEFAULT_EMOJI_COLLECTION twemoji_64) # 可选,如果需要表情显示 endif()仓库真实分支可参考 CMakeLists.txt 第 93 行起的if(CONFIG_BOARD_TYPE_BREAD_COMPACT_WIFI)分支,其中set(BOARD_DIR "bread-compact-wifi")同时设置了该板默认字体。
字体和表情配置说明(按屏幕分辨率选择):
| 屏幕规格 | 文本字体 | 图标字体 |
|---|---|---|
| 小屏幕(128x64 OLED) | font_puhui_basic_14_1 | font_awesome_14_1 |
| 中小屏幕(240x240) | font_puhui_basic_16_4 | font_awesome_16_4 |
| 中等屏幕(240x320) | font_puhui_basic_20_4 | font_awesome_20_4 |
| 大屏幕(480x320+) | font_puhui_basic_30_4 | font_awesome_30_4 |
表情集合选项:twemoji_32(32x32,小屏幕)、twemoji_64(64x64,大屏幕)。
第 6 步:配置与编译
方法一:使用 idf.py 手动配置
# 1. 设置目标芯片(首次配置或更换芯片时) idf.py set-target esp32s3 # 或 esp32c3 / esp32 / esp32p4 等 # 2. 清理旧配置 idf.py fullclean # 3. 进入配置菜单,导航到 Xiaozhi Assistant -> Board Type,选择自定义开发板 idf.py menuconfig # 4. 编译和烧录 idf.py build idf.py flash monitor方法二:使用 build.py 脚本(推荐)
只要开发板目录下有config.json,即可用 scripts/build.py 一键完成配置与编译:
python scripts/build.py my-custom-board语言和唤醒词属于用户构建参数:
python scripts/build.py my-custom-board \ --language en-US \ --wake-word wn9_jarvis_tts参数取值规则:
--language接受 main/assets/locales/ 下已有的 locale(如zh-CN、en-US),大小写与-/_会被归一化处理。--wake-word接受 ESP-SR 模型名、nihaoxiaozhi(自动选择与目标芯片兼容的模型)或disabled。ESP32-C3/C5/C6 仅支持 WakeNet9s(wn9s_*)模型;ESP32-S3/P4/S31 构建会自动使用 AFE 唤醒引擎。这一约束与 scripts/build.py 中的_LITE_WAKE_WORD_TARGETS = {"esp32c3", "esp32c5", "esp32c6"}和_AFE_WAKE_WORD_TARGETS = {"esp32s3", "esp32p4", "esp32s31"}完全对应。
可以用文本或 JSON 格式查询可用值:
python scripts/build.py --list-languages python scripts/build.py --list-languages --json python scripts/build.py --list-wake-words python scripts/build.py --list-wake-words --json注意:唤醒词列表从当前已解析的 ESP-SR 组件读取(即managed_components/espressif__esp-sr/Kconfig.projbuild)。如果尚未生成managed_components/,请先运行idf.py reconfigure。
build.py的自动化行为(与源码实现对应):
- 不传参数时打印帮助;使用
--list-boards列出所有开发板类型和变体。 - 如果开发板有多个变体(
builds数组),交互式提示选择;非交互环境使用--name <变体>(如python scripts/build.py bread-compact-wifi --name bread-compact-wifi-128x64)。 - 读取
config.json中的target;仅当已有 build 目录的目标芯片不同时才执行fullclean,然后通过一次idf.py reconfigure同时配置目标芯片、开发板名称、defaults 和所选变体的sdkconfig_append(该片段被写入build/xiaozhi-build.sdkconfig.defaults),随后的idf.py build复用这份配置。 - 将所选 build 的
name作为固件上报的变体名称。 - 默认生成
build/merged-binary.bin,不创建 ZIP;指定--zip时会重新生成releases/v<版本>_<名称>.zip(版本号来自根 CMakeLists.txt 的PROJECT_VER)。 - 另外还支持
--build-options-json传入语义化构建选项(如aec_mode、wifi_provisioning、display_style等),具体键值由--list-boards --json对所选变体输出,供 CLI、Agent 与在线编译接口共用。
第 7 步:创建 README.md
在开发板目录中编写README.md,说明开发板特性、硬件要求、编译和烧录步骤,便于其他开发者复现与维护。
四、常见开发板组件一览
1. 显示屏
项目支持多种显示屏驱动,包括:ST7789(SPI)、ILI9341(SPI)、SH8601(QSPI)、SSD1306/SSD1315(I2C OLED,见 bread-compact-wifi 的 SSD1306 初始化示例)、SH1106 等。SPI 屏走SpiLcdDisplay(如本文示例),OLED 屏走OledDisplay,均在 main/display/ 的lcd_display.h/oled_display.h中定义。
2. 音频编解码器
支持的编解码器包括:ES8311(常用)、ES7210(麦克风阵列)、AW88298(功放)、ES8374/ES8388/ES8389 等,实现均位于 main/audio/codecs/,统一继承AudioCodec基类(audio_codec.h)。
3. 电源管理
部分开发板使用电源管理芯片,如 AXP2101(实现见 main/boards/common/axp2101.cc)等 PMIC,用于电池充电管理与电量读取。
4. MCP 设备控制
可以添加各种 MCP 工具让 AI 能够使用:Speaker(扬声器控制)、Screen(屏幕亮度调节)、Battery(电池电量读取)、Light(灯光控制)等。MCP 服务端实现位于 main/mcp_server.cc,协议细节见 MCP 协议文档。
五、开发板类继承关系
板级类统一继承自Board抽象基类(main/boards/common/board.h):
Board- 基础板级类WifiBoard- Wi-Fi 连接的开发板Ml307Board- 使用 4G 模块的开发板DualNetworkBoard- 支持 Wi-Fi 与 4G 网络切换的开发板
选择继承哪个基类取决于硬件网络方案:Wi-Fi 板卡选WifiBoard,4G 模组(如 ML307)选Ml307Board,双网卡选DualNetworkBoard(实现分别见 wifi_board.cc、ml307_board.cc、dual_network_board.cc)。
六、开发技巧
- 参考相似的开发板:新开发板与现有开发板相似时,优先参考现有实现——仓库
main/boards/下有 70 多种板卡可作为"抄作业"模板,从中挑选芯片型号、屏幕类型、编解码芯片最接近的一块作为起点。 - 分步调试:先实现基础功能(如显示),再添加更复杂的功能(如音频)。
- 管脚映射:确保在
config.h中正确配置所有管脚映射,逐一核对 I2S、I2C、SPI、按钮、背光管脚与原理图一致。 - 检查硬件兼容性:确认所有芯片和驱动程序的兼容性,特别是编解码芯片地址与屏幕驱动型号。
七、可能遇到的问题
| 现象 | 排查方向 |
|---|---|
| 显示屏不正常 | 检查 SPI 配置、镜像设置(DISPLAY_MIRROR_X/Y)和颜色反转设置(esp_lcd_panel_invert_color) |
| 音频无输出 | 检查 I2S 配置、PA 使能引脚(AUDIO_CODEC_PA_PIN)和编解码器地址 |
| 无法连接网络 | 检查 Wi-Fi 凭据和网络配置,确认type/name标识唯一且未被其他板卡占用 |
| 无法与服务器通信 | 检查 MQTT 或 WebSocket 配置,参考 MQTT/UDP 协议文档 与 WebSocket 文档 |
八、参考资料
- 本指南英文版:docs/custom-board.md
- 自定义开发板接线与硬件方案:docs/v0/wiring.jpg、docs/v1/wiring2.jpg
- 板级公共组件源码:main/boards/common/
- 构建脚本:scripts/build.py
- 分区表定义:partitions/v2/
- 语言资源目录:main/assets/locales/
- 音频编解码器实现:main/audio/codecs/
- 显示驱动实现:main/display/
- MCP 协议与使用:docs/mcp-protocol_zh.md、docs/mcp-usage_zh.md
- ESP-IDF 相关开发细节可参考仓库内 esp-idf-6-migration.md 迁移文档
【免费下载链接】xiaozhi-esp32An MCP-based chatbot | 一个基于MCP的聊天机器人项目地址: https://gitcode.com/GitHub_Trending/xia/xiaozhi-esp32
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考