杰理 SDK 文档中心
首页
首页
  • 项目概览

    • AD16N 系列芯片与 SDK 能力总览
  • 快速开始

    • 环境搭建与编译工具链
    • 编译构建指南
    • 烧录与固件升级
  • SDK 工程架构

    • SDK 目录结构与模块分层
    • 构建系统与批处理工具
    • BSP 板级支持包
  • mbox_flash 小音箱应用

    • 应用初始化与启动流程
    • 应用配置系统
    • 按键、UI 与用户交互
  • 音频子系统

    • 音频解码框架与调度
    • 音频格式解码器实现
    • MIDI 合成与播放
    • 音频编码与录音
    • EQ/DRC 与音效处理
    • DAC/ADC 音频接口与采样
  • 存储与文件系统

    • 媒体 IO 抽象层 MIO
    • 存储设备驱动
    • 文件系统支持
  • 平台系统库

    • 系统基础服务
    • CPU 平台与运行库
    • 固件升级与更新机制
    • 蓝牙与扩展连接接口
  • 电源与低功耗管理

    • 电源管理与低功耗设计
    • 锂电池充电管理
  • 硬件与文档参考

    • SDK 文档中心与版本发布记录
    • 芯片数据手册与硬件设计参考

电源管理与低功耗设计

本文档介绍 AD16N 平台(fw-AD16N_GP-MCU_SDK)的电源管理与低功耗设计,涵盖应用层电源管理模块 app_power_mg 的电压监测、低电告警、自动关机机制,以及 CPU 层电源抽象接口 power_interface 的组成与设计意图。

Purpose and Scope

本页面聚焦 AD16N SDK 中与电源管理、低功耗相关的完整链路:

  • 应用层电源管理:app_power_mg.c / app_power_mg.h 实现的 VBAT 电压采样、LVD(低电压检测)警戒线、低电计数滤波、自动关机消息上报;
  • CPU 层电源抽象:power_interface.h 聚合的 P33 寄存器、GPIO 电源端口、电源 API、唤醒与复位模块的接口划分;
  • 配置与扩展:app_config.h 中的 TCFG_CHARGE_ENABLE、TCFG_SHUTDOWN_TIME 等配置项如何影响电源行为。

以下内容不在本页范围,属于同仓库其他能力页的主题,仅在必要时交叉引用:充电管理(charge.h / charge_get_lvcmp_det())的完整充电算法、ADC 驱动(adc_api.h)的采样实现细节、按键与消息系统(msg.h)的通用机制。

Overview

在电池供电的 MCU 产品(如 TWS 耳机、便携音箱、遥控器)中,电源管理决定了产品的续航、安全性与用户体验。AD16N 的电源管理采用分层设计:

  1. 硬件层:PMU(电源管理单元)内部集成 LVD 比较器与 VBAT 采样通道,通过 P33 寄存器控制;
  2. CPU 层:power_api / power_port / power_wakeup / power_reset 等模块封装寄存器读写、GPIO 电源控制、唤醒源配置与复位逻辑;
  3. 应用层:app_power_mg 周期性读取 VBAT 电压,与 LVD 警戒线比较,经过连续计数滤波后触发低电告警与关机消息,避免误关机。

低功耗设计的关键意图(WHY):

  • 使用 LVD 作为警戒线而非固定值:LVD 电压随芯片批次、温度存在差异,lvd_warning_voltage = lvd_voltage + 300 在 LVD 阈值基础上加 300mV 裕量,保证在真正触发 LVD 复位之前应用已有足够时间保存状态并关机;
  • 充电期间禁止低电关机:充电时 VBAT 会被充电器拉高/波动,直接判断电压会导致误关机,因此通过 CHARGE_IN_DET 检测充电插入状态并跳过低电判断;
  • 连续计数防抖:电压短暂跌落(如射频发射瞬间的电流尖峰)不应触发关机,app_power_scan 使用 low_power_cnt 连续计数,只有持续低电达到 TCFG_SHUTDOWN_TIME 才上报 MSG_POWER_OFF。

Architecture

flowchart TD
    subgraph sg_App["应用层 (App BSP Common)"]
        AppPowerMg["app_power_mg.c<br/>电压扫描/低电关机"]
        AppConfig["app_config.h<br/>TCFG_SHUTDOWN_TIME / TCFG_CHARGE_ENABLE"]
        Msg["msg.h<br/>post_msg(MSG_POWER_OFF)"]
    end

    subgraph sg_Cpu["CPU 层抽象 (power_interface.h)"]
        PowerApi["asm/power/power_api.h<br/>电源/低功耗 API"]
        PowerPort["asm/power/power_port.h<br/>GPIO 电源端口"]
        PowerWakeup["asm/power/power_wakeup.h<br/>唤醒源"]
        PowerReset["asm/power/power_reset.h<br/>复位"]
        P33["asm/power/p33.h<br/>PMU 寄存器"]
    end

    subgraph sg_Hw["硬件层"]
        PMU["PMU / LVD / VBAT 采样通道"]
        Charge["charge.h<br/>充电检测 lvcmp"]
        ADC["adc_api.h<br/>AD_CH_PMU_VBAT"]
    end

    AppPowerMg -->|"读电压"| ADC
    AppPowerMg -->|"充电检测"| Charge
    AppPowerMg -->|"读配置"| AppConfig
    AppPowerMg -->|"低电持续超时"| Msg
    AppPowerMg -->|"调用"| PowerApi
    PowerApi --> P33
    PowerPort --> P33
    PowerWakeup --> P33
    PowerReset --> P33
    P33 --> PMU

架构说明:

  • app_power_mg.c 是应用层唯一的电源管理入口,通过 power_interface.h 间接使用 CPU 层能力,与应用业务(消息、按键)解耦——它只负责"测电压 → 判低电 → 发消息",不直接操作寄存器;
  • power_interface.h 是 CPU 层对外唯一头文件(接口门面),内部按职责聚合 p33.h(寄存器定义)、power_port.h(GPIO 电源控制)、power_api.h(电源/低功耗 API)、power_wakeup.h(唤醒)、power_reset.h(复位)。这种聚合设计使应用层只需包含一个头文件即可获得全部电源能力,同时保持各子模块可独立演进;
  • 硬件层(PMU、ADC、充电检测)通过 adc_api.h 与 charge.h 暴露给应用层,应用层不感知具体寄存器地址。

Source: app_power_mg.c、power_interface.h

应用层电源管理实现解析

应用层电源管理全部实现在 sdk/apps/app/bsp/common/power_manage/ 目录下,仅两个文件:app_power_mg.c(实现)与 app_power_mg.h(对外声明与低电阈值宏)。

模块初始化 app_power_init()

void app_power_init(void)
{
    low_power_warning_init();
    adc_add_sample_ch(AD_CH_PMU_VBAT);
    app_power_scan();
}

Source: app_power_mg.c

初始化做三件事,顺序有明确意图:

  1. low_power_warning_init():先建立低电警戒线。在 LVD_WARNING_FOR_LOW_POWER == 1 时该宏展开为 lvd_warning_init(),它读取 PMU 的 LVD 阈值并加上 300mV 裕量:

    static void lvd_warning_init(void)
    {
        extern u32 get_lvd_vol(void);
        u32 lvd_voltage = get_lvd_vol();
        lvd_warning_voltage = lvd_voltage + 300;
        log_info("lvd_warning_voltage : %d\n", lvd_warning_voltage);
    }
    

    Source: app_power_mg.c

    LVD(Low Voltage Detector)是硬件比较器,当 VBAT 跌到 LVD 阈值时芯片会触发复位。软件警戒线比硬件阈值高 300mV,就是为了在硬件复位前给应用留出关机窗口——这是"软件先于硬件动作"的低功耗设计核心思想。若不希望依赖 LVD(例如硬件未校准),可在 app_power_mg.h 中把 LVD_WARNING_FOR_LOW_POWER 改为 0,此时警戒线退化为固定值 3300(3.3V),low_power_warning_init 展开为空操作。

  2. adc_add_sample_ch(AD_CH_PMU_VBAT):向 ADC 驱动注册 VBAT 采样通道。AD_CH_PMU_VBAT 是 PMU 内置的电池电压采样通道,采样结果由 ADC 驱动周期性刷新,app_power_scan 每次直接读最新值,不阻塞等待。

  3. app_power_scan():立即执行一次扫描,使 vbat_voltage 全局变量在模块初始化完成时就有有效初值,避免上层首次读取拿到 0。

周期扫描 app_power_scan() —— 低电检测与防抖

void app_power_scan(void)
{
    static u16 low_power_cnt = 0;
    u16 vol = adc_get_voltage(AD_CH_PMU_VBAT) * 4;
    if (0 == vol) {
        return;
    }

    /* log_info("vbat voltage : %d", vol); */
    if ((vol <= LOW_POWER_VOL) && (0 == CHARGE_IN_DET)) {
        //充电时不进入低功耗
        low_power_cnt++;
        if (low_power_cnt == (TCFG_SHUTDOWN_TIME / 500)) {
            log_error(LOW_POWER_LOG);
            post_msg(1, MSG_POWER_OFF);
        }
    } else {
        low_power_cnt = 0;
    }

    vbat_voltage = vol;
}

Source: app_power_mg.c

逐行分析:

  • vol = adc_get_voltage(AD_CH_PMU_VBAT) * 4:ADC 采样值需乘以 4 得到毫伏(mV)单位的真实电压。vol == 0 时直接返回,防止 ADC 尚未就绪(返回 0)时误判为"0V 超低电"而累积计数;
  • 低电条件 (vol <= LOW_POWER_VOL) && (0 == CHARGE_IN_DET):
    • LOW_POWER_VOL 在默认配置下即 lvd_warning_voltage(LVD + 300mV);
    • CHARGE_IN_DET 在 TCFG_CHARGE_ENABLE == 1 时是 charge_get_lvcmp_det()(充电器插入检测),充电时强制跳过低电判断。这是因为充电过程中电池电压会被充电器抬高/波动,若按空载电压判断会误关机;
  • 连续计数滤波:低电时 low_power_cnt++,非低电时清零。只有连续低电计数达到 TCFG_SHUTDOWN_TIME / 500 才触发动作。该公式隐含 app_power_scan 的调用周期为 500ms:TCFG_SHUTDOWN_TIME 以毫秒为单位配置"持续低电多久后关机",除以 500 得到需要连续低电的扫描次数。例如默认关机延时 3 秒时,需要连续 6 次(3 秒)扫描均判定低电;
  • 动作:post_msg(1, MSG_POWER_OFF):通过消息系统上报关机消息(1 为消息优先级),由应用主循环统一处理关机流程。电源模块本身不执行关机,只负责"汇报"——这种事件驱动设计使关机动作(保存参数、关蓝牙、关外设)可以复用应用已有的消息处理链路;
  • vbat_voltage = vol:无论是否低电,每次都刷新全局电压值,供 app_power_get_vbat() 查询。

电压读取 app_power_get_vbat()

u16 app_power_get_vbat(void)
{
    return vbat_voltage;
}

Source: app_power_mg.c

该接口返回最近一次扫描缓存的 VBAT 电压(mV),供 UI 显示电量、电量分级等业务使用。由于电压由周期扫描刷新,业务侧读取是 O(1) 且无阻塞的,不会引入额外 ADC 占用。

低电阈值宏定义

#define LVD_WARNING_FOR_LOW_POWER   1//1:LVD作为低电警戒线 0:固定值作为警戒线

#if LVD_WARNING_FOR_LOW_POWER
#define LOW_POWER_VOL               lvd_warning_voltage
#define LOW_POWER_LOG               "Waring!!! Vbat is near to lvd!\n"
#define low_power_warning_init      lvd_warning_init
#else
#define LOW_POWER_VOL               3300//3.3V
#define LOW_POWER_LOG               "low power\n"
#define low_power_warning_init
#endif

//TODO by bt
#define LOW_POWER_WARN_VAL          240
#define LOW_POWER_OFF_VAL           220

Source: app_power_mg.h

设计要点:

  • 用编译期宏开关切换两种警戒线策略,避免运行期分支开销:默认走 LVD 动态警戒线(更精确、自适应批次差异),固定值 3300mV 作为后备方案;
  • LOW_POWER_WARN_VAL(240)与 LOW_POWER_OFF_VAL(220)标注 TODO by bt,从命名看是电量百分比级别的"低电提醒/强制关机"分级阈值,当前版本未在 app_power_scan 中使用,属于预留扩展点;
  • LOW_POWER_LOG 区分两种策略下的告警日志文案,便于从日志直接判断当前生效的是哪种警戒线策略。

核心流程:从电压采样到自动关机

app_power_scan 由应用主循环周期调用(典型周期 500ms),整个低电关机链路如下:

sequenceDiagram
    participant App as 应用主循环
    participant Mg as app_power_scan
    participant ADC as adc_api
    participant PMU as PMU/LVD
    participant Chg as charge (lvcmp)
    participant Msg as 消息系统

    App->>Mg: 周期调用 (500ms)
    Mg->>ADC: adc_get_voltage(AD_CH_PMU_VBAT)
    ADC-->>Mg: 采样值
    Mg->>Mg: vol = 采样值 * 4 (mV)
    alt vol == 0
        Mg-->>App: return (ADC未就绪)
    else vol <= LOW_POWER_VOL
        Mg->>Chg: charge_get_lvcmp_det()
        alt 充电中
            Mg->>Mg: low_power_cnt = 0
        else 未充电
            Mg->>Mg: low_power_cnt++
            alt low_power_cnt == TCFG_SHUTDOWN_TIME / 500
                Mg->>Msg: log_error + post_msg(1, MSG_POWER_OFF)
                Msg-->>App: 应用处理关机流程
            end
        end
    else 电压正常
        Mg->>Mg: low_power_cnt = 0
    end
    Mg->>Mg: vbat_voltage = vol

流程关键点:

  1. 每次扫描先读 ADC 再判断,vol == 0 直接短路返回,这是对 ADC 采样未就绪的防御;
  2. 低电判断是两重条件:电压低于警戒线 且 未插入充电器,二者缺一不可;
  3. 关机触发是持续条件而非瞬时条件:low_power_cnt 连续计数到 TCFG_SHUTDOWN_TIME / 500 才 post_msg(1, MSG_POWER_OFF),任何一次电压恢复都会清零计数——这是典型的软件防抖(debounce)设计,用于滤除射频脉冲、电机启停等造成的瞬时电压跌落;
  4. 电源模块只发消息不执行关机,实际关机动作由应用在消息处理中完成,保证与业务状态(如蓝牙连接、参数保存)安全协同。

Usage Examples

示例 1:初始化电源管理模块

在应用初始化阶段调用一次,注册 VBAT 采样通道并建立 LVD 警戒线:

void app_power_init(void)
{
    low_power_warning_init();
    adc_add_sample_ch(AD_CH_PMU_VBAT);
    app_power_scan();
}

Source: app_power_mg.c

示例 2:在周期任务中扫描电压

将 app_power_scan 挂到 500ms 周期任务(如定时器/主循环),低电检测与 vbat_voltage 缓存都会随之更新:

void app_power_scan(void)
{
    static u16 low_power_cnt = 0;
    u16 vol = adc_get_voltage(AD_CH_PMU_VBAT) * 4;
    if (0 == vol) {
        return;
    }
    if ((vol <= LOW_POWER_VOL) && (0 == CHARGE_IN_DET)) {
        //充电时不进入低功耗
        low_power_cnt++;
        if (low_power_cnt == (TCFG_SHUTDOWN_TIME / 500)) {
            log_error(LOW_POWER_LOG);
            post_msg(1, MSG_POWER_OFF);
        }
    } else {
        low_power_cnt = 0;
    }
    vbat_voltage = vol;
}

Source: app_power_mg.c

示例 3:读取当前电池电压(用于电量显示)

UI 或电量分级逻辑可直接读取缓存的 VBAT 电压,无需再次触发 ADC 采样:

u16 app_power_get_vbat(void)
{
    return vbat_voltage;
}

Source: app_power_mg.c

示例 4:切换低电警戒线策略

在 app_power_mg.h 中修改编译期开关,可将警戒线从"LVD 动态值"切换为"固定 3.3V":

#define LVD_WARNING_FOR_LOW_POWER   1//1:LVD作为低电警戒线 0:固定值作为警戒线

#if LVD_WARNING_FOR_LOW_POWER
#define LOW_POWER_VOL               lvd_warning_voltage
#define LOW_POWER_LOG               "Waring!!! Vbat is near to lvd!\n"
#define low_power_warning_init      lvd_warning_init
#else
#define LOW_POWER_VOL               3300//3.3V
#define LOW_POWER_LOG               "low power\n"
#define low_power_warning_init
#endif

Source: app_power_mg.h

Configuration Options

应用层电源管理的可配置项如下,其中 TCFG_* 宏定义于 app_config.h,LVD_WARNING_FOR_LOW_POWER 定义于 app_power_mg.h:

配置项类型默认值说明
LVD_WARNING_FOR_LOW_POWER宏开关11:以 LVD 动态电压 + 300mV 作为低电警戒线;0:以固定值 3300mV 作为警戒线
LOW_POWER_VOL宏lvd_warning_voltage / 3300低电判定阈值(mV),由 LVD_WARNING_FOR_LOW_POWER 决定展开值
LOW_POWER_LOG宏"Waring!!! Vbat is near to lvd!\n"触发低电关机时打印的告警日志
low_power_warning_init宏lvd_warning_init(或空)警戒线初始化函数,固定值策略下为空操作
LOW_POWER_WARN_VAL宏240预留的低电提醒阈值(TODO by bt,当前未使用)
LOW_POWER_OFF_VAL宏220预留的强制关机阈值(TODO by bt,当前未使用)
TCFG_SHUTDOWN_TIME宏(ms)由 app_config.h 定义持续低电多长时间(毫秒)后触发 MSG_POWER_OFF;app_power_scan 以 500ms 为周期,将其除以 500 得到连续低电计数目标
TCFG_CHARGE_ENABLE宏开关由 app_config.h 定义1 时启用充电检测(CHARGE_IN_DET = charge_get_lvcmp_det()),充电中禁止低电关机;0 时 CHARGE_IN_DET 恒为 0

配置联动关系:TCFG_SHUTDOWN_TIME 必须与 app_power_scan 的实际调用周期匹配。若扫描周期不是 500ms,TCFG_SHUTDOWN_TIME / 500 的换算将失真,需要在移植时同步调整。

API Reference

void app_power_init(void)

初始化电源管理模块:建立低电警戒线、注册 VBAT ADC 采样通道,并执行首次电压扫描。

  • 调用时机:应用初始化阶段,早于首次使用 app_power_get_vbat;
  • 副作用:向 ADC 驱动注册 AD_CH_PMU_VBAT 通道;写入全局 vbat_voltage。

Source: app_power_mg.c、app_power_mg.h

void app_power_scan(void)

周期扫描 VBAT 电压,执行低电判断与防抖计数,达到条件时 post_msg(1, MSG_POWER_OFF)。

  • 参数:无;
  • 返回:无;
  • 行为:更新全局 vbat_voltage(mV);低电且未充电时累加 low_power_cnt,连续计数达到 TCFG_SHUTDOWN_TIME / 500 后打印 LOW_POWER_LOG 并发送关机消息;电压恢复或充电中清零计数;
  • 边界:ADC 返回 0 时直接返回,不更新电压、不计数。

Source: app_power_mg.c、app_power_mg.h

u16 app_power_get_vbat(void)

返回最近一次扫描缓存的 VBAT 电压(mV)。

  • 参数:无;
  • 返回:vbat_voltage,单位 mV;app_power_init 之前或扫描尚未成功时可能为 0。

Source: app_power_mg.c、app_power_mg.h

内部函数与依赖接口

名称类型说明
lvd_warning_init()static读取 get_lvd_vol()(PMU LVD 阈值)并 +300mV 得到警戒线
get_lvd_vol()extern u32获取硬件 LVD 阈值,来自 CPU 层电源 API
adc_get_voltage(AD_CH_PMU_VBAT)ADC API读取 VBAT 采样值,需乘以 4 换算为 mV
charge_get_lvcmp_det()充电 API充电器插入检测(TCFG_CHARGE_ENABLE==1 时启用)
post_msg(1, MSG_POWER_OFF)消息 API上报关机消息,优先级 1

CPU 层电源抽象

CPU 层通过 power_interface.h 对外暴露统一电源接口,它本身不实现逻辑,而是聚合五个职责清晰的子模块:

//p33寄存器
#include "asm/power/p33.h"
//gpio相关
#include "asm/power/power_port.h"
//电源、低功耗
#include "asm/power/power_api.h"
//唤醒
#include "asm/power/power_wakeup.h"
//复位
#include "asm/power/power_reset.h"

Source: power_interface.h

各子模块职责划分:

  • p33.h:PMU(电源管理单元)P33 寄存器定义,是所有电源行为的硬件基础——LVD 配置、稳压器控制、VBAT 采样的使能都通过 P33 寄存器完成;
  • power_port.h:GPIO 电源端口控制,管理 VDDIO 等电源域 GPIO 的上下电,用于外设电源的精细控制(降低静态漏电);
  • power_api.h:电源与低功耗核心 API(如 get_lvd_vol、进入低功耗/关机等),是应用层与硬件交互的主要入口;
  • power_wakeup.h:唤醒源配置(GPIO 唤醒、定时器唤醒、充电插入唤醒等),定义系统从低功耗状态恢复的途径;
  • power_reset.h:复位管理(软复位、看门狗复位等)。

仓库中该抽象存在 uc03(sdk/apps/include_lib/cpu/uc03/asm/power/)与 bd49(sdk/apps/include_lib/cpu/bd49/asm/power/)两个 CPU 变体,以及 sdk/apps/app/bsp/cpu/uc03/ 下的 power_api.c、power_port.c 实现。本页不展开 CPU 层各 API 的具体寄存器操作——那属于芯片 BSP 层文档主题;此处仅说明接口边界:应用层代码只依赖 power_interface.h 聚合出的稳定接口,CPU 更换时电源管理逻辑无需改动。

Failure Modes, Edge Cases & Concurrency

电压读数异常(0 值)

ADC 通道尚未就绪或采样失败时 adc_get_voltage 可能返回 0,app_power_scan 在 vol == 0 时直接 return。这是刻意的防御:若把 0 当作真实电压参与判断,会立刻被判定为"极低电压"并可能误触发关机。代价是本次扫描不刷新 vbat_voltage,上层读取到的是上一次缓存值——对 UI 显示无影响,对低电判断只是顺延一个周期。

充电状态与低电判断的竞争

CHARGE_IN_DET(charge_get_lvcmp_det)在 TCFG_CHARGE_ENABLE 关闭时恒为 0,此时充电中也可能触发低电关机。因此启用充电功能的产品必须开启 TCFG_CHARGE_ENABLE,否则会出现"插着充电器却因电压波动关机"的异常。另一个边界是充电器刚插入、lvcmp 尚未稳定时的短暂窗口——由于低电判断要求连续 TCFG_SHUTDOWN_TIME / 500 次低电,单次误判会被后续清零计数抵消,防抖机制天然覆盖该窗口。

电压抖动与防抖计数

射频发射、电机启动等瞬态负载会造成 VBAT 数十至数百毫伏的跌落。若警戒线设置过近(裕量不足 300mV),低电计数可能累积;但只要有一次扫描电压高于警戒线,low_power_cnt 即清零,因此误关机概率与扫描周期 × 低电持续时间成正比。调大 TCFG_SHUTDOWN_TIME 可增强抗抖动,但会延长真实低电下的关机响应时间,需要按产品场景权衡。

并发与可重入性

app_power_scan 使用 static u16 low_power_cnt 与 static u16 vbat_voltage,无锁、非可重入。它由单一周期任务(主循环/定时器)串行调用,模块内部不创建线程。若在中断上下文调用 app_power_scan,与主循环调用之间会存在对 vbat_voltage / low_power_cnt 的竞争,应在设计上保证只有一个调用者。post_msg 本身是线程安全的消息投递接口,故从扫描中发消息无竞态问题。

关机消息的异步性

app_power_scan 只投递 MSG_POWER_OFF 就返回,不等待关机完成。若应用在消息处理中执行耗时的参数保存、蓝牙断开等操作,期间系统仍可能因电压继续下降触发硬件 LVD 复位。设计上应让消息处理路径尽量短,或利用 LVD 的 300mV 裕量窗口完成收尾。

Performance & Operational Considerations

  • ADC 开销:AD_CH_PMU_VBAT 由 ADC 驱动后台采样,app_power_scan 每次只做一次寄存器读与乘法/比较,CPU 开销可忽略;以 500ms 周期扫描,功耗占比极低,适合常驻运行;
  • 日志行为:低电关机时打印 log_error(LOW_POWER_LOG),正常运行时 adc_get_voltage 附近的 log_info 被注释掉,避免高频日志占用串口与 Flash,调试时可临时打开;
  • 观测手段:开机日志中的 lvd_warning_voltage : xxx(mV)可用于确认警戒线是否符合硬件 LVD 实际值;若 LOW_POWER_LOG 出现即代表系统已进入关机流程;
  • 集成约束:TCFG_SHUTDOWN_TIME / 500 的换算假设扫描周期固定为 500ms,移植到其他周期调度时需同步修改,否则关机延时将偏离配置值。

Extension Points

  1. 警戒线策略切换:通过 app_power_mg.h 的 LVD_WARNING_FOR_LOW_POWER 宏,可在 LVD 动态警戒线与固定 3.3V 警戒线之间切换,适配不同硬件校准方案;
  2. 预留阈值 LOW_POWER_WARN_VAL / LOW_POWER_OFF_VAL:标注 TODO by bt 的两级阈值(240/220,疑似电量百分比),可用于实现"先提醒、后关机"的两级低电策略,当前版本未接入,是官方预留的扩展点;
  3. 充电检测注入:CHARGE_IN_DET 的宏抽象使充电状态来源可替换(charge_get_lvcmp_det 或其他 GPIO 检测),不修改扫描逻辑即可适配不同充电方案;
  4. 关机动作自定义:模块只发 MSG_POWER_OFF,关机前需要保存的状态、需要关闭的外设均可在应用的消息处理器中扩展,无需改动电源模块。

Tests

仓库内 app_power_mg 为轻量应用层模块,未发现独立的单元测试文件。其行为可通过以下方式验证:

  • 静态验证:检查 lvd_warning_voltage 日志是否等于 get_lvd_vol() + 300;
  • 动态验证:用可调电源模拟 VBAT,从正常工作电压缓慢下降,确认:①低于警戒线但未到 TCFG_SHUTDOWN_TIME 时回升电压不会关机(防抖生效);②持续低电达到配置时间后打印 LOW_POWER_LOG 并收到 MSG_POWER_OFF;③插入充电器后即使电压低于警戒线也不关机;
  • 回归关注点:vol == 0 分支、low_power_cnt 清零路径、vbat_voltage 缓存更新。

Related Links

  • app_power_mg.c — 应用层电源管理实现
  • app_power_mg.h — 低电阈值宏与对外声明
  • power_interface.h (uc03) — CPU 层电源接口聚合
  • power_api.c (uc03) — CPU 层电源 API 实现(BSP 层主题)
  • power_port.c (uc03) — GPIO 电源端口实现(BSP 层主题)
  • 相关能力页:充电管理(charge.h / TCFG_CHARGE_ENABLE)、ADC 采样(adc_api.h / AD_CH_PMU_VBAT)、消息系统(msg.h / MSG_POWER_OFF)
Next
锂电池充电管理