待机、电源管理与 USB 从机
语音玩具应用(voice-toy)中负责低功耗待机(Standby)、电源状态管理(Power Management) 与 USB 从机(USB Device / Slave) 功能的子系统说明。该子系统决定了玩具设备在电池供电下的续航表现、充电/供电行为,以及设备以 USB Device 角色与主机(PC、充电器、U 盘/声卡主机)交互的方式。
Purpose and Scope
本页覆盖 applications/voice-toy/power-usb 目录所对应的完整能力域:
- 待机管理:应用何时进入低功耗待机、如何保存/恢复上下文、由哪些唤醒源退出待机;
- 电源管理:充电检测、电池电量监控、电源事件(插入/拔出/充满)的分发与策略;
- USB 从机:设备如何以 USB Device 角色完成枚举、加载类驱动(声卡/复合设备等)、与充电/待机策略共存。
边界声明:本页只覆盖上述电源与 USB 从机能力。voice-toy 应用的其他业务(语音播放、按键交互、蓝牙配对、玩具逻辑等)若存在于目录树中,应归其各自的 Wiki 页面,不在本页展开。
源码证据说明(重要):在本次文档生成的源码探索预算(6 次工具调用)内,ListFiles 与 Grep 均未在可检索树中命中 applications/voice-toy/**、apps/**、power_usb 等模式;仓库根目录当前可检索到的仅有 README.md、README-en.md、LICENSE 与 jl_ad_chip.png。因此本页以「能力边界 + 预期架构 + 待验证项」的方式撰写,所有未经源码验证的结论均明确标注「待验证」,读者应以仓库实际源码为准进行核对。
Overview
在 JieLi(杰理)AD 系列 MCU SDK 的典型应用中,voice-toy 这类电池供电的语音玩具设备有三个紧密耦合的基础需求:
- 待机(Standby):玩具在无人操作时应当尽快进入低功耗状态以延长电池续航。这通常意味着关闭不必要的外设时钟、降低 CPU 频率或进入芯片级休眠,同时保留按键、充电检测、USB 插入等唤醒源。
- 电源管理(Power Management):设备需要感知电源状态——是否插入充电器、电池电压高低、是否充满——并根据状态调整行为(例如充电中禁止进入深度休眠、电量不足时限制功能)。
- USB 从机(USB Slave / Device):玩具通常通过 USB 口完成充电,同时也可能作为 USB Device 与主机通信(例如固件升级、U 盘/声卡模式、调试日志)。USB 插入既可能是「仅充电」也可能是「数据连接」,这直接影响枚举流程与电源策略。
三者并非独立模块,而是共享同一组硬件事件:USB 插入(VBUS 检测) 既是充电信号、也是 USB 从机枚举的起点、还是从待机唤醒的触发源。因此该子系统的核心设计问题是如何在低功耗与对外通信/充电服务之间做状态仲裁。
Architecture
下图给出该子系统预期(待验证)的分层架构。节点名称反映能力职责而非已验证的类名,实际类/函数名以仓库源码为准。
flowchart TD
subgraph sg_App["应用层 voice-toy"]
AppMain["应用主循环 app_main"]
Business["玩具业务逻辑"]
end
subgraph sg_Power["电源管理子系统"]
PowerMgr["电源管理模块"]
Standby["待机/休眠管理"]
Wakeup["唤醒源管理"]
end
subgraph sg_USB["USB 从机子系统"]
UsbDev["USB 从机协议栈"]
UsbClass["USB 类驱动 声卡/复合设备"]
end
subgraph sg_HAL["芯片层 外设与硬件"]
PMU["PMU 电源域/时钟"]
USBPhy["USB PHY D+/D-"]
Charger["充电检测 VBUS/电量"]
end
AppMain --> Business
Business --> PowerMgr
Business --> UsbDev
PowerMgr --> Standby
PowerMgr --> Wakeup
PowerMgr --> PMU
Standby --> PMU
UsbDev --> UsbClass
UsbDev --> USBPhy
Charger --> PowerMgr
Charger --> UsbDev
架构说明(基于 JieLi AD 系列 SDK 通用分层,待验证):
- 应用层:
voice-toy的主循环(如app_main)驱动业务逻辑;业务模块在空闲时主动请求进入待机,在有数据需要与主机交互时请求 USB 从机工作。 - 电源管理子系统:承接业务层与芯片层之间的电源状态仲裁——决定进入哪种低功耗模式、配置哪些唤醒源、在唤醒后恢复哪些外设。
- USB 从机子系统:在 USB 插入且被判定为数据连接时启动枚举;枚举完成后按类驱动(声卡/复合设备等)与主机通信。
- 芯片层:PMU/电源域、USB PHY、充电检测是硬件基础;电源管理与 USB 从机都直接操作这些硬件,二者通过共享的插入/拔出事件解耦。
设计意图:将「电源状态仲裁」与「USB 协议处理」分层,是为了让业务代码只关心「我要休眠」或「我要通信」,而不直接接触寄存器级的电源域切换与 USB 协议细节;同时让充电检测这类硬件事件可以同时驱动两条路径(充电策略 + 枚举启动),避免两套逻辑重复轮询硬件。
源码证据与缺口
- ✅ 已验证:仓库根目录存在 README.md、README-en.md、
LICENSE、jl_ad_chip.png。 - ⚠️ 未命中:
ListFiles("apps/voice-toy/**/*.c")、ListFiles("**/voice-toy/**")、ListFiles("apps/**")均返回空;Grep("power_usb|POWER_USB|usb_slave|USB_SLAVE")与Grep("power_usb")均无结果。 - 📌 结论:应用源码可能位于工具未索引的子模块/目录布局中(仓库 Git URL 为 fw-AD15N,目录名与 SDK 命名可能不一致),或
voice-toy应用位于客户分支。后续文档更新应在可访问源码树后,将本页所有「待验证」条目替换为真实实现。
待机管理(Standby)
设计意图
对电池供电的语音玩具而言,待机是续航的核心手段。设计上需要回答三个问题:
- 何时进入待机:通常由业务层在「空闲超时」或「主动休眠请求」时触发。过早休眠会打断用户体验,过晚休眠则浪费电量,因此进入条件一般由业务策略(而非电源模块自身)决定。
- 进入多深的休眠:从「关外设时钟」到「整机低功耗/深度休眠」存在多个等级,等级越高省电越多,但唤醒延迟与恢复成本也越高。典型策略是:仅充电/仅 USB 连接时保持浅休眠,无任何外部事件时进入深休眠。
- 如何唤醒:唤醒源通常包括按键(GPIO 中断)、充电器插入(VBUS 检测)、USB 插入(DP 上拉检测)、定时器(周期唤醒巡检)。唤醒后必须恢复时钟、外设与中断状态,并把「唤醒原因」告知业务层,以便业务决定是继续运行还是再次休眠。
以下流程为基于该能力域的预期实现(待验证);真实函数名、状态机与寄存器操作以仓库源码为准。
待机进入/唤醒状态流
stateDiagram-v2
[*] --> Running
Running --> Standby: 空闲超时/主动休眠
Standby --> Running: 唤醒事件 按键/USB/充电
Standby --> Charging: 插入充电器 仅充电
Charging --> Running: 拔除/充满/按键
Running --> Charging: 插入充电器 数据未连接
Running:正常工作态,CPU 全速、外设按需使能。Standby:低功耗待机态,时钟与大部分外设关闭,仅保留唤醒源;USB 未连接。Charging:充电共存态,通常为浅休眠(维持充电监测与电量上报),避免深度休眠导致充电状态不可见。
进入与唤醒的预期时序
sequenceDiagram
participant App as voice-toy 业务层
participant PM as 电源管理模块
participant HAL as 芯片 PMU/低功耗外设
participant USB as USB 从机子系统
App->>PM: 请求进入待机 携带空闲原因
PM->>PM: 关闭非必要外设/保存上下文
PM->>HAL: 配置唤醒源并设置低功耗模式
HAL-->>PM: 唤醒事件 按键/充电/USB插入
PM->>PM: 恢复时钟/外设/中断
PM-->>App: 返回唤醒原因 wakeup_reason
alt 唤醒原因为 USB 插入
App->>USB: 启动 USB 从机初始化
end
关键点(待验证):
- 进入待机前必须先关闭 USB 从机(若在运行),否则 VBUS/DP 状态机与休眠逻辑冲突;
- 唤醒原因需在恢复阶段尽早读取,因为部分唤醒源(如电平型事件)在电源恢复后可能丢失;
- 从休眠恢复后,业务层应根据
wakeup_reason决定路径:按键 → 正常业务;USB 插入 → 枚举;充电 → 仅更新电源状态。
唤醒源(预期分类,待验证)
| 唤醒源 | 类型 | 典型用途 | 备注 |
|---|---|---|---|
| 按键/GPIO | 电平/边沿中断 | 用户交互 | 需配置防抖与去抖滤波 |
| USB VBUS/DP | 电平检测 | 充电/数据连接 | 与充电检测、枚举共享事件 |
| 充电器插入 | ADC/GPIO | 充电状态感知 | 通常保持浅休眠 |
| 定时器 | RTC/系统定时器 | 周期巡检(电量、按键扫描) | 唤醒窗口应尽量短 |
电源管理(Power Management)
职责范围
电源管理模块是待机与 USB 从机之间的仲裁者。它负责:
- 充电检测:通过 VBUS/ADC 判断是否插入充电器、是否在充电、是否充满;
- 电量感知:读取电池电压/电量,向业务层提供电量等级,供业务决定功能裁剪(低电量关灯、关声音等);
- 电源事件分发:将插入/拔出/充满事件广播给待机管理(决定休眠深度)与 USB 从机(决定是否枚举);
- 策略仲裁:例如「充电中禁止深休眠」「低电量禁止 USB 大电流枚举」「插入 USB 数据线时维持运行」等。
电源事件决策流(预期,待验证)
flowchart TD
Start([电源事件] ) --> Detect["VBUS/ADC 采样"]
Detect --> IsInsert{"VBUS 有效?"}
IsInsert -->|"否"| Battery["电池供电模式"]
Battery --> LowPower{"电量充足?"}
LowPower -->|"是"| Normal["正常运行 可进入待机"]
LowPower -->|"否"| Limit["限制功能 提示充电"]
IsInsert -->|"是"| ChargeType{"数据连接 or 仅充电?"}
ChargeType -->|"仅充电"| ChargeMode["充电模式 浅休眠"]
ChargeType -->|"数据连接"| UsbMode["USB 从机模式 保持运行"]
ChargeMode --> Full{"已充满?"}
Full -->|"是"| FullDone["充满 停止充电 上报事件"]
Full -->|"否"| ChargeMode
设计意图:把「电源事件」建模为一条统一决策链,而不是让业务层各自轮询。这样无论事件来自硬件中断还是周期采样,最终都收敛到三态之一——电池供电(可待机)、充电模式(浅休眠)、USB 数据模式(保持运行),从而与待机管理、USB 从机的状态机天然对齐。
与 USB 从机的耦合点
电源管理与 USB 从机共享同一个物理事件(USB 口插入),但语义不同:
| 事件 | 电源管理视角 | USB 从机视角 |
|---|---|---|
| VBUS 插入 | 进入充电态,禁止深休眠 | 等待 DP 上拉确认,准备枚举 |
| DP 检测到主机 | 维持运行态(数据模式) | 开始枚举,加载类驱动 |
| 主机断开 | 回到充电态或电池态 | 断开端点,释放资源 |
| 拔线 | 退出充电态,可恢复待机 | 关闭从机,等待下次插入 |
待验证的关键决策:是否在「仅充电」时也保持 USB 从机可枚举(许多充电器支持 USB 协商,需要枚举后才能拉大电流)。这决定了充电模式是纯硬件充电还是需要跑 USB 协议栈——直接影响休眠深度与功耗预算。
电量与充电状态上报(预期接口形态)
电源模块预计向业务层提供类似以下语义的接口(签名待验证,勿直接调用):
- 查询当前充电状态(未充电 / 充电中 / 充满);
- 查询电池电量百分比或电压等级;
- 注册电源事件回调,业务层订阅插入/拔出/充满通知;
- 查询当前允许的休眠深度(由电源模块根据充电/数据状态仲裁)。
⚠️ 以上为能力域的预期接口形态,用于指导阅读源码时的查找方向(可在仓库中搜索
charge、battery、power、vbus等关键字),并非从源码提取的真实签名。
USB 从机(USB Device / Slave)
角色定位
voice-toy 设备以 USB Device(从机) 身份挂接到主机(PC、充电器或专用底座)上。典型场景:
- 充电:USB 口供电,配合充电管理;
- 固件升级 / 量产工具:通过厂商类或 HID 类与 PC 工具通信;
- U 盘 / 声卡模式:玩具作为存储或音频设备,需要 MSC / Audio 类驱动;
- 调试/日志:CDC(虚拟串口)输出日志。
这些场景对电源策略的影响不同:仅充电时希望浅休眠省电;数据连接时必须保持 CPU 运行以维护 USB 协议栈。
从插入到枚举的预期流程
flowchart TD
Start([USB 插入] ) --> Detect["VBUS/DP 检测"]
Detect --> Charge{"充电检测判定"}
Charge -->|"仅充电"| ChargeOnly["充电模式 不枚举 浅休眠"]
Charge -->|"数据连接"| Enum["启动 USB 从机"]
Enum --> Reset["检测到主机复位信号"]
Reset --> Setup["处理 SETUP 请求 地址分配"]
Setup --> Config["主机配置设备 选择配置"]
Config --> Class["加载类驱动 声卡/MSC/CDC"]
Class --> Ready["设备就绪 与主机通信"]
Ready --> Suspend{"主机断开/挂起?"}
Suspend -->|"是"| Disable["关闭端点 释放资源"]
Suspend -->|"否"| Ready
Disable --> Back(["回到电源决策链"])
关键点(待验证):
- 枚举前判定:从插入到枚举之间存在「充电 vs 数据」的仲裁窗口,通常由充电检测(如 DP/DM 短路检测、USB 电池充电规范 BCS 检测)决定是否走协议栈;
- 枚举状态机:
复位 → 地址设置 → 配置选择 → 类驱动就绪是标准 USB 设备枚举路径,SDK 的从机协议栈应封装了这些阶段; - 与待机的互斥:一旦进入
Config/Ready状态,电源管理应把设备置为「运行态」,待机模块不得在 USB 会话期间进入深休眠,否则会破坏枚举时序; - 断开清理:主机断开后应尽快释放端点与 DMA 资源,并把事件交回电源决策链,让设备重新评估是充电、电池还是待机。
USB 从机生命周期与电源状态映射(预期)
| USB 从机阶段 | 电源管理状态 | 说明 |
|---|---|---|
| 未插入 | Standby / Running | 与 USB 无关 |
| 插入,仅充电 | Charging(浅休眠) | 不枚举,靠硬件充电监测 |
| 插入,枚举中 | Running | 必须维持 CPU 运行 |
| 配置完成,通信中 | Running | 类驱动活跃 |
| 主机挂起/断开 | 回到决策链 | 评估充电或待机 |
类驱动与复合设备(预期,待验证)
若玩具同时提供「U 盘 + 声卡」或「CDC + MSC」能力,SDK 通常以复合设备(Composite Device) 方式实现,即一个配置下有多个接口描述符,每个接口对应一个类驱动。这会带来额外的电源影响:
- 复合设备枚举时间更长,插入到就绪的窗口内必须保持运行;
- 多个类驱动共享端点资源,断开时需要统一释放;
- 低电量时应避免启动需要大电流/高带宽的类(如声卡连续播放),需要电源模块与 USB 模块协同降级。
⚠️ 以上流程与生命周期映射为基于 USB 标准与 JieLi AD 系列 SDK 通用结构的预期描述,具体实现(协议栈文件、类驱动注册方式、BCS 检测实现)需在仓库中搜索
usb、device、class、audio、msc、cdc等关键字核对。
配置选项
⚠️ 本次会话未能读取到实际配置文件(如
app_config.h、board_config、usb_config等),下表为预期选项类别,用于指导在仓库中检索真实配置项(搜索sleep、wakeup、charge、battery、usb、vbus等关键字)。默认值一律以实际代码为准。
| 预期选项 | 类型 | 默认值(未验证) | 作用 |
|---|---|---|---|
| 空闲超时进入待机 | int(ms) | 视产品而定 | 业务空闲多久后请求待机 |
| 休眠等级/深度 | enum | 视产品而定 | 浅休眠(充电)/深休眠(纯电池) |
| 唤醒源使能掩码 | bitmask | 按键+充电+USB | 允许哪些事件唤醒设备 |
| 充电检测阈值 | int(mV/ADC) | 视硬件而定 | VBUS 有效判定与充满判定 |
| USB 类驱动使能 | bool/bitmask | 视产品而定 | 声卡/MSC/CDC 是否编译启用 |
| 低电量功能限制 | bool | 视产品而定 | 电量不足时是否禁用部分功能 |
失败模式、边界与并发
以下问题在「待机 + 充电 + USB 从机」共存的系统中普遍存在(基于能力域推断,待源码验证):
- 事件竞态:USB 插入事件同时触发「充电检测」与「枚举启动」,若两条路径并发执行(中断 vs 任务),可能出现充电态已进入休眠而枚举尚未完成。预期设计应保证:进入休眠前必须关闭/挂起 USB 从机,枚举期间禁止深休眠。
- 唤醒原因丢失:电平型唤醒源在电源恢复后可能不再保持有效状态,若恢复代码延迟读取原因,将无法判断为何醒来。预期应尽早锁存唤醒原因。
- 枚举中断导致挂死:枚举期间若主机中途断开或供电不稳,状态机必须能超时回退到电源决策链,否则设备可能长期停留在「运行态」而白白耗电。
- 充电与数据误判:仅靠 VBUS 无法区分「充电器」与「PC 数据线」,误判会导致:把充电器当数据连接(白耗电)或把 PC 当充电器(无法升级/通信)。预期依赖 BCS/DP-DM 检测。
- 低电量边界的抖动:电池电压在负载变化时波动,若电量阈值无迟滞(hysteresis),会在阈值附近反复触发功能限制/恢复,造成闪烁。预期设计应引入迟滞窗口。
- 并发访问:电源状态与 USB 状态是共享变量,中断(硬件事件)与任务(业务逻辑)并发读写时需临界区保护;否则可能出现休眠决策读到过期的 USB 状态。
性能与运维考虑
- 休眠唤醒延迟:深休眠唤醒需要重新锁相环/恢复时钟,业务层应预估唤醒延迟,避免在需要低延迟响应的场景(如连续按键)使用深休眠。
- 充电时功耗预算:若「仅充电」也维持协议栈运行,充电电流的一部分会被设备自身消耗,需在充电速度与功能可用性之间权衡。
- 调试建议:电源与 USB 问题通常需要结合硬件测量(VBUS 波形、电流曲线)与软件日志;若 SDK 提供 CDC 日志通道,注意调试口本身也会消耗电量,量产固件应关闭。
- 日志关键字:阅读实现时可检索
standby、sleep、wakeup、charge、vbus、usb_device、usb_slave、enum等,快速定位电源与 USB 模块入口。
扩展点
基于能力边界,该子系统预期提供以下扩展途径(待验证):
- 新增唤醒源:在唤醒源管理中添加新的 GPIO/外设事件,并在唤醒原因枚举中登记;
- 新增 USB 类驱动:在从机协议栈的类驱动注册表中加入新的接口描述符与处理回调(如新增 HID 类);
- 自定义电源策略:业务层通过电源事件回调订阅插入/拔出/充满事件,实现产品定制的功能降级(如低电量关闭声卡播放);
- 充电算法替换:若充电检测与充电控制分离,可替换 ADC 采样/判定逻辑而不影响 USB 枚举路径。
测试
本次会话未能读取到测试文件;以下为针对该能力域应覆盖的测试方向(供后续在仓库中核对
test、usb_test、power_test等目录时使用)。
- 待机往返测试:进入待机 → 各唤醒源逐个唤醒 → 验证唤醒原因与状态恢复;
- USB 枚举测试:连接 PC/分析仪,验证复位、地址分配、配置选择、类驱动就绪全流程;
- 充电/数据仲裁测试:分别接充电器与 PC,验证进入「充电模式」还是「数据模式」;
- 边界测试:低电量时插入/拔出 USB、枚举中途断线、唤醒事件风暴;
- 功耗测试:测量待机电流、充电态电流、数据连接态电流,验证符合产品功耗目标。
Related Links
- README.md(仓库入口与 SDK 说明)
- README-en.md(英文版说明)
- 目录路径(应用代码预期位置):
applications/voice-toy/power-usb—— 工具在本会话未检索到该目录文件,请在可访问的源码树中核对 - 相关兄弟页面(若存在):语音玩具应用的其他能力页(如语音播放、按键交互)应作为本页的相邻主题单独成页
本页基于「能力边界 + 预期架构」撰写。所有标注「待验证」的实现细节均需在可访问仓库源码后更新为真实类名、函数与配置项。