WT9932P4C61-TINY 开发指南
更新历史
| 日期 | 版本 | 作者 | 更新内容 |
|---|---|---|---|
| 2026-07-15 | 1.1.0 | Yobie Zhou | 增加 WT_BSP 获取与更新方法,并同步最新示例目录和开发流程 |
| 2026-07-09 | 1.0.0 | Yobie Zhou | 新增基于 WT_BSP 的应用开发流程 |
一、开发方式概览
WT_BSP 是 Wireless-Tag 为 ESP32 系列开发板维护的板级支持包。使用 WT9932P4C61-TINY 开发时,推荐把应用逻辑建立在 WT_BSP 之上,而不是在业务代码中直接写具体 GPIO、屏幕初始化参数、摄像头引脚或 SD 卡管脚。
基于 WT_BSP 开发的核心思路是:
- 应用工程通过
components/wt_bsp引入 BSP 组件。 - 使用
idf.py set-board选择WT9932P4C61-TINY。 - 应用调用
wt_bsp_init()初始化板级资源。 - 应用通过
wt_bsp_get_rgb()、wt_bsp_get_button()、wt_bsp_get_sdmmc()、wt_bsp_get_dsi()、wt_bsp_get_csi()、wt_bsp_get_touch()获取资源句柄。 - 应用根据返回值判断功能是否可用,并实现自己的业务逻辑。
这样做的好处是:
- 应用代码不绑定具体硬件引脚。
- 同一个示例可以较低成本适配多块 Wireless-Tag 开发板。
- 外设能力可通过
menuconfig裁剪。 - 板级差异由
components/wt_bsp/boards/WT9932P4C61-TINY统一维护。
二、获取与更新 WT_BSP
WT_BSP 的官方仓库地址为:
仓库仍在持续更新。首次获取时应从官方仓库克隆;已经下载过仓库的用户,在开始新项目或排查问题前应先同步 main 分支,以便使用最新的板级适配、示例和工具。
2.1 环境要求
开始前请准备:
Git。ESP-IDF。WT_BSP 当前针对ESP-IDF v6.0.1及以上版本优化,并兼容v5.3及以上版本;新项目推荐使用v6.0.1或更新版本。- 已激活的 ESP-IDF 开发环境,确保
idf.py --version可以正常输出版本信息。
2.2 首次克隆仓库
选择一个用于存放开发项目的目录,然后克隆官方仓库:
mkdir -p ~/work
cd ~/work
git clone https://github.com/Wireless-TAG-Maker/WT_BSP.git
cd WT_BSP
当前仓库不要求通过 --recursive 获取子模块,直接执行上述 git clone 即可。克隆完成后检查当前分支和最新提交:
git status --short --branch
git log -1 --oneline
正常情况下应位于 main 分支。后续示例统一假设仓库位于:
~/work/WT_BSP
实际开发时可以使用其他目录,只需把文档命令中的路径替换为自己的真实路径。
2.3 更新已有仓库
如果本地已经存在 WT_BSP,先进入仓库并检查是否有未提交修改:
cd ~/work/WT_BSP
git status --short --branch
如果工作区干净,可以切换到 main 并使用仅快进方式同步官方更新:
git switch main
git pull --ff-only origin main
更新后再次确认当前版本:
git log -1 --oneline
如果 git status 显示有本地修改,请先提交到自己的开发分支,或使用 git stash 暂存,再更新 main。不要为了更新仓库直接删除本地修改。
建议:自定义应用尽量放在 WT_BSP 仓库外部,或保存在独立 Git 分支中。这样后续同步官方
main时,不容易与自己的业务代码产生冲突。团队协作时还应记录验证过的 WT_BSP commit,便于其他开发者复现相同的构建环境。
2.4 从最新示例开始验证
每次更新 WT_BSP 后,建议先编译最小的 blink 示例,确认 ESP-IDF、BSP 和板卡选择工具工作正常:
cd ~/work/WT_BSP/examples/get-started/blink
idf.py set-board
idf.py build
在交互列表中选择 WT9932P4C61-TINY。如果需要非交互构建,可以执行:
WT_BSP_BOARD=WT9932P4C61-TINY idf.py set-board
idf.py build
set-board 会生成当前工程使用的板级默认配置;切换到目标芯片不同的开发板时,工具会自动执行 fullclean。
三、WT_BSP 目录结构
假设本地仓库路径为:
~/work/WT_BSP
主要目录如下:
| 路径 | 说明 |
|---|---|
components/wt_bsp |
BSP 核心组件 |
components/wt_bsp/include |
顶层公共头文件,例如 wt_bsp.h |
components/wt_bsp/src |
BSP 公共实现 |
components/wt_bsp/features |
可复用外设能力,如 RGB、按键、SDMMC、DSI、CSI、Touch |
components/wt_bsp/boards |
具体开发板适配 |
components/wt_bsp/boards/WT9932P4C61-TINY |
当前开发板的板级配置和资源初始化 |
components/wt_bsp/tools |
set-board、p4_flash 和 CMake 辅助脚本 |
examples/get-started/blink |
最小 RGB LED 示例,适合验证环境和 BSP 初始化 |
examples/get-started/button |
板载按键事件示例 |
examples/get-started/c61-hello-through-p4 |
通过 P4 桥接烧录并运行 C61 Hello 示例 |
examples/display/dsi |
MIPI DSI 显示和 LVGL 示例 |
examples/camera/csi |
MIPI CSI 摄像头、PPA 和 DSI 实时显示示例 |
examples/storage/sdmmc |
MicroSD 挂载和文件读写示例 |
examples/wifi/esp-hosted/wt9932p4c61-tiny |
P4 通过 ESP-Hosted 使用板载 C61 Wi-Fi 的示例 |
examples/wt_factory/wt9932p4c61-tiny |
显示、摄像头、触摸、SD 卡和 Wi-Fi 综合工厂测试示例 |
应用开发者通常只需要关注:
examples/:优先阅读与需求最接近的示例及其README_CN.md,再复制或参考代码。components/wt_bsp/include/wt_bsp.h:查看 BSP 顶层 API。components/wt_bsp/features/*/include/:查看各外设能力的 API。
不建议应用层直接包含:
#include "boards/WT9932P4C61-TINY/board.h"
#include "board_config.h"
这些文件属于板级适配内部实现,应用层应通过 wt_bsp.h 获取统一接口。
四、新建自己的应用工程
4.1 选择最接近需求的示例
最新 WT_BSP 已按功能提供多个独立示例。创建应用前,先根据需求选择起点:
| 开发需求 | 推荐起点 |
|---|---|
| 验证环境、控制 RGB LED | examples/get-started/blink |
| 处理板载按键 | examples/get-started/button |
| 驱动 MIPI DSI 屏幕和 LVGL | examples/display/dsi |
| 采集 MIPI CSI 摄像头并显示 | examples/camera/csi |
| 使用 MicroSD 卡 | examples/storage/sdmmc |
| P4 通过 C61 使用 Wi-Fi | examples/wifi/esp-hosted/wt9932p4c61-tiny |
| 单独体验或开发 C61 | examples/get-started/c61-hello-through-p4 |
| 同时使用显示、摄像头、触摸、SD 卡和 Wi-Fi | examples/wt_factory/wt9932p4c61-tiny |
先阅读所选示例目录中的 README_CN.md,确认硬件连接和构建步骤,再以该示例为基线开发。
4.2 从 blink 示例复制最小应用
如果是第一个自定义应用,建议从 blink 示例复制,因为它结构最小、依赖清晰。
get_idf
cd ~/work/WT_BSP/examples
mkdir -p my_apps
cp -r get-started/blink my_apps/my_p4c61_app
cd my_apps/my_p4c61_app
复制后建议清理旧构建产物:
rm -rf build managed_components sdkconfig sdkconfig.old
保留以下文件:
| 文件 | 是否保留 | 说明 |
|---|---|---|
CMakeLists.txt |
保留 | 已接入 WT_BSP 的 CMake 辅助脚本 |
main/CMakeLists.txt |
保留 | 注册应用源码 |
main/main.c |
修改 | 替换为自己的业务逻辑 |
sdkconfig.defaults |
保留或修改 | 工程默认配置 |
sdkconfig.wt9932p4c61_tiny |
保留 | set-board 需要读取的板级默认配置 |
README.md / README_CN.md |
修改 | 改成自己的应用说明 |
然后选择开发板并构建:
WT_BSP_BOARD=WT9932P4C61-TINY idf.py set-board
idf.py build
4.3 新工程必须具备的 CMake 配置
工程顶层 CMakeLists.txt 需要把 WT_BSP 的 components 目录加入 ESP-IDF,并调用 WT_BSP 的板级默认配置函数。
如果工程仍放在 WT_BSP/examples/... 下,可参考:
cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS "../../../components")
include("../../../components/wt_bsp/tools/wt_bsp_project.cmake")
wt_bsp_apply_sdkconfig_defaults()
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(my_p4c61_app)
如果工程放在 WT_BSP 仓库外部,例如:
~/work/my_p4c61_app
而 WT_BSP 位于:
~/work/WT_BSP
则可以写成:
cmake_minimum_required(VERSION 3.16)
set(WT_BSP_PATH "$ENV{HOME}/work/WT_BSP")
set(EXTRA_COMPONENT_DIRS "${WT_BSP_PATH}/components")
include("${WT_BSP_PATH}/components/wt_bsp/tools/wt_bsp_project.cmake")
wt_bsp_apply_sdkconfig_defaults()
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(my_p4c61_app)
main/CMakeLists.txt 通常保持简单:
idf_component_register(SRC_DIRS "."
INCLUDE_DIRS ".")
如果你的应用拆分了更多源码目录,可以在 SRC_DIRS 或 SRCS 中继续添加。
4.4 添加板级默认配置文件
idf.py set-board 会在当前工程目录查找开发板对应的默认配置文件。对于 WT9932P4C61-TINY,文件名应为:
sdkconfig.wt9932p4c61_tiny
最小内容可以包含:
CONFIG_WT_BSP_BOARD_WT9932P4C61_TINY=y
实际项目中还可以加入与该板卡相关的默认配置,例如分区表、PSRAM、LVGL、显示或摄像头相关配置。建议从官方示例复制同名文件,再按项目需求调整。
执行:
idf.py set-board
会生成:
sdkconfig.board
sdkconfig.board.Kconfig
这两个文件由工具生成,不建议手动编辑。
五、基础应用模板
下面是一个最小应用模板,用于初始化 BSP、点亮 RGB LED,并读取板卡信息。
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "wt_bsp.h"
static const char *TAG = "my_app";
void app_main(void)
{
esp_err_t ret = wt_bsp_init();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "BSP init failed: %s", esp_err_to_name(ret));
return;
}
wt_bsp_board_t board = wt_bsp_get_board();
if (board) {
ESP_LOGI(TAG, "WT_BSP board initialized");
}
wt_bsp_rgb_t rgb = wt_bsp_get_rgb();
if (rgb) {
wt_bsp_rgb_set_pixel(rgb, 0, (wt_bsp_rgb_color_t){.r = 0, .g = 64, .b = 255});
wt_bsp_rgb_refresh(rgb);
}
while (1) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
关键点:
wt_bsp_init()必须先调用。wt_bsp_get_*()可能返回NULL,应用必须检查。- 不要假设所有板卡都具备显示、摄像头、触摸或 SD 卡。
- 不要在应用代码中直接使用板级私有引脚宏。
六、选择、编译、烧录
6.1 选择开发板
交互方式:
idf.py set-board
非交互方式:
WT_BSP_BOARD=WT9932P4C61-TINY idf.py set-board
构建时直接指定:
WT_BSP_BOARD=WT9932P4C61-TINY idf.py build
如果工程中存在多个开发板配置文件,set-board 会列出可选开发板。选择 WT9932P4C61-TINY 后,目标芯片会被设置为 esp32p4。
6.2 编译
idf.py build
如果修改了板级选择、目标芯片或底层配置后遇到奇怪的编译错误,可清理后重试:
idf.py fullclean
idf.py build
6.3 烧录 ESP32-P4 应用
P4 应用使用 FUSB 烧录:
idf.py -p /dev/ttyACM0 flash monitor
退出监视器:
Ctrl + ]
6.4 使用 menuconfig 裁剪能力
进入配置界面:
idf.py menuconfig
可以按工程需要关闭不使用的外设能力,减少初始化开销和依赖。配置后重新编译:
idf.py build
应用代码中仍然需要检查 wt_bsp_get_*() 返回值。因为某个外设可能由于硬件不支持、配置关闭或初始化失败而不可用。
七、常用 BSP 能力
7.1 RGB LED
WT9932P4C61-TINY 板载 WS2812 RGB LED。使用流程:
wt_bsp_rgb_t rgb = wt_bsp_get_rgb();
if (rgb) {
wt_bsp_rgb_set_pixel(rgb, 0, (wt_bsp_rgb_color_t){.r = 255, .g = 0, .b = 0});
wt_bsp_rgb_refresh(rgb);
}
建议用途:
- 启动状态提示。
- 错误状态提示。
- 网络连接状态提示。
- 简单交互反馈。
7.2 按键
应用可通过 wt_bsp_get_button() 获取默认按键句柄,并注册事件回调。按键回调里建议只做轻量操作,例如设置标志位、发送队列消息,不要执行长时间阻塞逻辑。
示意流程:
static void button_cb(wt_bsp_button_t button,
wt_bsp_button_event_t event,
void *user_data)
{
if (event == WT_BSP_BUTTON_EVENT_KEEPALIVE) {
/* 设置标志位或通知任务 */
} else if (event == WT_BSP_BUTTON_EVENT_RELEASE) {
/* 清理长按状态或处理释放事件 */
}
}
wt_bsp_button_t button = wt_bsp_get_button();
if (button) {
wt_bsp_button_register_event_cb(button, button_cb, NULL);
}
具体事件枚举和函数声明以 components/wt_bsp/features/button/include/wt_bsp_button.h 为准。
7.3 MicroSD
使用 SD 卡前先获取句柄并挂载:
wt_bsp_sdmmc_t sdmmc = wt_bsp_get_sdmmc();
if (sdmmc) {
esp_err_t ret = wt_bsp_sdmmc_mount(sdmmc);
if (ret == ESP_OK) {
sdmmc_card_t *card = wt_bsp_sdmmc_get_card(sdmmc);
(void)card;
}
}
使用建议:
- 插卡后再挂载。
- 文件读写前确认挂载成功。
- 写入重要数据后及时
fsync或关闭文件。 - SD 卡相关引脚和供电由 BSP 板级适配处理,应用不应重复初始化底层 SDMMC 总线。
7.4 MIPI DSI 显示和 LVGL
工厂测试示例演示了显示和 LVGL 使用方式。应用开发时建议参考:
examples/wt_factory/wt9932p4c61-tiny/main/main.c
examples/wt_factory/wt9932p4c61-tiny/main/lvgl_ui.c
常见流程:
- 调用
wt_bsp_init()。 - 获取 DSI 显示资源。
- 使用 BSP 提供的 LVGL lock/unlock 保护 LVGL 操作。
- 在 UI 任务或受保护的区域更新控件。
需要注意:
- LVGL 不是线程安全的,多任务访问时必须使用锁。
- 显示屏 FPC 方向和线序必须与开发板匹配。
- 屏幕未连接时,应用应能给出错误提示或降级运行。
7.5 MIPI CSI 摄像头
摄像头使用建议参考工厂测试示例中的 camera callback。典型流程:
- 初始化 BSP。
- 获取 CSI 摄像头资源。
- 注册帧回调或启动采集。
- 根据显示格式进行颜色转换、缩放或旋转。
- 把处理后的帧送到 UI 或业务算法。
ESP32-P4 适合处理显示、摄像头和图像搬运。工厂测试示例中使用 PPA 进行图像格式转换和旋转,避免把所有像素处理压到 CPU 上。
7.6 触摸
触摸通常与 DSI 显示和 LVGL 一起使用。应用中应通过 BSP 获取触摸资源,不建议单独重复初始化触摸控制器。屏幕、触摸型号和 I2C 参数由板级适配维护。
7.7 Wi-Fi 与 ESP32-C61
ESP32-P4 本身不提供 Wi-Fi。WT9932P4C61-TINY 通过板载 ESP32-C61 提供无线能力。开发时有两类场景:
| 场景 | 建议方式 |
|---|---|
| P4 应用需要 Wi-Fi | 参考工厂测试示例,使用 ESP-Hosted / Wi-Fi remote 相关组件,让 P4 通过 C61 获取无线能力 |
| 单独开发 C61 固件 | 先执行 idf.py p4_flash,再通过 HUSB 烧录和调试 C61 |
如果只是控制 RGB、显示、摄像头、SD 卡等 P4 外设,不需要烧录 C61。
八、基于工厂测试示例做功能开发
如果你的项目需要显示、摄像头、触摸、SD 卡和 Wi-Fi,建议从工厂测试示例开始裁剪,而不是从 blink 逐项添加复杂依赖。
复制示例:
cd ~/work/WT_BSP/examples
mkdir -p my_apps
cp -r wt_factory/wt9932p4c61-tiny my_apps/my_factory_app
cd my_apps/my_factory_app
rm -rf build managed_components sdkconfig sdkconfig.old
建议按以下顺序改造:
- 保留
wt_bsp_init()和硬件初始化主流程。 - 先确认原始工厂固件能正常编译、烧录、运行。
- 删除不需要的 UI 页面或控件。
- 保留 SD 卡、摄像头、Wi-Fi 等底层任务中你需要的部分。
- 修改
lvgl_ui.c,替换为自己的界面。 - 修改
main.c中的业务状态机。 - 最后再调整分区表、NVS、日志等级和性能参数。
不要一开始就同时修改 UI、摄像头、Wi-Fi 和分区表。先保持一个可运行基线,再逐项替换,更容易定位问题。
九、单独开发 ESP32-C61 固件
如果你要把板载 ESP32-C61 当作独立 MCU 开发,需要通过 P4 桥接烧录。
9.1 使用官方 C61 示例
最新 WT_BSP 提供了专门的 C61 入门示例:
examples/get-started/c61-hello-through-p4
建议先完整运行该示例,再把其中的 C61 工程作为独立开发的起点。
9.2 烧录 P4 桥接固件
连接 FUSB,进入官方 C61 示例并执行:
cd ~/work/WT_BSP/examples/get-started/c61-hello-through-p4
idf.py set-target esp32c61
idf.py p4_flash
按提示选择 P4 串口,并输入 Y 确认覆盖当前 P4 固件。
9.3 切换到 HUSB
p4_flash 成功后:
- 拔掉
FUSB。 - 接入
HUSB。 - 在 WSL2 中重新挂载 USB 设备。
- 使用
ls /dev/ttyACM*查找新的 CDC 串口。
9.4 烧录 C61 工程
仍在 c61-hello-through-p4 示例目录时,直接通过 HUSB 枚举出的 TinyUSB CDC 串口烧录:
idf.py -p <HUSB_CDC_PORT> flash monitor
将 <HUSB_CDC_PORT> 替换为 HUSB 对应的实际端口。示例正常运行后,串口会持续输出 Hello Wireless-tag 相关日志。
确认官方示例工作正常后,再复制该示例并修改 C61 应用代码。P4 仅在烧录桥接固件时使用;后续编译、烧录和调试 C61 都通过 HUSB 完成。
如果后续要恢复 P4 应用,需要重新连接 FUSB 并烧录 P4 工程。
十、调试建议
10.1 日志
建议每个模块定义自己的 TAG:
static const char *TAG = "my_module";
ESP_LOGI(TAG, "module started");
调试阶段可以在 menuconfig 中提高日志等级;发布前再降低不必要的日志。
10.2 构建目录
如果需要同时维护 P4 应用和 C61 应用,建议使用不同工程目录或不同 build 目录,避免配置互相覆盖。
示例:
idf.py -B build_p4 build
idf.py -B build_c61 set-target esp32c61 build
10.3 依赖更新
ESP-IDF managed components 会生成:
managed_components/
dependencies.lock
managed_components/ 是下载产物;dependencies.lock 用于锁定依赖版本。团队协作时,建议保留 lock 文件,避免不同电脑解析出不同组件版本。
10.4 常见错误定位顺序
遇到问题时建议按以下顺序定位:
idf.py --version,确认 ESP-IDF 版本。idf.py set-board,确认选择的是WT9932P4C61-TINY。idf.py build,确认编译是否通过。idf.py -p <PORT> flash monitor,确认端口是否正确。- 查看启动日志中
wt_bsp_init()是否成功。 - 检查
wt_bsp_get_*()是否返回NULL。 - 确认对应外设是否连接、电源是否稳定、FPC 方向是否正确。
- 对 C61 相关问题,确认是否已经烧录 slave 固件,并区分当前连接的是
FUSB还是HUSB。
十一、开发规范建议
- 应用层只包含
wt_bsp.h和各业务模块头文件。 - 应用层不要直接依赖
boards/<BOARD>/中的私有头文件。 - 对所有
wt_bsp_get_*()返回值做NULL检查。 - 对所有返回
esp_err_t的 BSP / ESP-IDF 调用做错误处理。 - 长时间任务放到 FreeRTOS task,不要阻塞按键回调或 LVGL 临界区。
- LVGL 更新统一放在持锁区域或 UI 任务中。
- 摄像头帧处理注意 PSRAM、cache alignment 和帧缓冲生命周期。
- SD 卡写入注意异常断电风险。
- P4 与 C61 分开理解:P4 负责主应用和高性能外设,C61 负责无线或独立低功耗任务。
十二、推荐阅读顺序
- 仓库根目录
README_CN.md:确认当前支持的开发板、ESP-IDF 版本和最新使用方式。 examples/get-started/blink/README_CN.md和main/main.c:理解板卡选择、BSP 初始化和 RGB 控制。examples/get-started/button、examples/display/dsi、examples/camera/csi、examples/storage/sdmmc:按实际外设需求学习独立示例。components/wt_bsp/include/wt_bsp.h:查看 BSP 顶层入口。components/wt_bsp/features/*/include/:按需查看 RGB、Button、SDMMC、DSI、CSI、Touch API。examples/wifi/esp-hosted/wt9932p4c61-tiny:学习 P4 如何通过 C61 使用 Wi-Fi。examples/get-started/c61-hello-through-p4:学习通过 P4 桥接烧录和调试 C61。examples/wt_factory/wt9932p4c61-tiny/main/main.c:学习复杂外设初始化和任务组织。examples/wt_factory/wt9932p4c61-tiny/main/lvgl_ui.c:学习 UI 层如何与硬件状态联动。
完成这些内容后,就可以基于 WT_BSP 搭建自己的 WT9932P4C61-TINY 应用工程。