WS53指导资料

- hardware
  - SoC Wi-Fi、BLE和SLE Combo芯片 硬件用户指南
    - 前言
    - 封装与管脚
    - 电性能参数
    - 原理图设计建议
    - PCB设计建议
    - 热设计建议
    - 焊接工艺
    - 潮敏参数
    - 接口时序
    - 注意事项
    - 缩略语
  - 单板硬件关键器件选型指导
    - 前言
    - 关键器件选型约束
  - 射频测试 用户指南
    - 前言
    - 测试指令
    - 注意事项
- 软件资料
  - AT命令 使用指南
    - 前言
    - 指令说明
    - Wi-Fi模块AT指令
    - BLE&SLE模块AT指令
    - PLAT模块AT指令
  - BLE BQB认证测试 指导书
    - 前言
    - 蓝牙BQB认证简介
    - BQB协议认证
    - BQB 射频认证
    - WS53特性支持情况
    - 常见问题&测试命令汇总(FAQ)
  - BOOT API开发参考
    - 前言
    - 接口介绍
  - Boot移植应用 开发指南
    - 前言
    - Boot简介
    - RomBoot功能说明
    - LoaderBoot功能说明
    - FlashBoot说明
  - CJSON 开发指南
    - 前言
    - API接口说明
    - 开发指南
  - CoAP 开发指南
    - 前言
    - API接口说明
    - 开发指南
  - EFUSE 使用指南
    - 前言
    - 概述
    - 软件编程接口使用指导
    - Burntool烧写efuse_cfg.bin说明
  - FOTA 开发指南
    - 前言
    - 概述
    - 升级包制作
    - 升级包传输
    - 升级包保存
    - 升级包本地升级
    - AB面升级
    - FAQ
  - HTTP 开发指南
    - 前言
    - 开发指南
  - MQTT 开发指南
    - 前言
    - API接口描述
    - 开发指南
    - 注意事项
  - NV存储 用户指南
    - 前言
    - NV简介
    - NV编译预置
    - NV API指南
    - NV项汇总
  - SAMPLE用例 用户指南
    - 前言
    - SAMPLE简介
    - 外设SAMPLE用例
  - SDK 开发指南
    - 前言
    - 概述
    - 系统接口
  - SDK开发环境搭建 用户指南
    - 前言
    - 开发环境搭建
    - 编译
    - 新建APP
  - Syschannel 使用指南
    - 前言
    - Syschannel 简介
    - Syschannel 使用指南
    - Syschannel 编译指导
    - Syschannel 适配常见问题
  - TLS&DTLS 开发指南
    - 前言
    - API接口说明
    - 开发指南
    - 硬件适配
    - 注意事项
  - WFA认证测试指导书
    - 前言
    - WLAN WFA协议认证介绍
    - WS53 WFA认证
    - 缩略语
  - lwIP 开发指南
    - 前言
    - 概述
    - 功能特性
    - 开发指引
    - 网络安全
    - 常见问题
    - 术语
  - 产测FAQ
    - 前言
    - FAQ
    - 注意事项
    - 版本问题记录
  - 产线工装 用户指南
    - 前言
    - 测试软件准备
    - 单板测试方案
    - TX/RX测试参考
    - WLAN Facility与固件版本
    - 产线生产ESD防护要求
  - 低功耗 开发指南
    - 前言
    - 概述
    - 超深睡模式
    - 深睡模式
    - 浅睡模式
    - 常见问题
  - 单板冒烟 测试指南
    - 前言
    - 概述
    - 单板冒烟测试
  - 安全模块 使用指南
    - 前言
    - 概述
    - 错误码
    - 网络安全注意事项
  - 文件系统 使用指南
    - 前言
    - LFS简介
    - LFS编译预置
    - LFS接口API
  - 星闪认证测试 指导书
    - 前言
    - 星闪认证简介
    - 星闪协议认证
    - 星闪射频认证
    - 星闪特性支持
    - 常见问题&测试命令汇总（FAQ）
  - 特性开发说明书
    - 前言
    - 混杂模式特性说明
    - 动态国家码特性说明
    - BLE配网特性说明
    - 安全启动特性说明
    - FLASH在线解密特性说明
  - 第三方软件 移植指南
    - 前言
    - 移植指引
    - 常见问题
  - 设备驱动 开发指南
    - 前言
    - Pinctrl
    - GPIO
    - UART
    - SPI
    - QSPI
    - I2C
    - ADC
    - DMA
    - PWM
    - WDT
    - Timer
    - Systick
    - TCXO
    - SFC
    - eFuse
    - REBOOT
    - I2S
  - 软件 开发指南
    - 前言
    - 概述
    - Wi-Fi 软件开发指南
    - BLE&SLE 软件开发指南
    - 注意事项
  - 运维手册
    - 前言
    - 系统/平台模块
    - Wi-Fi模块
  - 鸿蒙XTS认证 指导书
    - 前言
    - 概述
    - 准备工作
    - 编译openharmony静态库
    - XTS版本编译和执行

### 该页内容

- 前言
- 概述
  - 低功耗配置前提条件
  - 系统低功耗模式说明
- 超深睡模式
  - 概述
  - 接口说明
  - 应用示例
  - 注意事项
- 深睡模式
  - 概述
  - 接口说明
  - 应用示例
  - 注意事项
- 浅睡模式
  - 概述
  - 接口说明
  - 应用示例
- 常见问题
  - 不能进入休眠模式，可能是什么原因
  - 外设对应业务概率性收发报文异常
  - 进入超深睡模式后立即被唤醒
  - 功耗数据会比预期偏高
  - Wi-Fi子系统低功耗与系统低功耗的关系
  - 如何调整Wi-Fi链路保活Null Data帧的发送周期
  - 降低功耗的相关建议

# 前言

概述

本文档详细描述了WS53V100 的系统低功耗模式及应用开发指导，同时提供了常见问题的处理方法。

产品版本

与本文档对应的产品版本如下。

产品名称 | 产品版本
--- | ---
WS53 | V100

读者对象

本文档主要适用于以下工程师：

- 技术支持工程师

- 软件开发工程师

符号约定

在本文中可能出现下列标志，它们所代表的含义如下。

符号 | 说明
--- | ---
| 表示如不避免则将会导致死亡或严重伤害的具有高等级风险的危害。
| 表示如不避免则可能导致死亡或严重伤害的具有中等级风险的危害。
| 表示如不避免则可能导致轻微或中度伤害的具有低等级风险的危害。
| 用于传递设备或环境安全警示信息。如不避免则可能会导致设备损坏、数据丢失、设备性能降低或其它不可预知的结果。 “须知”不涉及人身伤害。
| 对正文中重点信息的补充说明。 “说明”不是安全警示信息，不涉及人身、设备及环境伤害信息。

修改记录

文档版本 | 发布日期 | 修改说明
--- | --- | ---
04 | 2025-05-28 | 更新“系统低功耗模式说明”小节内容。 更新“接口说明”小节内容。 更新“接口说明”小节内容。
03 | 2024-11-25 | 更新“系统低功耗模式说明”小节内容。 更新“超深睡模式”小节内容。 更新“接口说明”小节内容。 更新“接口说明”小节内容。
02 | 2024-09-13 | 更新“接口说明”、“应用示例”小节内容。 更新“接口说明”、“应用示例”小节内容。 更新“浅睡模式”小节内容。
01 | 2024-08-08 | 第一次正式版本发布。 更新“系统低功耗模式说明”小节内容。 更新“概述”、“接口说明”小节内容。 更新“概述”、“接口说明”小节内容。 更新“浅睡模式”小节内容。
00B02 | 2024-07-15 | 更新“概述”小节内容。 更新“概述”小节内容。 更新“概述”、“接口说明”、“应用示例”小节内容。 更新“概述”小节内容。
00B01 | 2024-05-11 | 第一次临时版本发布。

# 概述

- 低功耗配置前提条件

- 系统低功耗模式说明

## 低功耗配置前提条件

WS53芯片包含A核和C核两个核：C核负责Wi-Fi、蓝牙和星闪的底层数据收发；A核负责网络数据协议、外设驱动和应用处理。上电默认两个核均使能了深睡模式。芯片上电C核在无Wi-Fi、蓝牙数据处理时隙时进入深睡，C核在Wi-Fi、蓝牙数据需要A核协议层处理时，C核唤醒A核。A核只有执行Idle任务，并且idle空闲时间超过配置值（默认配置20ms），才会进入深睡。在A核和C核均处于深睡时，WS53芯片整体进入深睡。A核深睡模式下，可以被UART RX、GPIO中断、RTC中断（操作系统idle到期）和看门狗唤醒。UART RX唤醒之后，软件上会让系统等待至少1s才进入深睡。

系统IDLE任务优先级最低，只有其它业务任务挂起或者阻塞时，系统才能进入IDLE任务。IDLE任务的空闲时间受其它高优先级任务阻塞时间和定时器影响，所以业务需要设计好相关任务和定时器，防止系统无法进入IDLE任务或者IDLE空闲时间过短影响功耗。在IDLE任务会对睡眠条件进行管理：

如果业务希望执行IDLE任务时不进入睡眠模式，可以关闭低功耗入口或者可以通过投否决票实现。

> 说明： 注册给操作系统的低功耗入口函数：static void idle_task_process(void) 低功耗管理功能函数：void uapi_pm_enter_sleep(void)

低功耗入口函数：static void idle_task_process(void)

添加睡眠否决票：errcode_t uapi_pm_add_sleep_veto(pm_veto_id_t veto_id)

移除睡眠否决票：errcode_t uapi_pm_remove_sleep_veto(pm_veto_id_t veto_id)

如果只是希望从投票时间开始一段时间不能进入睡眠，也可以调用接口：

errcode_t uapi_pm_add_sleep_veto_with_timeout(pm_veto_id_t veto_id, uint32_t timeout_ms)

## 系统低功耗模式说明

WS53V100支持3种系统低功耗模式（如表1所示），用户可根据实际应用场景选用对应的低功耗策略（默认使用深睡模式）。

表 1 低功耗模式说明

模式 | 芯片状态 | 特点
--- | --- | ---
超深睡模式 | CPU下电，RAM下电，所有外设下电。 该模式仅支持配置GPIO唤醒源唤醒。 | 不支持Wi-Fi协议规定的节能模式。 唤醒后系统重新启动（类似上电重启）。 不保持Wi-Fi、蓝牙连接。 配置为输出模式的AGOIO输出电平可保持。
深睡模式 | CPU下电，RAM不下电，GPIO、RTC以外其他外设下电。 该模式仅支持GPIO/Wi-Fi/BLE/SLE/RTC/UART/看门狗唤醒。 | 支持Wi-Fi协议规定的节能模式。 支持BLE协议规定的节能模式。 支持SLE协议规定的节能模式。 保持AP连接（Station关联AP后）。 AGPIO可以保持输出电平，其他外设在休眠时不能正常工作。 与浅睡模式互斥，不能同时设置。
浅睡模式 | CPU不下电，RAM不下电，支持WiFi、蓝牙、星闪的低功耗，SOC外设均不关闭，不下电。 | 支持Wi-Fi协议规定的节能模式。 支持BLE协议规定的节能模式。 支持SLE协议规定的节能模式。 保持AP连接（Station关联AP后）。 依赖Wi-Fi子系统的低功耗，关闭Wi-Fi模块电路，包括RF。 依赖BLE、SLE子系统的低功耗，关闭BLE、SLE模块电路，包括RF。 支持所有外设正常工作。 与深睡模式互斥，不能同时设置。

# 超深睡模式

- 概述

- 接口说明

- 应用示例

- 注意事项

## 概述

超深睡模式下仅保留IO唤醒相关模块供电，AGPIO配置及其复用关系不丢失，所有IO管脚驱动能力和PULL UP/DOWN配置不丢失，其他模块均下电，内存信息不保留，外设配置恢复到初始状态，Wi-Fi、星闪、蓝牙连接均断开。超深睡模式由用户调用超深睡函数接口后直接进入超深睡模式，超深睡接口调用之后，在之前所有配置为输入中断模式的AGPIO都能触发系统从超深睡模式唤醒。

## 接口说明

表 1 超深睡模式接口说明

接口名称 | 描述
--- | ---
-uapi_pm_enter_udsleep | -进入超深睡。
pm_port_get_udsleep_wakeup_src | 超深睡唤醒以后查询唤醒管脚，如果有多个GPIO配置了中断模式，查询结果是本次唤醒的GPIO。

## 应用示例

超深睡模式一般用于按键唤醒、主从设备长时间待机唤醒等极低功耗要求的场景。

超深睡配置：

/* 设置管脚APGIO3为GPIO模式 */

uapi_pin_set_mode(S_AGPIO3, PIN_MODE_0);

/* 设置GPIO为输入模式 */

uapi_gpio_set_dir(S_AGPIO3,, GPIO_DIRECTION_INPUT);

/* 设置GPIO为下降沿中断唤醒模式 */

uapi_gpio_set_isr_mode(S_AGPIO3,, GPIO_INTERRUPT_FALLING_EDGE);

/* 进入超深睡模式 */

uapi_pm_enter_udsleep();

超深睡唤醒之后，系统重启，软件可以查询获取唤醒GPIO号：

int32_t pm_port_get_udsleep_wakeup_src(const uint8_t agpio_array[], uint8_t agpio_cnt, bool wakeup[])

agpio_array为查询的GPIO标号，wakeup将对唤醒的GPIO位置标记为TRUE.

## 注意事项

超深睡之前，只要有AGPIO配置了中断模式，如果该管脚被触发，都能把系统从超深睡唤醒。

# 深睡模式

- 概述

- 接口说明

- 应用示例

- 注意事项

## 概述

WS53在idle空闲任务系统判断没有即将执行的业务则可以进入深睡模式，默认使用该模式。该模式可以通过深睡唤醒源唤醒，深睡唤醒源包括GPIO、系统tick（RTC）等。系统休眠时间采用tickless机制，避免每个系统tick都被唤醒。

模组作为STA，设置深睡模式后，系统空闲时会自动进入休眠，默认休眠时间取决于系统空闲状态、所关联AP的DTIM及Beacon周期、BLE和SLE连接状态等。只有系统低功耗、业务（WiFi、星闪蓝牙）低功耗均打开的时候才能进入深睡模式。

> 说明： DTIM (Delivery Traffic Indication Message)：AP发送广播/组播数据包的频率。 BI(Beacon period)：AP beacon帧发送间隔。 用户无需特别配置，BLE/SLE默认开启深睡策略；在BLE/SLE业务空闲5ms及以上时间时，投票允许进入深睡，不择投票禁止深睡。

## 接口说明

> 说明：

> - 用户无需特别配置，软件默认开启深睡，通过uapi_pm_add_sleep_veto/uapi_pm_remove_sleep_veto实现否决投票和否决投票移除，采用一票否决机制，只要有一个模块禁止休眠，则系统不能进入系统低功耗模式。

> - 进入深睡前，如果已经开启了Wi-Fi/BLE/SLE业务，需要Wi-Fi/BLE/SLE模块全部进入浅睡，整系统才会进入深睡。即只有在uapi_lpc_set_type和uapi_wifi_set_pm_switch同时打开才能进入深睡。

> - 使能/去使能Wi-Fi协议低功耗，原接口wifi_sta_set_pm不建议使用，推荐使用新接口uapi_wifi_set_pm_switch

表 1 深睡模式接口说明

接口名称 | 描述
--- | ---
uapi_pm_add_sleep_veto | 用户投票使用，否决进入休眠状态。用户可通过增加pm_veto_id_t枚举实现否决投票，每个ID仅对应一个否决票。如果有业务投票反对进入深睡，系统将无法进入深睡模式。
uapi_pm_remove_sleep_veto | 用户投票使用，解除否决进入休眠状态。
uapi_pm_add_sleep_veto_with_timeout | 用户从投票时刻起延时进入低功耗，不需要对应解除函数，进入低功耗时判断超时时间
uapi_lpc_set_type | 设置系统睡眠模式，在Wi-Fi子系统低功耗使能的场景下设置深睡模式PM_DEEP_SLEEP支持外设和CPU可下电。
uapi_wifi_set_pm_switch | 打开/关闭Wi-FI子系统低功耗 参数说明如下： [1]enable 使能/去使能Wi-Fi协议低功耗 [2]sleep_time 配置睡眠时长，通常配置1s（DTIM10），enable配置去使能时，参数2无效
uapi_pm_register_dev_ops | 深睡定制接口回调注册，成员函数suspend做睡眠前处理，resume做唤醒之后的处理

> 说明： uapi_wifi_set_pm_switch不支持在中断上下文调用。

外设下电恢复：在低功耗处理流程中，由于外设模块在深睡过程中会掉电，深睡前软件对外设进行状态和配置保存，深睡唤醒以后软件在进行恢复操作。

表 2 外设下电和恢复说明

序号 | 驱动 | 深睡下电说明 | 唤醒恢复
--- | --- | --- | ---
1 | Pinctrl | AGPIO mode不下电，MGPIO mode下电：SDK调用uapi_pin_suspend保存状态. pull不下电、ds不下电。 | mode：SDK调用uapi_pin_resume恢复。
2 | GPIO | AGPIO不下电：睡眠时输出电平可保持，输入可以作为唤醒引脚。 MGPIO下电： 睡眠时输出电平不保持。SDK调用uapi_gpio_suspend保存配置，睡眠时芯片默认为输入，软件默认配置为输入下拉(业务可以调用pm_port_skip_pull_down去掉引脚在睡眠时做下拉)。MGPIO1\MGPIO6\MGPIO7\MGPIO11\MGPIO16可以作为输入唤醒GPIO | AGPIO：芯片和软件均不处理，建议客户在深睡状态如果不需要使用输出功能，可以配置为输入下拉，减少漏电，流程定制接口函数uapi_pm_register_dev_ops。 MGPIO: SDK调用uapi_gpio_resume恢复配置。
3 | UART | 下电，RX引脚如果使用AGPIO，可以作为UART RX输入唤醒。 | SDK调用uapi_uart_resume恢复。
4 | ADC | 下电。 | 上电不做恢复，每次读取采样结果时配置ADC。
5 | DMA | 下电。 | SDK调用uapi_dma_resume恢复。。
6 | WDT | 不下电。 | SDK恢复WDT NMI中断。。
7 | RTC | 不下电，睡眠前获取计数。 | 唤醒以后读取计数补充系统tick。
8 | SFC | 下电。 | SDK恢复。
9 | PWM | 下电，SDK调用uapi_pwm_suspend恢复配置 | SDK调用uapi_pwm_resume恢复，PWM不自动输出，用户调用uapi_pwm_start开始输出PWM波形。
10 | I2C | 下电，SDK调用uapi_i2c_suspend保存配置。 | SDK调用uap_i2c_resume恢复，用户调用接口进行数据传输。
11 | SPI | 下电，SDK调用uapi_spi_suspend保存配置。 | SDK调用uapi_spi_resume恢复配置，用户调用接口进行数据传输。
12 | RAM | 不下电。 | -

> 说明： 上述外设低功耗处理流程在文件pm_sleep_porting.c中处理。

## 应用示例

示例代码

用户可以配置GPIO为输入中断模式来唤醒系统，同时也可以使用接口uapi_pm_register_dev_ops定制在睡眠唤醒前后的业务处理。

GPIO唤醒的示例代码:

    static errcode_t lpc_gpio_sample_suspend(uintptr_t arg)
    {
    unused(arg);
    g_lpc_gpio_suspend++;
    return 0;
    }

    static errcode_t lpc_gpio_sample_reume(uintptr_t arg)
    {
    unused(arg);
    g_lpc_gpio_resume++;
    return 0;
    }

    static pm_dev_ops_t g_lpc_gpio_ops = {
    .suspend = lpc_gpio_sample_suspend,
    .resume = lpc_gpio_sample_reume,
    };

    static void lpc_gpio_wakeup_callback(pin_t pin, uintptr_t param)
    {
    unused(pin);
    unused(param);
    /* 用户投票反对A核休眠，保护业务代码，避免业务代码运行中，A核进入低功耗 */
    uapi_pm_add_sleep_veto(PM_USER0_VETO_ID);
    g_lpc_gpio_isr++;
    /* 用户同意A核休眠，如果所有子业务均同意休眠，A核进入低功耗 */
    uapi_pm_remove_sleep_veto(PM_USER0_VETO_ID);
    printf("lpc gpio test count isr:%u, suspend:%u, resume:%u\r\n",
    g_lpc_gpio_isr, g_lpc_gpio_suspend, g_lpc_gpio_resume);
    }

    static int lpc_gpio_task(void *data)
    {
    unused(data);
    /* 设置GPIO模式 */
    uapi_pin_set_mode(LPC_WAKEUP_GPIO, PIN_MODE_0);
    /* 注册进入低功耗supend和退出低功耗resume接口，可选 */
    uapi_pm_register_dev_ops(PM_DEV_USER1, &g_lpc_gpio_ops);

    /* 设置为输入模式 */
    uapi_gpio_set_dir(LPC_WAKEUP_GPIO, GPIO_DIRECTION_INPUT);
    /* 中断下降沿唤醒，不需要处理函数可以使用uapi_gpio_set_isr_mode */
    uapi_gpio_register_isr_func(LPC_WAKEUP_GPIO, GPIO_INTERRUPT_FALLING_EDGE, lpc_gpio_wakeup_callback);
    return 0;
    }

    深睡模式：
    static int deep_sleep_sample_task(void *data)
    {
    /* 注册深睡GPIO唤醒回调处理 */
    lpc_gpio_task(data)
    /* 设置深睡模式 */
    uapi_lpc_set_type(PM_DEEP_SLEEP); // 默认配置深睡，可以不设置
    /* 创建STA */
    wifi_sta_enable();
    /* 关闭Wi-Fi协议低功耗,避免连接后自动进入协议低功耗，后面需要主动打开Wi-Fi协议低功耗 */
    uapi_wifi_set_pm_switch(0, 0);
    /* 配置Wi-Fi连接测试热点 */
    /* Wi-Fi连接热点示例代码参见SDK路径：\application\samples\wifi\sta_sample\sta_sample.c */
    /* 使能Wi-Fi协议低功耗，配置睡眠时长1s（DTIM10） */
    uapi_wifi_set_pm_switch(1, 1000);

    return 0;
    }

## 注意事项

暂无

# 浅睡模式

- 概述

- 接口说明

- 应用示例

## 概述

实现原理与深睡模式类似，区别为CPU和外设不下电，通过业务子系统来降低功耗。实现上通过uapi_lpc_set_type设置模式PM_LIGHT_MODE进入浅睡，此时Wi-Fi/BLE/SLE子系统低仍然可以进入低功耗模式，CPU可以进入WFI状态来实现降低整体功耗。

## 接口说明

> 说明：

> 1. 浅睡模式，uapi_lpc_set_type设置PM_LIGHT_SLEEP或者PM_NO_SLEEP，打开uapi_wifi_set_pm_switch，即支持wifi协议低功耗，CPU和外设不会掉电。但是PM_LIGHT_SLEEP模式CPU可进入WFI降功耗。

> 2. Wi-Fi打开时，uapi_lpc_set_type不设置PM_DEEP_SLEEP或者uapi_wifi_set_pm_switch参数1设置为1无法进入深睡，只能进入浅睡。

> 3. Wi-Fi打开时，uapi_wifi_set_pm_switch参数1设0，则关闭wifi协议低功耗，uapi_lpc_set_type设置为PM_DEEP_SLEEP或者PM_LIGHT_SLEEP模式，CPU和外设都不会掉电，CPU空闲可以进入WFI。

> 4. 使能/去使能Wi-Fi协议低功耗，原接口wifi_sta_set_pm不建议使用，推荐使用新接口uapi_wifi_set_pm_switch。

> 5. uapi_wifi_sta_set_pm_param，仅调试使用，如无特殊需求，不建议配置。

表 1 浅睡模式接口说明

接口名称 | 描述
--- | ---
uapi_lpc_set_type | 参数设置PM_LIGHT_SLEEP: 系统支持WFI模式的浅睡模式。 参数设置PM_NO_SLEEP：系统关闭低功耗，Wi-Fi子系统低功耗独立控制。
uapi_wifi_set_pm_switch | 打开/关闭Wi-FI子系统低功耗 参数说明如下： [1]enable 使能/去使能Wi-Fi协议低功耗 [2]sleep_time 配置睡眠时长，通常配置1s（DTIM10），enable配置去使能时，参数2无效
uapi_wifi_sta_set_pm_param | 参数说明如下： [1]pm_timeout 低功耗定时器周期，默认20ms。 [2]pm_timer_cnt 低功耗定时器重启次数。 [3]bcn_timeout beacon接收超时时间。 [4]mcast_timeout 组播广播接收超时时间。 [5]sleep_time 预期休眠时间。

> 说明： uapi_wifi_set_pm_switch，uapi_wifi_sta_set_pm_param不支持在中断上下文调用。

## 应用示例

代码示例：

    浅睡模式：
    static int light_sleep_sample_task(void *data)
    {
    unused(data);
    /* 设置浅睡模式 */
    uapi_lpc_set_type(PM_LIGHT_SLEEP);
    /* 创建STA */
    wifi_sta_enable();
    /* 关闭Wi-Fi协议低功耗,避免连接后自动进入协议低功耗，后面需要主动打开Wi-Fi协议低功耗 */
    uapi_wifi_set_pm_switch(0, 0);
    /* 配置Wi-Fi连接测试热点 */
    /* Wi-Fi连接热点示例代码参见SDK路径：\application\samples\wifi\sta_sample\sta_sample.c */
    /* 使能Wi-Fi协议低功耗，配置睡眠时长1s（DTIM10） */
    uapi_wifi_set_pm_switch(1, 1000);
    return 0;
    }

    关闭低功耗，仅使能Wi-Fi协议低功耗：
    static int only_wifi_sleep_sample_task(void *data)
    {
    unused(data);
    /* 设置浅睡模式 */
    uapi_lpc_set_type(PM_NO_SLEEP);
    /* 创建STA */
    wifi_sta_enable();
    /* 关闭Wi-Fi协议低功耗,避免连接后自动进入协议低功耗，后面需要主动打开Wi-Fi协议低功耗 */
    uapi_wifi_set_pm_switch(0,0);
    /* 配置Wi-Fi连接测试热点 */
    /* Wi-Fi连接热点示例代码参见SDK路径：\application\samples\wifi\sta_sample\sta_sample.c */

    /* 使能Wi-Fi协议低功耗，配置睡眠时长1s（DTIM10） */
    uapi_wifi_set_pm_switch(1, 1000);
    return 0;
    }

# 常见问题

- 不能进入休眠模式，可能是什么原因

- 外设对应业务概率性收发报文异常

- 进入超深睡模式后立即被唤醒

- 功耗数据会比预期偏高

- Wi-Fi子系统低功耗与系统低功耗的关系

- 如何调整Wi-Fi链路保活Null Data帧的发送周期

- 降低功耗的相关建议

## 不能进入休眠模式，可能是什么原因

不能进入休眠模式原因比较多，常见以下几种原因：

- 定时器使用错误

  - 举例：启动10ms周期定时器。

  - 分析：系统在入睡前会检查是否有定时器即将到期，如果定时器即将到期，系统不允许进入系统低功耗模式。

  - 建议：根据实际业务启动定时器，在业务空闲时关闭对应定时器，特别是周期性定时器。

- 任务使用错误

  - 举例：任务体中循环操作，无主动释放动作，如调用阻塞接口接口。

  - 分析：某一任务无主动释放动作，则其他低优先级任务得不到执行，严重时会引起看门狗复位。系统在入睡前会检查是否有任务即将被调度，如果存在任务主动释放过少，则系统不允许进入系统低功耗模式。

  - 建议：业务设计上尽量调用阻塞接口，超时时间设置为无穷大或合理超时时间。

- uapi_pm_add_sleep_veto/uapi_pm_remove_sleep_veto使用错误

  - 举例：uapi_pm_add_sleep_veto/uapi_pm_remove_sleep_veto未成对使用。

  - 分析：系统在入睡前会检查“否决”休眠的状态，如有某个模块否决休眠，则一票即否决进入休眠模式，如果不解除对应的否决状态，系统将永远不能进入休眠模式。

  - 建议：严格检查是否成对使用，并保证否决休眠的状态持续时间尽量短，以保证尽快进入休眠模式。

- 未打开Wi-Fi子系统低功耗

  - 举例：关闭Wi-Fi子系统低功耗后，未调用uapi_wifi_set_pm_switch接口恢复Wi-Fi子系统低功耗。

  - 分析：打开Wi-Fi子系统低功耗是系统可进入休眠模式的前提，否则即使设置了低功耗模式系统也不会进入休眠模式。

  - 建议：采用低功耗策略，必须打开Wi-Fi子系统低功耗。

- UART外设阻止入睡

  - 举例：系统默认AT业务串口具有睡眠投票属性。如果UART RX处于悬空或没有上拉，即RX为低电平，UART IP将误认为处于接收状态，会拒绝睡眠。如果通过串口执行AT命令唤醒设备，AT模块会使设备在1S定时器超时后才能进休眠。

- 时钟不稳定

  - 举例：RC时钟不稳定，如VBAT电压在休眠后的唤醒瞬间抖动偏大，影响RC校准准确度。

  - 影响：时钟不稳定会导致接受beacon异常，导致无法睡眠，可以直接使用示波器进行测量保活电流波形。

- 抓取无法入睡下的维测

  - 在开启业务串口参与投票时，尽可能的减少log打印或采用延时打印等，避免投票函数的错误判断。

  - 调试阶段，A核串口每50s打印一次A核深睡、浅睡核全系统深睡的统计，可以通过统计判断系统睡眠情况。

## 外设对应业务概率性收发报文异常

- 举例：SPI设备通信发现偶尔接收不到数据，或发送数据与预期不符。

- 分析：深睡后外设均掉电，会导致接收不到对端的发送数据，或者调用完异步发送接口后，数据实际并未发送出去，但系统认为没有业务即将或正在执行，从而进入休眠模式导致数据发送异常。

- 建议：对应业务上需要增加uapi_pm_add_sleep_veto/uapi_pm_remove_sleep_veto等接口调用，以通知系统是否可以进入休眠模式。

## 进入超深睡模式后立即被唤醒

建议：查看唤醒源对应管脚电平是不是稳定的低电平状态。

## 功耗数据会比预期偏高

建议从硬件和软件两个方面排查。

- 硬件：检查底电流是否符合预期。

- 软件：通过以下手段排查：

  1. 观察A核串口打印中，深睡和全系统深睡统计增长情况；

  2. 在WS53处于低功耗模式下，抓包查看到：STA周期性醒来，查收并获取到路由器的缓存数据时，会发送null data帧。之后STA会额外等待一定时间来保持唤醒状态。即STA每次发送null data后，间隔20ms才会再次发送null data帧进入睡眠状态，造成功耗偏高。

     在STA连接上路由器之后，可通过调用uapi_wifi_sta_set_pm_param接口进行保持唤醒时间的动态配置，从而降低功耗。参数定义见service API手册。

## Wi-Fi子系统低功耗与系统低功耗的关系

- 功耗角度：Wi-Fi子系统进行睡眠时关闭Wi-Fi业务侧的MAC PHY等；系统睡眠时Wi-Fi子系统也处于睡眠状态，如果设置系统为深睡模式则CPU会下电，如果设置系统为浅睡模式则会WFI CPU。

- 投票关系：Wi-Fi子系统睡眠时向系统进行投睡眠票，Wi-Fi子系统工作时向系统投否决票；系统睡眠前将Wi-Fi子系统的投票结果以及其他业务注册的投票结果一起判决，只有所有投票结果都赞成睡眠时系统才会入睡；否则，存在某一投票结果投否决票，系统将不睡。

## 如何调整Wi-Fi链路保活Null Data帧的发送周期

不支持修改Wi-Fi链路保活Null Data帧的发送周期

## 降低功耗的相关建议

1. 不使用的外设可在深睡唤醒后关闭相应的时钟门控，建议不使用的外设在不使用时就关闭掉，可进一步降低功耗。

2. 深睡时不使用的IO可配置为GPIO模式、配置为输入态、关闭IO的IE以及无上下拉电阻来降低漏电流。

3. 建议使用默认提供的低功耗参数，以达到功耗和性能的平衡。

4. 睡眠流程在锁中断、锁任务的状态下执行，尽可能的减少阻塞动作，减少不必要的打印等。

5. AT串口默认开启低功耗投票，尽量不使用printk。

6. 如果业务注册了投票函数，在业务需要睡眠时要进行投睡眠票

7. Wi-Fi投票进入深睡的必要条件：使能低功耗（AT+PS=1），idle时间大于200ms，才投票睡眠。