# 低功耗应用指导 ***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 。