# 低功耗应用指导
***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.***
---
# 功能概述
在嵌入式开发与物联网应用中,功耗管理是提升设备续航能力的关键。LPM(Low Power Mode,低功耗模式)模块通过精细化的休眠与唤醒控制,有效降低设备功耗并延长电池使用寿命。本文主要描述如何通过相关API实现低功耗。
- **休眠机制:** 设备在无业务活动时,根据配置进入低功耗状态,关闭非必要硬件功能组件以节约能源。LPM支持常规休眠以及更深度的PSM(Power Saving Mode,省电模式),但PSM功能需要模块硬件支持。
- **唤醒机制:** 处于休眠状态的设备由特定触发源唤醒,并恢复至正常运行状态。LPM支持多种唤醒方式,包括DTR信号变化、UART串口数据收发、网络数据交互以及外部引脚(PIN)触发等。
- **投票机制:** 该机制允许多个功能组件共同参与系统的休眠决策。系统会为每个业务功能组件分配独立的投票句柄。仅当所有投票者均投出“允许”票时,系统才会进入休眠状态;若任意一个功能组件投出“禁止”票(例如正在执行关键数据传输任务),设备将保持唤醒状态。
```{image} images/image_PzjmbhUMYozk1zxgHipc8bWhn4f.webp
:width: 2293px
:height: 1827px
:align: center
```
LPM功能组件为开发者提供了一套完整的低功耗开发工具链,涵盖以下核心功能:
| **功能分类** | **核心工具/接口** | **技术价值** |
| --- | --- | --- |
| **策略配置** | ***qosa_lpm_config_set()*** | 自定义休眠模式、延迟休眠时间、PSM定时器参数(T3412/T3324)、UART/DTR等外部唤醒源配置及RRC快速释放策略 |
| **业务同步** | 投票句柄API
***qosa_lpm_app_vote_new_handle()***
***qosa_lpm_app_vote_enable()***
***qosa_lpm_app_vote_disable()*** | 通过逻辑“与”关系协调多任务间的休眠冲突,确保业务连续性 |
| **状态感知** | 休眠唤醒事件机制,详见 [休眠唤醒事件通知](#休眠唤醒事件通知) | 实时上报休眠状态切换及具体的唤醒原因(如网络数据或外部信号),便于应用层调整业务逻辑 |
| **高级优化** | RRC快速释放
***qosa_lpm_config_set()*** | 在无数据交互时主动释放网络资源,从而进一步降低空闲期的功耗 |
# LPM API
## 头文件
*qosa_lpm.h*
## 函数概览
| **函数** | **描述** |
| --- | --- |
| *qosa_lpm_config_set()* | 设置LPM休眠配置 |
| *qosa_lpm_config_get()* | 获取LPM休眠配置 |
| *qosa_lpm_app_vote_new_handle()* | 创建低功耗投票句柄 |
| *qosa_lpm_app_vote_enable()* | 投票允许系统进入休眠 |
| *qosa_lpm_app_vote_disable()* | 投票禁止系统进入休眠 |
| *qosa_lpm_app_vote_del_handle()* | 删除投票句柄 |
## 函数详解
### 休眠配置API
#### **qosa_lpm_config_set**
- **功能描述**
设置LPM休眠配置,包括休眠模式、延迟休眠时间、PSM定时器参数、DTR/UART唤醒控制以及RRC快速释放等功能。通过配置低功耗策略,使系统按照指定规则进入休眠状态。
- **函数原型**
```objective-c
qosa_lpm_error_e qosa_lpm_config_set(qosa_lpm_config_t *info)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *info* | 输入 | *qosa_lpm_config_t\** | LPM配置结构体指针 |
- **返回值说明**
*QOSA_LPM_ERR_OK*:函数执行成功
*QOSA_LPM_ERR_INVALID_PARAM*:参数无效
*QOSA_LPM_ERR_GENERAL*:配置错误
```{note}
PSM模式需要网络侧支持才能生效。
```
#### **qosa_lpm_config_get**
- **功能描述**
获取LPM休眠配置,包括休眠模式、延迟休眠时间和PSM定时器参数等信息。
- **函数原型**
```objective-c
void qosa_lpm_config_get(qosa_lpm_config_t *info)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *info* | 输出 | *qosa_lpm_config_t\** | LPM配置结构体指针 |
- **返回值说明**
无
```{note}
1. 调用前需确保info结构体内存已分配。
2. 该函数获取的配置参数为系统当前生效的实际配置值。
```
### 休眠投票API
#### qosa_lpm_app_vote_new_handle
- **功能描述**
创建低功耗投票句柄,用于应用层控制系统休眠状态。
- **函数原型**
```objective-c
qosa_lpm_error_e qosa_lpm_app_vote_new_handle(
const char *name,
qosa_handle *handle_id
)
```
调用成功后,系统为该应用分配一个独立的投票句柄。应用可基于该句柄调用 ***qosa_lpm_app_vote_enable()*** 或 ***qosa_lpm_app_vote_disable()*** 来投票控制是否允许系统进入低功耗模式。系统将综合所有已注册投票句柄的状态做出休眠决策。
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *name* | 输入 | const char * | 投票者名称,用于区分不同的投票功能组件。单位:字节 |
| *handle_id* | 输出 | qosa_handle * | 投票句柄 |
- **返回值说明**
*QOSA_LPM_ERR_OK*:函数执行成功
*QOSA_LPM_ERR_INVALID_PARAM*:参数无效
*QOSA_LPM_ERR_GENERAL*:创建失败
```{note}
1. 每个应用功能组件应使用唯一的名称标识,便于调试和追踪。
2. 创建句柄后,默认状态为允许休眠。
3. 应用关闭休眠投票功能时,需要调用 ***qosa_lpm_app_vote_del_handle()*** 删除句柄。
```
#### qosa_lpm_app_vote_enable
- **功能描述**
投票允许系统进入休眠。仅当所有投票句柄均允许休眠时,系统才会进入休眠模式。
- **函数原型**
```objective-c
qosa_lpm_error_e qosa_lpm_app_vote_enable(qosa_handle handle_id)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *handle_id* | 输入 | qosa_handle | 投票句柄 |
- **返回值说明**
*QOSA_LPM_ERR_OK*:函数执行成功
*QOSA_LPM_ERR_INVALID_PARAM*:参数无效
*QOSA_LPM_ERR_NO_HANDLE*:句柄无效
```{note}
1. 调用函数前,需确保句柄已通过 ***qosa_lpm_app_vote_new_handle()*** 成功创建。
2. 投票结果遵循逻辑“与”关系,仅当所有句柄均允许休眠时,系统才会进入休眠。
```
#### **qosa_lpm_app_vote_disable**
- **功能描述**
投票禁止系统进入休眠。只要有一个投票句柄禁止休眠,系统就不会进入休眠模式,且保持唤醒状态。
- **函数原型**
```objective-c
qosa_lpm_error_e qosa_lpm_app_vote_disable(qosa_handle handle_id)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *handle_id* | 输入 | qosa_handle | 投票句柄 |
- **返回值说明**
*QOSA_LPM_ERR_OK*:函数执行成功
*QOSA_LPM_ERR_INVALID_PARAM*:参数无效
*QOSA_LPM_ERR_NO_HANDLE*:句柄无效
```{note}
1. 当应用功能组件需保持设备唤醒时(如数据传输和定时任务),应调用此函数阻止系统休眠。
2. 任务完成后,请调用 ***qosa_lpm_app_vote_enable()*** 恢复允许休眠状态,以降低功耗。
```
#### **qosa_lpm_app_vote_del_handle**
- **功能描述**
删除投票句柄,并释放相关资源。删除后该句柄不再参与休眠决策。
- **函数原型**
```objective-c
qosa_lpm_error_e qosa_lpm_app_vote_del_handle(qosa_handle handle_id)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *handle_id* | 输入 | qosa_handle | 投票句柄 |
- **返回值说明**
*QOSA_LPM_ERR_OK*:函数执行成功
*QOSA_LPM_ERR_INVALID_PARAM*:参数无效
*QOSA_LPM_ERR_NO_HANDLE*:句柄无效
```{note}
1. 当应用功能组件退出或不再需要参与休眠决策时,应调用此函数释放资源。
2. 句柄被删除后即为失效状态,请勿再次使用。
```
### 休眠唤醒事件通知
LPM功能组件基于 *qosa_event_notify* 机制,向应用层上报休眠与唤醒的状态变化。应用层可根据业务需求注册对应的事件回调函数,从而实时感知系统休眠状态的切换并做出相应处理。
#### 事件ID定义
事件ID定义于 *qosa_event_notify.h* 的 *qosa_notify_event_e* 枚举中,与LPM相关的事件共有两个:
| **事件ID** | **枚举值** | **说明** | **关联数据结构** |
| --- | --- | --- | --- |
| *QOSA_EVENT_LPM_SLEEP_STATUS* | 23 | 设备休眠或唤醒状态变化 | [*qosa_lpm_sleep_event_t*](#qosalpmsleepeventt) |
| *QOSA_EVENT_PSM_SLEEP_STATUS* | 19 | PSM深度休眠状态 | [*qosa_lpm_psm_event_t*](#qosalpmpsmeventt) |
```{note}
1. 两个事件独立上报,不存在互斥或替代关系。
2. 常规休眠事件(*QOSA_EVENT_LPM_SLEEP_STATUS*)适用于所有休眠模式的进入与退出;而 *QOSA_EVENT_PSM_SLEEP_STATUS* 仅在PSM模式下触发。
```
#### 注册与注销事件回调
通过 *qosa_event_notify_register()* 和 *qosa_event_notify_unregister()* 管理事件回调:
```c
// 注册
qosa_e_n_error_e qosa_event_notify_register(
qosa_notify_event_e event,
event_callback_ptr event_cb,
void *user_argv
);
// 注销
qosa_e_n_error_e qosa_event_notify_unregister(
qosa_notify_event_e event,
event_callback_ptr event_cb
);
```
```{note}
1. 同一事件类型可注册多个不同的回调函数,各回调函数将独立接收该事件。
2. 注销时需传入与注册时相同的 *event_cb* 指针,系统据此区分不同的注册者。
```
#### 回调函数签名
该类型定义了LPM事件回调函数的标准原型。所有通过 *qosa_event_notify_register()* 注册的回调函数,均需严格遵循此签名规范。
```c
typedef int (*event_callback_ptr)(void *user_argv, void *argv)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *user_argv* | 输入 | void* | 注册时传入的用户自定义参数 |
| *argv* | 输入 | void* | 事件数据指针,使用时需强制转换为对应的结构体类型 |
- **返回值说明**
*0*:函数执行成功
非 *0*:函数执行失败
#### 使用示例
**常规休眠与唤醒事件处理示例**
```c
#include "qosa_lpm.h"
#include "qosa_event_notify.h"
static int lpm_sleep_event_cb(void *user_argv, void *argv)
{
qosa_lpm_sleep_event_t *event = (qosa_lpm_sleep_event_t *)argv;
if (event->status == QOSA_LPM_SLEEP_STATUS_SLEEP)
{
printf("device entering sleep\r\n");
}
else
{
printf("device wakeup, reason: %d, pin: %d\r\n",
event->reason, event->wakeup_pin_num);
}
return 0;
}
void app_lpm_init(void)
{
qosa_event_notify_register(QOSA_EVENT_LPM_SLEEP_STATUS,
lpm_sleep_event_cb, QOSA_NULL);
}
```
**PSM深度休眠事件**
```c
static int psm_status_event_cb(void *user_argv, void *argv)
{
qosa_lpm_psm_event_t *psm_event = (qosa_lpm_psm_event_t *)argv;
if (psm_event->sleep_status == QOSA_PSM_ENTER_SLEEP)
{
// 进入PSM 深度休眠
}
else
{
// PSM 唤醒后恢复
}
return 0;
}
void app_psm_init(void)
{
qosa_event_notify_register(QOSA_EVENT_PSM_SLEEP_STATUS,
psm_status_event_cb, QOSA_NULL);
}
```
## 结构体定义
本章节定义LPM功能组件相关的数据结构,用于描述配置参数与休眠事件等内容。这些结构体主要用于LPM函数的参数传递及事件回调。
### qosa_lpm_sleep_event_t
设备休眠或唤醒状态变化结构体定义如下:
```c
typedef struct
{
qosa_lpm_sleep_e status;
qosa_lpm_wakeup_reason_e reason;
qosa_uint8_t wakeup_pin_num;
} qosa_lpm_sleep_event_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *status* | *qosa_lpm_sleep_e* | 休眠状态。详见 [*qosa_lpm_sleep_e*](#qosalpmsleep_e) 章节 |
| *reason* | *qosa_lpm_wakeup_reason_e* | 唤醒原因。仅在参数 *status* 为 *QOSA_LPM_SLEEP_STATUS_WAKEUP* 时有效。详见 [*qosa_lpm_wakeup_reason_e*](#qosalpmwakeupreasone) 章节 |
| *wakeup_pin_num* | qosa_uint8_t | 触发唤醒的引脚编号,仅在参数 *reason* 为 *QOSA_LPM_WAKEUP_REASON_PIN* 时有效 |
```{note}
该结构体需配合 *QOSA_EVENT_LPM_SLEEP_STATUS* 事件使用。
```
### qosa_lpm_psm_event_t
PSM休眠状态结构体定义如下:
```c
typedef struct
{
qosa_lpm_psm_sleep_status_e sleep_status;
} qosa_lpm_psm_event_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *sleep_status* | *qosa_lpm_psm_sleep_status_e* | PSM休眠状态。详见 [*qosa_lpm_psm_sleep_status_e*](#qosalpmpsmsleepstatus_e) 章节 |
```{note}
该结构体需配合 *QOSA_EVENT_PSM_SLEEP_STATUS* 事件使用。
```
### qosa_lpm_config_t
LPM配置结构体定义如下:
```c
typedef struct
{
qosa_lpm_mode_e lpm_mode;
qosa_uint32_t delay_time;
qosa_uint8_t tau[QOSA_LPM_PTAUS_MAX_LEN + 1];
qosa_uint8_t active[QOSA_LPM_PTAUS_MAX_LEN + 1];
qosa_lpm_dtr_e dtr_en;
qosa_lpm_uart_e uart_en;
qosa_bool_t rfr_enable;
qosa_uint8_t no_data_time;
qosa_uint16_t retry_time;
} qosa_lpm_config_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *lpm_mode* | *qosa_lpm_mode_e* | 休眠模式。详见 [*qosa_lpm_mode_e*](#qosalpmmode_e) 章节 |
| *delay_time* | qosa_uint32_t | 延迟休眠时间。单位:毫秒;范围:1000~255000;默认值:5000毫秒 |
| *tau* | qosa_uint8_t[9] | PSM T3412定时器值。字符串格式,如"01000010" |
| *active* | qosa_uint8_t[9] | PSM T3324定时器值。字符串格式,如"00100010" |
| *dtr_en* | *qosa_lpm_dtr_e* | DTR唤醒使能 |
| *uart_en* | *qosa_lpm_uart_e* | UART唤醒使能 |
| *rfr_enable* | qosa_bool_t | RRC快速释放功能使能 |
| *no_data_time* | qosa_uint8_t | 无数据交互后,释放RRC并进入休眠的时间。单位:秒;范围:1~50 |
| *retry_time* | qosa_uint16_t | 检测到异常并关闭RRC快速释放功能后,重新开启的等待时间,单位:秒,范围:60~36000 |
## 枚举定义
### qosa_lpm_error_e
码枚举定义如下:
```c
typedef enum
{
QOSA_LPM_ERR_OK = 0,
QOSA_LPM_ERR_INVALID_PARAM = 1 | QOSA_COMPONENT_API_LPM,
QOSA_LPM_ERR_GENERAL,
QOSA_LPM_ERR_NO_HANDLE,
} qosa_lpm_error_e;
```
| **成员** | **说明** |
| --- | --- |
| *QOSA_LPM_ERR_OK* | 函数执行成功 |
| *QOSA_LPM_ERR_INVALID_PARAM* | 参数无效 |
| *QOSA_LPM_ERR_GENERAL* | 配置错误 |
| *QOSA_LPM_ERR_NO_HANDLE* | 句柄无效 |
### qosa_lpm_mode_e
休眠模式枚举定义如下:
```c
typedef enum
{
QOSA_LPM_MODE_DISABLE = 0,
QOSA_LPM_MODE_ENABLE = 1,
QOSA_LPM_MODE_PSM = 2,
QOSA_LPM_MODE_MAX,
} qosa_lpm_mode_e;
```
| **成员** | **说明** |
| --- | --- |
| *QOSA_LPM_MODE_DISABLE* | 禁用休眠,设备保持唤醒状态 |
| *QOSA_LPM_MODE_ENABLE* | 允许休眠,设备可进入低功耗模式 |
| *QOSA_LPM_MODE_PSM* | 启用PSM模式,设备进入深度低功耗模式 |
### qosa_lpm_dtr_e
DTR唤醒使能枚举定义如下:
```c
typedef enum
{
QOSA_LPM_DTR_ENABLE = 0,
QOSA_LPM_DTR_DISABLE = 1,
} qosa_lpm_dtr_e;
```
| **成员** | **说明** |
| --- | --- |
| *QOSA_LPM_DTR_ENABLE* | 启用DTR唤醒控制,DTR信号变化可唤醒设备 |
| *QOSA_LPM_DTR_DISABLE* | 禁用DTR唤醒控制 |
### qosa_lpm_uart_e
UART唤醒使能枚举定义如下:
```c
typedef enum
{
QOSA_LPM_UART_ENABLE = 0,
QOSA_LPM_UART_DISABLE = 1,
} qosa_lpm_uart_e;
```
| **成员** | **说明** |
| --- | --- |
| *QOSA_LPM_UART_ENABLE* | 启用UART唤醒控制,UART收发数据即可唤醒设备 |
| *QOSA_LPM_UART_DISABLE* | 禁用UART唤醒控制 |
### qosa_lpm_psm_sleep_status_e
PSM休眠状态枚举定义如下:
```c
typedef enum
{
QOSA_PSM_ENTER_SLEEP = 0,
QOSA_PSM_EXIT_SLEEP = 1,
} qosa_lpm_psm_sleep_status_e;
```
| **成员** | **说明** |
| --- | --- |
| *QOSA_PSM_ENTER_SLEEP* | 进入PSM休眠模式 |
| *QOSA_PSM_EXIT_SLEEP* | 从PSM休眠模式唤醒 |
### qosa_lpm_sleep_e
休眠状态枚举定义如下:
```c
typedef enum
{
QOSA_LPM_SLEEP_STATUS_SLEEP = 0,
QOSA_LPM_SLEEP_STATUS_WAKEUP = 1,
} qosa_lpm_sleep_e;
```
| **成员** | **说明** |
| --- | --- |
| *QOSA_LPM_SLEEP_STATUS_SLEEP* | 设备已进入低功耗休眠状态 |
| *QOSA_LPM_SLEEP_STATUS_WAKEUP* | 设备已从休眠状态中唤醒 |
### qosa_lpm_wakeup_reason_e
唤醒原因枚举定义如下:
```plaintext
typedef enum
{
QOSA_LPM_WAKEUP_REASON_DTR = 0,
QOSA_LPM_WAKEUP_REASON_NET_DATA = 1,
QOSA_LPM_WAKEUP_REASON_UART = 2,
QOSA_LPM_WAKEUP_REASON_USB = 3,
QOSA_LPM_WAKEUP_REASON_ACTIVE = 4,
QOSA_LPM_WAKEUP_REASON_PIN = 5,
QOSA_LPM_WAKEUP_REASON_OTHER = 6,
QOSA_LPM_WAKEUP_REASON_MAX,
} qosa_lpm_wakeup_reason_e;
```
| **成员** | **说明** |
| --- | --- |
| *QOSA_LPM_WAKEUP_REASON_DTR* | DTR引脚电平变化 |
| *QOSA_LPM_WAKEUP_REASON_NET_DATA* | 网络数据收发 |
| *QOSA_LPM_WAKEUP_REASON_UART* | UART串口数据收发 |
| *QOSA_LPM_WAKEUP_REASON_USB* | USB插拔事件 |
| *QOSA_LPM_WAKEUP_REASON_ACTIVE* | 主动调用API或AT命令禁用休眠 |
| *QOSA_LPM_WAKEUP_REASON_PIN* | 外部引脚变化 |
| *QOSA_LPM_WAKEUP_REASON_OTHER* | 其他原因 |
# 应用示例
## 示例使用说明
### 1. 准备工作
在使用LPM示例验证相关功能前,请完成以下准备工作:
- 准备一套支持LPM功能的测试模块;
- 确保模块固件已包含LPM功能组件;
- 了解模块的休眠唤醒引脚配置。
### 2. SDK配置说明
在SDK根目录下修改 *target.config* 文件,启用LPM示例功能:
```bash
CONFIG_QOSA_LPM_FUNC=y
```
修改完成后,请重新编译SDK,以确保配置生效。
# 应用逻辑流程图
```{figure} images/board_Dzulw1mvZhU5GFbxI2ccFtcNnH6.jpg
:align: center
:alt: image
```
# 示例代码
完整示例代码请查看 https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/system/lpm/lpm_demo.c 。