跳转至

pm - 电源管理

作者:陈取德

一、概述

PM 库的核心功能是统一管理模块的电源模式(Power Mode),根据功能分为几类控制接口:

  1. 主控 CPU 的休眠定时器管理;

  2. pm.dtimerStart(id, timeout)

  3. pm.dtimerStop(id)
  4. pm.dtimerCheck(id)
  5. pm.dtimerWkId()
  6. 主控 CPU 的唤醒原因;

  7. pm.lastReson()

  8. 主控 CPU 的关机和重启;

  9. pm.shutdown()

  10. pm.reboot()
  11. 主控 CPU 的常规、低功耗和 PSM+ 极低功耗模式切换;

  12. pm.power(id, mode, chip)

  13. 主控 CPU 的所有 GPIO 输出高电平电压控制;

  14. pm.ioVol(id, val)

  15. 主控 CPU 的充电 IC 管理;

  16. pm.chgcmd(gpio, chip_add, reg, data)

  17. pm.chginfo(gpio, chip_add)
  18. 历史原因被放弃的接口,但是为了让已经出货的客户业务正常运行,而保留的接口说明;

  19. pm.request(mode, chip)

  20. pm.force(mode)
  21. pm.check()

合宙在嵌入式开发低功耗领域深耕多年,致力于让产品能够以更低的功耗正常运作,但是功耗高低的决定因素并不只是硬件决定,软件的业务逻辑和对于多功能的调度配合也能让功耗做到有效降低,所以熟练运营 PM 库的电源模式管理接口,将让您的产品功耗表现得到进一步的提升。

二、核心示例

1、核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码;

2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;

3、更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/lowpower

--[[
本核心示例的的业务逻辑为:
1、上电设定两个不同唤醒时间的dtimerStart休眠定时器,用于执行不同周期的任务。
2、每次开机都判断一次唤醒原因,如果为休眠定时器唤醒,则判断两个休眠定时器的工作状态和剩余时间。
3、如果休眠定时器状态为false则确定该休眠定时器时间到了,执行对应任务后再重新创建休眠定时器。
]] -- Luatools需要PROJECT和VERSION这两个信息
PROJECT = "lowpower_dtimerstart_demo"
VERSION = "001.000.000"

log.info("main", PROJECT, VERSION)

-- 获取唤醒休眠定时器的ID
local timer_id = pm.dtimerWkId()
-- 获取上次唤醒的原因和休眠状态
--[[复位开机详细原因:0-powerkey或者上电开机 1-充电或者AT指令下载完成后开机 
                    2-闹钟开机 3-软件重启 4-未知原因 5-RESET键 6-异常重启 7-工具控制重启 
                    8-内部看门狗重启 9-外部重启 10-充电开机]] --
local reason, _, slp_state = pm.lastReson()
-- 记录唤醒状态信息
log.info("唤醒原因:", pm.lastReson())

local function dtimerstart_check()
    -- 检查休眠定时器0的状态
    local result0, timer0 = pm.dtimerCheck(0)
    log.info("result0 = ", result0, "timer0 = ", timer0)
    -- 检查休眠定时器4的状态
    local result4, timer4 = pm.dtimerCheck(4)
    log.info("result4 = ", result4, "timer4 = ", timer4)

    -- 如果休眠定时器0时间到了,则返回false,就可以在这执行休眠定时器0预定的任务,然后重新下一个休眠定时器0.
    if not result0 then
        -- 重新启动休眠定时器0,定时10000毫秒
        pm.dtimerStart(0, 10000)
    end

    -- 如果休眠定时器4时间到了,则返回false,就可以在这执行休眠定时器4预定的任务,然后重新下一个休眠定时器4.
    if not result4 then
        -- 重新启动休眠定时器4,定时15000毫秒
        pm.dtimerStart(4, 15000)
    end

    -- 等待2000毫秒,确保任务全部执行完毕再进入PSM+,这里可以做个防御机制,避免进入PSM+失败。
    sys.wait(2000)
    -- 进入PSM+模式。
    pm.power(pm.WORK_MODE, 3)
end

local function dtimerstart_main_func()
    -- 打开飞行模式
    mobile.flymode(0, true)
    -- 配置两个时间不同的定时,用于两个不同周期的任务唤醒设备。
    pm.dtimerStart(0, 10000)
    pm.dtimerStart(4, 15000)
    -- 等待5秒,确保任务全部执行完毕再进入PSM+,这里可以做个防御机制,避免进入PSM+失败。
    sys.wait(5000)
    -- 进入PSM+模式。
    pm.power(pm.WORK_MODE, 3)
end

--[[判断开机原因,如果等于0,属于POWERKEY开机的则执行dtimerstart_main_func函数,
创建两个休眠定时器然后进入PSM+休眠,
当开机原因大于0,属于被唤醒开机时执行dtimerstart_check休眠定时器检查函数,
判断休眠定时器状态并做出对应的处理;]]
if reason > 0 then
    sys.taskInit(dtimerstart_check)
else
    -- 开机原因为0,则开机定好两个休眠定时器,然后直接进入PSM+
    sys.taskInit(dtimerstart_main_func)
end
-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

三、常量详解

核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;

常量取值勿主动使用,底层可能会变更,避免造成固件版本升级导致取值与对应的常量不对应的情况,仅做日志打印时查询使用;

3.1 pm.USB

常量含义:USB的供电使能
数据类型:number
常量取值:0
适用产品:Air780E系列Air700E系列Air8000系列
示例代码:--如下方所示,关闭USB的供电使能,即可关闭USB功能;
         pm.power(pm.USB false

3.2 pm.GPS

常量含义:GPS的供电使能
数据类型:number
常量取值:1
适用产品:Air780E系列Air700E系列Air8000系列
示例代码:--如下方所示,关闭GPS的供电使能,即可关闭GPS功能;
         pm.power(pm.GPS false

3.3 pm.GPS_ANT

常量含义:GPS天线的供电使能
数据类型:number
常量取值:2
适用产品:Air780E系列Air700E系列Air8000系列
示例代码:--如下方所示,关闭GPS天线的供电使能,即可关闭GPS天线功能;
         pm.power(pm.GPS_ANT false 
         --当前的天线功能会在调用pm.power(pm.GPS ,false)时同步处理,不需要再单独处理;

3.4 pm.PWK_MODE

常量含义:开机键防抖模式;
数据类型:number
常量取值:5
适用产品:Air780E系列Air700E系列Air8000系列Air8101系列
示例代码:-- Air780EPM、EGH、EHM、EHV、Air8000系列开启pwrkey开机防抖,开机键需拉低2秒以上才能开机;
         -- Air780E、Air780EG开启开机键防抖时,reset键会变成关机键!!!;
         -- 开启pwrkey防抖,反之关闭就是传false;
         pm.power(pm.PWK_MODE, true)

3.5 pm.WORK_MODE

常量含义:模块的工作功耗模式;
数据类型:number
常量取值:6
适用产品:Air780EXX系列Air700EXX系列Air8000系列Air8101系列
示例代码:--Air780EXXX系列、Air8000系列、Air8101系列配置各种功耗模式,使用前一定要仔细学习各型号下软件资料中的“低功耗指南”文档!!!;
         pm.power(pm.WORK_MODE0 
         --[[
         功耗模式简介
         -- 常规模式
         -- PRO低功耗模式
         -- PSM+模式

         以上模式均使用 pm.power(pm.WORK_MODE, mode) 来设置
         -- mode=0   常规模式,正常运行,就是无休眠
         -- mode=1   PRO低功耗模式, CPU停止, RAM保持, 可中断唤醒, 可任意定时器唤醒, 可网络唤醒. 支持脚本从休眠处继续运行
         -- mode=2   与mode=1完全相同,使用1和2都是PRO低功耗模式
         -- mode=3   PSM+模式, CPU停止, RAM掉电, 支持特殊唤醒管脚唤醒, 支持休眠定时器唤醒. 唤醒后脚本从头开始执行
         ]]

3.6 pm.IOVOL_ALL_GPIO

常量含义:模块所有GPIO输出的高电平电压
数据类型:number
常量取值:0
适用产品:Air780EXX系列Air700EXX系列Air8000系列Air8101系列
示例代码:--如下方所示,第二个参数为**3300**,所有GPIO高电平输出3.3V;
         **pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)**

3.7 pm.ID_NATIVE

常量含义:从硬件架构的角度来划分,目前合宙模组产品有两大类:
         1、第一类产品的硬件中,有主处理芯片和协处理芯片两种芯片,例如Air8000系列中的部分型号
         2、第二类产品的硬件中,只有主处理芯片一种芯片,例如Air8000系列中的部分型号Air6101/8101系列、Air780系列Air700系列
         pm.ID_NATIVE指每个产品中的主处理芯片
数据类型:number
常量取值:1
适用产品:Air8000系列Air8101系列Air6101系列
示例代码:--如下方所示,在例如Air8000这类多芯产品上,可以指定某个芯片进入对应的工作功耗模式;
         pm.power(pm.WORK_MODE0 pm.ID_NATIVE
         --所有单芯片产品的默认芯片均不需要填写;
         --Air8000类多芯产品默认芯片均为4G芯片,WIFI芯片ID为pm.ID_WIFI;

3.8 pm.ID_WIFI

常量含义:从硬件架构的角度来划分,目前合宙模组产品有两大类:
        1、第一类产品的硬件中,有主处理芯片和协处理芯片两种芯片,例如Air8000系列中的部分型号
        2、第二类产品的硬件中,只有主处理芯片一种芯片,例如Air8000系列中的部分型号Air6101/8101系列、Air780系列Air700系列
        pm.ID_WIFI指每个产品中的协助处理WIFI芯片
数据类型:number
常量取值:1
适用产品:Air8000系列Air8101系列Air6101系列
示例代码:--如下方所示,在例如Air8000这类多芯产品上,可以指定WIFI芯片进入对应的工作功耗模式;
         pm.power(pm.WORK_MODE0 pm.ID_WIFI
         --所有单芯片产品的默认芯片均不需要填写;
         --Air8000类多芯产品默认芯片均为4G芯片,WIFI芯片ID为pm.ID_WIFI;

3.9 pm.WIFI_STA_DTIM

常量含义:WIFI通信时的DTIM频率
数据类型:number
常量取值:8
适用产品:Air8000系列中支持WIFI数传功能的型号Air8101系列Air6101系列
示例代码:--如下方所示,可将WIFI通信时的DTIM频率设为10,也就是1000毫秒一次;
         pm.power(pm.WIFI_STA_DTIM, 10)
         --DTIM1 和 DTIM10 的核心区别有:
         --DTIM1不会丢失WIFI AP路由器发送给wiFi station的广播帧和组播帧,DTIM10会丢失,
         --一般来说,对于iot应用,丢失广播帧和组播帧对产品应用没有什么影响,只要单播帧不丢失就行;
         --一般来说,WiFiAP路由器发送Beacon帧的间隔是100毫秒,DTIM1最长延迟100毫秒可以收到WIFI AP路由器发送过来的数据,
         --DTIM10最长演示1000毫秒可以收到WIFI AP路由器发送过来的数据。可以根据自己项目对功耗以及数据收发时延的要求选择合适的DTIM配置。

3.10 pm.IOVOL_SDIO

常量含义:MMC供电输出1.6-3.2V 之间可调,默认3.1VIOmax=150mA
数据类型:number
常量取值:1
适用产品:Air72x系列Air820系列
示例代码:--如下方所示,配置MCC供电电压为3V;
         pm.ioVol(pm.IOVOL_SDIO, 3000)

3.11 pm.IOVOL_LCD

常量含义:LCD供电输出1.6-3.3V 之间可调,默认1.8V, IOmax=200mA
数据类型:number
常量取值:2
适用产品:Air72x系列Air820系列
示例代码:--如下方所示,配置LCD供电电压为3V;
         pm.ioVol(pm.IOVOL_LCD, 3000)

3.12 pm.IOVOL_CAMA

常量含义:Camera提供模拟电压输出1.6-3.2V 之间可调,默认1.8V, IOmax=100mA
数据类型:number
常量取值:3
适用产品:Air72x系列Air820系列
示例代码:--如下方所示,配置Camera的模拟电压为3V;
         pm.ioVol(pm.IOVOL_CAMA, 3000)

3.13 pm.IOVOL_CAMD

常量含义:Camera提供数字电压输出1.4-2.1V 之间可调,默认1.8V, IOmax=100mA
数据类型:number
常量取值:4
适用产品:Air72x系列Air820系列
示例代码:--如下方所示,配置Camera的数字电压为2V;
         pm.ioVol(pm.IOVOL_CAMA, 2000)

四、函数详解

4.1 pm.dtimerStart(id, timeout)

功能

dtimerStart 全称为 deeptimerStart,即休眠定时器;

pm.dtimerStart(id, timeout)的功能为启动一个休眠定时器,在休眠模式下依然生效. 只执行一次,调用 pm.shutdown()关机或者断电情况下休眠定时器失效,重新上电后休眠定时器清零;

与 sys 库中的 timerStart 定时器的区别在于 dtimerStart 可在 PSM+ 极低功耗模式代码停跑的环境下仍可工作,timerStart 仅可工作在常规模式和低功耗模式这种代码正常执行的环境;

dtimerStart 在不同的电源状态下的工作状态:

  1. 非休眠状态

  2. 正常工作,与 timerStart 一样;

  3. 休眠状态

  4. 正常工作,可用于唤醒休眠状态,唤醒后未超时的 dtimerStart 仍正常工作;

  5. 重启过程中

  6. 使用 reset 重启后 dtimerStart 清零,需要重新配置;

  7. vbat 不断电关机后

  8. 调用 pm.shutdown()后软件关机,dtimerStart 清零,不再唤醒模块;

  9. vbat 不断电自动重启

  10. 调用 pm.reboot()或者 rtos.reboot()重启,dtimerStart 清零,不再唤醒模块;

  11. vbat 断电关机后

  12. dtimerStart 清零,不再唤醒模块;

  13. vbat 断电关机后再 vbat 上电开机

  14. dtimerStart 清零,不再唤醒模块;

注意事项

  1. Air780 系列、Air700 系列、Air8000 系列

  2. 最多只能定 6 个休眠定时器,注意 id 的管理,重复 id 将会被重置,只识别最后设定的 id 休眠定时器

  3. id 为 0 和 1 的休眠定时器最大休眠时长为 2.5 小时
  4. id 为 2、3、4、5 的休眠定时器最大休眠时长为 740 小时
  5. Air8101 系列、Air6101 系列

  6. 仅有 1 个休眠定时器,id 为 0,最长休眠时长为 1008 小时,重复 id 将会被重置,只识别最后设定的 id 休眠定时器

参数

id

参数含义:休眠定时器id,底层已经固定,根据定时时长需求选择对应的定时id
数据类型:number
取值范围:0-5
是否必选:必须传入此参数;
注意事项:id为0和1的休眠定时器最大休眠时长为2.5小时;
         id为2345的休眠定时器最大休眠时长为740小时;
参数示例:--如下方所示,这是设定一个dtimerStart休眠定时器的写法,第一个参数必须指定休眠定时器id;
         pm.dtimerStart(0, 10000)

timeout

参数含义:休眠定时器超时时长(单位:毫秒),需注意休眠定时器id号对应的时长限制
数据类型:number
取值范围:0-9000000 or 0-2664000000
是否必选:必须传入此参数;
注意事项:id为0和1的休眠定时器最大休眠时长为2.5小时; 
         id为2345的休眠定时器最大休眠时长为740小时;
         目前的timeout参数如果填入了超出了对应休眠定时器id的最长休眠时长范围,休眠定时器会按照最大休眠时长唤醒设备,后面更新版本时底层会增加验证机制将会更新增加timeout参数的验证功能,超出则会有提示错误的打印,并将timeout修正为对应休眠定时器id的最大休眠时长
参数示例:--如下方所示,这是设定一个dtimerStart休眠定时器的写法,第二个参数必须在对应id号的设定时长范围内;
         pm.dtimerStart(0, 10000)

返回值

local result = pm.dtimerStart(id, timeout)

有一个返回值 result

result

含义说明:dtimerStart休眠定时器是否启动成功
数据类型:boolean
取值范围:成功时返回true,失败时返回false
注意事项:返回值为dtimerStart休眠定时器的启动是否成功,如果休眠定时器id不是在0-5的范围内,不在范围内返回false
         timeout时长超出最大休眠时长则会有提示错误的打印,并将timeout修正为对应休眠定时器id的最大休眠时长
返回示例:true

示例

--如下方所示,这是设定一个dtimerStart休眠定时器的写法,第一个参数必须指定休眠定时器id,第二个参数必须在对应id号的设定时长范围内;
local a = pm.dtimerStart(0, 10000)
log.info("第一个休眠定时器返回值", a)
-- a 的返回值即为true;
--如下方所示,第一个参数超出休眠定时器id范围;
local b = pm.dtimerStart(9, 15000)
log.info("第二个休眠定时器返回值", b)
-- b 的返回值即为false;
--如下方所示,第二个参数超出对应休眠定时器id最长休眠时长范围;
local c = pm.dtimerStart(0, 3*60*60*1000)
log.info("第二个休眠定时器返回值", c)
-- c 的返回值为true,后面更新版本时底层会增加验证机制,超出最长休眠时长范围则会有提示错误的打印,并将timeout修正为对应定时器id的最大休眠时长;

4.2 pm.dtimerStop(id)

功能

关闭休眠定时器

注意事项

  1. Air780 系列、Air700 系列、Air8000 系列

  2. 有最多 6 个休眠定时器,需要逐一调用 pm.dtimerStop(id)关闭对应 ID 的休眠定时器

  3. Air8101 系列、Air6101 系列

  4. 仅有 1 个休眠定时器,id 为 0,所以在这类模块中只需要调用 pm.dtimerStop(0)即可关闭休眠定时器

参数

id

参数含义:需要关闭的休眠定时器对应的id
数据类型:number
取值范围:0-5
是否必选:必须传入此参数;
注意事项:Air780系列Air700系列Air8000系列
         有最多6个休眠定时器,需要逐一调用pm.dtimerStop(id)关闭对应ID的休眠定时器
         Air8101系列Air6101系列
         仅有1个休眠定时器,id为0,所以在这类模块中只需要调用pm.dtimerStop(0)即可关闭休眠定时器;
参数示例:--如下方所示,这是关闭一个dtimerStart休眠定时器的写法,第一个参数必须指定休眠定时器id;
         pm.dtimerStop(0)

返回值

示例

-- 关闭休眠定时器
pm.dtimerStop(0) -- 关闭id=0的休眠定时器

4.3 pm.dtimerCheck(id)

功能

检查休眠定时器是不是在运行

注意事项

注意 dtimerstart 的 id 管理

参数

id

参数含义:休眠定时器id,调用前已启动的dtimerstart休眠定时器所使用的id
数据类型:number
取值范围:0-5
是否必选:必须传入此参数;
注意事项:注意dtimerstart的id管理
参数示例:--如下方所示,这是查询一个dtimerStart休眠定时器的写法,第一个参数必须指定休眠定时器id;
         pm.dtimerCheck(0)

返回值

local result ,time = pm.dtimerCheck(id)

有两个返回值 result 和 time

result

含义说明:对应ID的dtimerStart休眠定时器的运行状态
数据类型:boolean
取值范围:运行中返回true,已超时定时器已被定时器消息管理列表删除,找不到该ID的休眠定时器所以返回false
注意事项:返回值为对应ID的dtimerStart休眠定时器当前运行状态
返回示例:false

time

含义说明:对应ID还在运行中的dtimerStart休眠定时器的剩余状态时长
数据类型:number
取值范围:0-2664000000,单位毫秒;
注意事项:无;
返回示例:9999

示例

-- 如下所示,检查ID为0的休眠定时器工作状态和定时器超时剩余时间;
-- 如果休眠定时器0超时了则重新创建一个新的休眠定时器0;
local result , time = pm.dtimerCheck(0)
if not result then
    pm.dtimerStart(0, 10000)
end

4.4 pm.dtimerWkId()

功能

检查模块的开机原因是否为休眠定时器唤醒,输出超时的休眠定时器 ID 号,如果不是休眠定时器唤醒的,返回-1

注意事项

注意 dtimerstart 的 id 管理

参数

返回值

local timer_id = pm.dtimerWkId()

有一个返回值 timer_id

timer_id

含义说明:检查唤醒原因是否为dtimerStart休眠定时器唤醒
数据类型:number
取值范围:-1 - 5
注意事项:处理结果 >=0 说明本次是休眠定时器唤醒,并且timer_id是休眠定时器唤醒源的id-1说明不是休眠定时器唤醒的;
返回示例:-1

示例

-- 如下示例,开机后先检查开机是否由休眠定时器唤醒,并打印对应的休眠定时器ID;
-- 然后设定0号和1号两个定时器,并且关闭0号定时器;
-- 实际工作的只有1号定时器,所以执行后打印都是由1号休眠定时器唤醒开机;
local result = pm.dtimerWkId()
if result > 0 then
    log.info("本次开机是由"..result.."号休眠定时器超时唤醒")
else
    log.info("本次开机非休眠定时器唤醒")
end
pm.dtimerStart(0, 5*60*1000)
log.info("设定0号休眠定时器,5分钟后唤醒")
pm.dtimerStart(1, 5*60*1000)
log.info("设定1号休眠定时器,5分钟后唤醒")
local result1 , time = pm.dtimerCheck(0)
log.info("检查0号休眠定时器工作状态:" , result1 , "还有"..time.."秒后超时")
pm.dtimerStop(0)
log.info("关闭0号休眠定时器")

4.5 pm.lastReson()

功能

检查开机原因,该函数有 3 个返回值,根据产品型号不同,查看对应的开机原因:

第一个返回值:
0-上电/复位开机;
1-RTC开机
2-WakeupIn/Pad/IO开机

第二个返回值:
0-普通开机(上电/复位)
3-深睡眠开机;
4-休眠开机;

第三个返回值:
0-powerkey或者上电开机
1-充电或者AT指令下载完成后开机
2-闹钟开机;
3-软件重启;
4-未知原因;
5-RESET键
6-异常重启;
7-工具控制重启;
8-内部看门狗重启;
9-外部重启;
10-充电开机;
  1. Air700 系列、Air780 系列、Air8000 系列

  2. 先看第一个返回值如果为 0 则看第三个返回值对应的具体开机原因;

  3. 第一个返回值为 1 则是休眠定时器唤醒,返回值为 2 则是通过 WAKEUP 中断唤醒;
  4. Air72x 系列、Air820 系列

  5. 看第二个返回值的开机原因;

注意事项

pm.lastReson()有 3 个返回值,不同型号的返回值查看方式不同,请注意返回值详情

参数

返回值

local a , b , c = pm.lastReson()

有三个返回值 a , b , c

a

含义说明:
        0-上电/复位开机:POWERKEY/RESET开机,或者其他原因触发的开机具体原因通过C的返回值查看
        1-RTC开机dtimerstart休眠定时器超时唤醒开机
        2-WakeupIn/Pad/IO开机AGPIO或者WAKEUP中断触发唤醒开机
数据类型:number
取值范围:0-2
注意事项:Air700系列Air780系列Air8000系列该返回值为0时,通过c的返回值查看详细的复位开机原因
返回示例:1

b

含义说明:
        0-普通开机(上电/复位)
        4-休眠开机;
数据类型:number
取值范围:034
注意事项:Air72X系列Air820系列直接查看该返回值对应的开机原因
返回示例:4

c

含义说明:a返回值为0时,复位开机详细原因
        0-powerkey或者上电开机:由powerkey触发的开机
        3-软件重启:调用pm.reboot()或者rtos.reboot()重启开机;
        4-未知原因:运行死机导致的异常重启开机;
        5-RESET键:由外部触发reset键或者LUATOS下载脚本后的重启
        6-异常重启:运行死机导致的异常重启开机;
        8-内部看门狗重启:底层看门狗超时重启;
        9-外部重启:高温或高压导致的重启;
        10-充电开机:VBUS上电开机
数据类型:number
取值范围:0-10
注意事项:Air700系列Air780系列Air8000系列a返回值为0时,通过c的返回值查看详细的复位开机原因
返回示例:0

示例

-- 以下列出了在PSM+模式下常见的各种开机或重启时调用pm.lastReson()获取的开机原因参考;

-- powerkey或上电自动开机时;
local a , b , c = pm.lastReson()
log.info("本次开机原因:", a , b , c)
-- LUATOOLS中的实际打印为:
I/user.本次开机原因: 0 0 0

-- dtimerstart休眠定时器唤醒开机时;
local a , b , c = pm.lastReson()
log.info("本次开机原因:", a , b , c)
-- LUATOOLS中的实际打印为:
I/user.本次开机原因: 1 4 0

-- wakeupio中断唤醒开机时;
local a , b , c = pm.lastReson()
log.info("本次开机原因:", a , b , c)
-- LUATOOLS中的实际打印为:
I/user.本次开机原因: 2 4 0

-- 调用pm.reboot()重启开机时;
local a , b , c = pm.lastReson()
log.info("本次开机原因:", a , b , c)
-- LUATOOLS中的实际打印为:
I/user.本次开机原因: 0 0 3

-- 调用rtos.reboot()重启开机时;
local a , b , c = pm.lastReson()
log.info("本次开机原因:", a , b , c)
-- LUATOOLS中的实际打印为:
I/user.本次开机原因: 0 0 3

4.6 pm.shutdown()

功能

软件控制关机

注意事项

软件关机后必须手动拉低开机键才可以再开机,无法通过软件再开机和唤醒,PWRKEY 接地也不行,谨慎使用!!! 在以下硬件环境下调用该接口的结果: POWERKEY 用按钮引出,调用 pm.shutdown()后软件关机,软件无法再开机和唤醒,可以按 POWERKEY 按钮触发开机。 POWERKEY 接地自动开机时调用 pm.shutdown(),将无法通过软硬件再开机,需要断电重新上电才可以触发开机。

参数

返回值

示例

pm.shutdown()

4.7 pm.reboot()

功能

软件控制模块重启;

与 rtos 库中的 rtos.reboot()完全一致,只是函数名称不同;

注意事项

调用该接口时软件会强制重启,注意调用前保存必要临时数据,避免数据丢失

参数

返回值

示例

pm.reboot()

4.8 pm.power(id, mode, chip)

功能

配置模块的功耗模式:

支持控制内部 GPS 的供电使能开关,非内置 GPS 功能的模块需要将外挂 GPS 的供电使能脚接到 GPIO21,也可调用该接口作为 GPS 的供电使能开关控制;

支持控制内部 USB 的供电使能开关;

注意事项

在控制 GPS 和 USB 的供电使能开关时需要注意硬件连线方式,请看详细示例

参数

id

常量:pm.USB
参数含义:模块内部USB的使能管脚,运行USB的相关业务时底层自动控制供电使能,不需要额外控制;
是否必选:必须传入此参数;
参数示例:--如下方所示,关闭USB的供电使能,即可关闭USB功能;
         pm.power(pm.USB false 

常量:pm.GPS
参数含义:模块内部GPS的使能管脚,运行GPS的相关业务时底层自动控制GPS和GPS_ANT天线的供电使能,不需要额外控制;
是否必选:必须传入此参数;
参数示例:--如下方所示,关闭GPS的供电使能,即可关闭GPS功能;
         pm.power(pm.GPS false 

常量:pm.PWK_MODE
参数含义:开启pwrkey的防抖功能
是否必选:必须传入此参数;
参数示例:--如下方所示,开启pwrkey防抖,开机键需拉低2秒以上才能开机;
         pm.power(pm.PWK_MODE true 

常量:pm.WORK_MODE
参数含义:模组功耗模式;
是否必选:必须传入此参数;
参数示例:--如下方所示,模块进入常规模式;
         pm.power(pm.WORK_MODE0

mode

含义说明:配置pm.USB/pm.GPS/pm.PWK_MODE时所需要的参数
参数示例:--如下方所示,第二个参数为false,关闭USB的供电使能,即可关闭USB功能;
         pm.power(pm.USB false 
         --如下方所示,第二个参数为false,关闭GPS的供电使能,即可关闭GPS功能;
         pm.power(pm.GPS false 
         --如下方所示,第二个参数为true,开启pwrkey防抖,开机键需拉低2秒以上才能开机;
         pm.power(pm.PWK_MODE true 

含义说明:配置pm.WORK_MODE所需要的参数
参数示例:--[[
        功耗模式简介
        -- 常规模式
        -- PRO低功耗模式
        -- PSM+模式

        以上模式均使用 pm.power(pm.WORK_MODE, mode) 来设置
        -- mode=0   常规模式,正常运行,就是无休眠
        -- mode=1   PRO低功耗模式, CPU停止, RAM保持, 可中断唤醒, 可任意定时器唤醒, 可网络唤醒.          支持脚本从休眠处继续运行
        -- mode=2   与mode=1完全相同,使用1和2都是PRO低功耗模式
        -- mode=3   PSM+模式, CPU停止, RAM掉电, 支持特殊唤醒管脚唤醒, 支持休眠定时器唤醒. 唤醒           后脚本从头开始执行
        ]]
        --如下方所示,第二个参数为0,模块进入常规模式;
        pm.power(pm.WORK_MODE0

chip

含义说明:需要控制功耗模式的芯片ID
数据类型:number
取值范围:pm.ID_NATIVE / pm.ID_WIFI
注意事项:参考pm.ID_NATIVE / pm.ID_WIFI的常量注意事项

返回值

local result = pm.power(id, onoff, chip)

有一个返回值 result

result

含义说明:判断功能开启关闭是否正常执行;
数据类型:boolean
取值范围:成功时返回true,失败时返回false
注意事项:该返回值仅代表传入的参数是否正确,返回true时不代表进入了对应的低功耗模式
         进入PRO低功耗模式只能通过电流表观察电流是否下降,判断是否成功进入PRO模式
         因为进入PSM+后代码停跑的原理,可以在这条代码后增加显性动作,查看是否正常进入PSM+
         在这条代码在增加等待和一个打印或者重启可以显性的判断模块是否正常休眠,见下方示例;
参数示例:--如下方所示,第二个参数为0,模块进入常规模式;
         **local result = pm.power(pm.WORK_MODE , 3)** 
         sys.wait(5000)
         log.info("进入PSM+模式失败,即将重启")
         pm.reboot()
返回示例:true

示例

-- 关闭USB电源, 反之开启就是传true;
pm.power(pm.USB, false) 

-- 在内置GPS的模块上,例如Air780EGH、Air8000等会同步控制GPS_ANT天线使能;
-- 在外挂GPS模块时,必须将GPS供电使能脚接到GPIO21才可以调用该接口!!!;
-- 关闭GPS电源,反之开启就是传true;
pm.power(pm.GPS, false)

-- Air780E系列开启pwrkey开机防抖,开机键需拉低2秒以上才能开机;
-- Air780E、Air780EG这类618系列芯片开启开机键防抖时,reset键会变成关机键!!!;
-- 开启pwrkey防抖,反之关闭就是传false;
pm.power(pm.PWK_MODE, true)


--Air780EXXX系列、Air8000系列、Air8101系列配置各种功耗模式,使用前一定要仔细学习各型号下软件资料中的“低功耗指南”文档!!!;
-- 第二参数传入0-3,进入对应的功耗模式;
--[[
功耗模式简介
-- 常规模式
-- PRO低功耗模式
-- PSM+模式

以上模式均使用 pm.power(pm.WORK_MODE, mode) 来设置
-- mode=0   常规模式,正常运行,就是无休眠
-- mode=1   PRO低功耗模式, CPU停止, RAM保持, 可中断唤醒, 可任意定时器唤醒, 可网络唤醒. 支持脚本从休眠处继续运行
-- mode=2   与mode=1完全相同,使用1和2都是PRO低功耗模式
-- mode=3   PSM+模式, CPU停止, RAM掉电, 支持特殊唤醒管脚唤醒, 支持休眠定时器唤醒. 唤醒后脚本从头开始执行
]]
pm.power(pm.WORK_MODE0 

--Air8000系列带WIFI功能的产品在进入低功耗时需要单独控制WIFI芯片进入低功耗模式;
pm.power(pm.WORK_MODE1 pm.ID_WIFI 

4.9 pm.ioVol(id, val)

功能

配置模块所有 IO 引脚的高电平电压

注意事项

可配置 IO 电平, 范围 1650 ~ 2000,2650~3400 , 单位毫伏, 步进 50mv,可以根据外围电路需求配置;

实际应用中,经常配置的三个经典电压值为 1.8V/2.8V/3.3V;

合宙支持二次开发的模组,绝大多数默认都为 3.3V,例外是:

Air8000 系列模组,全系只支持 3.3V,不支持其它电平;

Air780EHV,IO 电平固定为 3.3V;相对应的,Air780EHV-1.8V,IO 电平固定为 1.8V;

特别注意!

Air722UG/Air724UG/Air795UG 三款模组不支持本函数配置 IO 电平,支持这三个模组型号的函数有 pm.IOVOL_CAMA、pm.IOVOL_CAMD 等,具体请查阅本文其它介绍;

合宙 4G 模组(Air700 系列/Air780 系列/Air8000 系列),IO 管脚分属于不同的两个电压域,分别为 LDO_AON 和 VDD_EXT,IO 本身又分为普通 GPIO、AGPIO 和 WAKEUP,AGPIO 又可以分为 AGPIO 和 AGPIOWU,具体差异如下图所示;

不同的 IO 的驱动力存在差异,以 Air780Exx 为例:

  • GPIO20\21\22:这三个管脚为 AGPIOWU,也就是既可以配置为 AGPIO 使用,也可以配置为 WAKEUP 使用,需要注意的是:

这三个 IO 管脚,电流驱动能力只有 30uA,在需要上拉或下拉的情况下,一般需要搭配 100K 电阻使用,如果阻值太低,有可能会因驱动能力有限导致电平值偏低;

  • GPIO23-28:这 6 个管脚为 AGPIO,可以在低功耗模式下保持电平,实际驱动力为 1.2 毫安,在需要上拉或下拉的情况下,一般需要搭配 10K 电阻使用,如果阻值太低,有可能会因驱动能力有限导致电平值偏低;

早期的模组型号中,比如 Air780EPM/Air780EHM,将 PIN100 固定用作 IO_Volt_Set 使用,IO_Volt_Set 脚悬空则模块 IO 电平配置为 3.3V,接地拉低则配置为 1.8V;

需要说明的是:

  • Air780EPM/EHM:模块会根据 100 脚的 IO_Volt_Set 脚接地还是悬空而配置模块的电压,但还是软件配置优先;
  • Air780EGH/EGP/EGG 等:不再将 PIN100 固定作为 IO_Volt_Set 使用,而是将其释放为 GPIO17 使用,需要改变 IO 电平时,可以使用 pm.ioVol()配置;

参数

id

含义说明:需要配置高电平电压的对象;
数据类型:number
取值范围:0
注意事项:对象id仅有pm.IOVOL_ALL_GPIO,如命名含义,指配置所有GPIO的高电压电平,调用该接口时模块会以该接口配置的高电压电平调整,无视固件的默认配置和硬件100IO_Volt_Set的拉高和拉低配置
参数示例:--如下方所示,第一个参数为**pm.IOVOL_ALL_GPIO**,所有GPIO高电平输出1.8V;
        pm.ioVol(pm.IOVOL_ALL_GPIO, 1800)

val

含义说明:需要配置对象的电压值;
数据类型:number
取值范围:1650 ~ 20002650~3400 , 单位毫伏, 步进50mv
注意事项:模块会有1.8V和3.3V默认高电平电压的版本,也可调用该接口手动调整,以外围电路要求为主;
参数示例:--如下方所示,第二个参数为**3300**,所有GPIO高电平输出3.3V;
         pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)

返回值

local result = pm.ioVol(id, val)

有一个返回值 result

result

含义说明:判断高电平电压调整是否正确执行;
数据类型:boolean
取值范围:成功时返回true,失败时返回false
注意事项:注意电压变化前后的外部电阻匹配;
参数示例:--如下方所示,第二个参数为3300,模块所有IO的高电平电压配置为为3.3V;
         --result返回true则模块电压转为3.3V;
         local result = pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)
返回示例:true

示例

pm.ioVol(pm.IOVOL_ALL_GPIO, 3300)    -- 所有GPIO高电平配置为3.3V
pm.ioVol(pm.IOVOL_ALL_GPIO, 1800)    -- 所有GPIO高电平配置为1.8V

4.10 pm.chgcmd(gpio, chip_add, reg, data)

功能

单总线命令,配置 YHM27XX 充电 IC

注意事项

支持如 Air8000 系列内置 YHM27XX 的模块;

支持管理外挂 YHM27XX;

该接口只能配置型号为:YHM27xx 系列的充电 IC,不是该型号的不要调用!!!

该接口只能配置型号为:YHM27xx 系列的充电 IC,不是该型号的不要调用!!!

该接口只能配置型号为:YHM27xx 系列的充电 IC,不是该型号的不要调用!!!

由于历史原因,在 Air8000 系列产品上开放了该接口,现在已经有了 exchg 扩展库,新项目推荐使用 exchg 扩展库!

本文档保留 pm.chgcmd 接口的完整说明以供历史项目参考,

参数

gpio

含义说明:与YHM27XX直连的gpio号
数据类型:number
取值范围:虽然理论上支持0-254,但实际可用的GPIO取决于具体的模组型号
注意事项:需要明确与THM27xx充电IC直连的gpio号,不是pin脚号
参数示例:--如下方所示,第一个参数为与YHM27XX直连的gpio号;
         pm.chgcmd(2, 0x04, 0x42, 0XAA)

chip_add

含义说明:YHM27XX充电IC的芯片地址
数据类型:number
取值范围:参考YHM27XX规格书
注意事项:参考YHM27XX规格书
参数示例:--如下方所示,第二个参数为YHM27XX充电IC的芯片地址;
         pm.chgcmd(2, 0x04, 0x42, 0XAA)

reg

含义说明:YHM27XX充电IC的寄存器地址,配置YHM27XX的相关功能时需要向对应寄存器输入相对应的指令或者读取寄存器数据
数据类型:number
取值范围:参考YHM27XX规格书
注意事项:需要明确与THM27xx充电IC读写数据的寄存器地址
参数示例:--如下方所示,第三个参数为YHM27XX的寄存器地址;
         pm.chgcmd(2, 0x04, 0x42, 0XAA)

data

含义说明:向YHM72XX对应功能寄存器发送的指令,不填数据则是向对应功能寄存器读取数据;
数据类型:number
取值范围:参考YHM27XX规格书
注意事项:需要明确与THM27xx充电IC对应寄存器发送的明确指令,参考规格书;
参数示例:--如下方所示,第四个参数为向YHM27XX的0X42寄存器存入数据0XAA;
         pm.chgcmd(2, 0x04, 0x42, 0XAA)
         --如下方所示,第四个参数不填写数据,则是向0X42寄存器读取数据;
         pm.chgcmd(2, 0x04, 0x42)

返回值

local ret1 、ret2 = pm.chgcmd(gpio, chip_add, reg, data)

有 2 个返回值

ret1

含义说明:pm.chgcmd接口读写状态
数据类型:boolean
取值范围:成功时返回true,失败时返回false
注意事项:需根据所使用YHM27XX的规格书明确对应芯片地址、寄存器地址和指令;
参数示例:--如下方所示,向GPIO2所连接的YHM27XX充电IC,芯片地址为0X04,寄存器地址为0X42的寄存器中发送一条指令0XAA;
         **local ret1 ret2  = pm.chgcmd(2, 0x04, 0x42, 0XAA)**
         --ret1返回true则发送成功;
         --如下方所示,向GPIO2所连接的YHM27XX充电IC,芯片地址为0X04,寄存器地址为0X42的寄存器读取数据;
         **local ret1 ret2  = pm.chgcmd(2, 0x04, 0x42)**
         --ret1返回true则读取成功;
返回示例:true

ret2

含义说明:pm.chgcmd接口读取的数据
数据类型:boolean
取值范围:number
注意事项:需根据所使用YHM27XX的规格书明确对应芯片地址、寄存器地址;
参数示例:--如下方所示,向GPIO2所连接的YHM27XX充电IC,芯片地址为0X04,寄存器地址为0X42的寄存器中           发送一条指令0XAA;
         --写入成功ret2无返回值;
         local ret1 ret2  = pm.chgcmd(2, 0x04, 0x42, 0XAA)

         --如下方所示,从GPIO2所连接的YHM27XX充电IC,芯片地址为0X04,寄存器地址为0X42的寄存器读           取数据;
         --读取成功后ret2会携带读取的数据;
         local ret1 ret2  = pm.chgcmd(2, 0x04, 0x42)
返回示例:0X00

示例

--如下方所示,向GPIO2所连接的YHM27XX充电IC,芯片地址为0X04,寄存器地址为0X42的寄存器中发送一条指令0XAA;
local ret1 ret2  = pm.chgcmd(2, 0x04, 0x42, 0XAA)
--如下方所示,从GPIO2所连接的YHM27XX充电IC,芯片地址为0X04,寄存器地址为0X42的寄存器读取数据;
local ret1 ret2  = pm.chgcmd(2, 0x04, 0x42)

4.11 pm.chginfo(gpio, chip_add)

功能

获取最新的寄存器信息(异步)

注意事项

该接口为异步执行,不会阻塞当前代码

参数

gpio

含义说明:与YHM27XX直连的gpio号
数据类型:number
取值范围:虽然理论上支持0-254,但实际可用的GPIO取决于具体的模组型号
注意事项:需要明确与THM27xx充电IC直连的gpio号,不是pin脚号
参数示例:--如下方所示,第一个参数为与YHM27XX直连的gpio号;
         **pm.chginfo(2, 0x04)**

chip_add

含义说明:YHM27XX充电IC的芯片地址
数据类型:number
取值范围:参考YHM27XX规格书
注意事项:参考YHM27XX规格书
参数示例:--如下方所示,第二个参数为YHM27XX充电IC的芯片地址;
         **pm.chginfo(2, 0x04)**

返回值

示例

--如下方所示,在调用yhm27xx.reqinfo前需要订阅"YHM27XX_REG"消息,yhm27xx.reqinfo异步执行完成后会推送"YHM27XX_REG"消息并携带所有寄存器的数据;
sys.subscribe("YHM27XX_REG", function(data)
    -- 注意, 会一次性读出0-8,总共9个寄存器值
    log.info("yhm27xx", data and data:toHex())
end)
yhm27xx.reqinfo(**2, 0x04**)

4.12 pm.wakeupPin(gpio,level)

功能

Air8101 系列、Air6101 系列所有 IO 脚都可以配置为唤醒脚,在进入低功耗和 PSM+ 模式时配置唤醒 IO 使用;

注意事项

该接口仅 Air8101 系列、Air6101 系列产品可调用;

对 Air780xx 系列,Air8000,Air72x 系列均无效;

参数

gpio

含义说明:需要实现唤醒功能的GPIO管脚
数据类型:number
取值范围:根据实际使用的产品型号管脚说明填写;
注意事项:该接口仅Air72x系列Air820系列可调用
参数示例:--如下方所示,第一个参数为gpio1的管脚;
         **pm.wakeupPin( 1 , gpio.FALLING )**

level

含义说明:唤醒方式, 例如gpio.RISING (上升沿), gpio.FALLING (下降沿)
数据类型:number
取值范围:gpio.RISING (上升沿), gpio.FALLING (下降沿)
注意事项:该接口仅Air72x系列Air820系列可调用
参数示例:--如下方所示,第二个参数为检测到上升沿时唤醒;
         **pm.wakeupPin( 1 , gpio.FALLING )**

返回值

local result = pm.wakeupPin(gpio,level)

有一个返回值 result

result

含义说明:配置处理结果;
数据类型:boolean
取值范围:成功时返回true,失败时返回false
参数示例:--如下方所示,配置GPIO1在检测到上升沿时唤醒;
         **local result = pm.wakeupPin( 1 , gpio.FALLING )**
         --result返回true则配置成功;
返回示例:true

示例

--该接口仅展锐平台可用,例如Air724UG、Air720UG等;
--如下方所示,配置GPIO1在检测到上升沿时唤醒;
**local result = pm.wakeupPin( 1 , gpio.FALLING )**
--result返回true则配置成功;

五、不推荐使用接口

以下接口在以前常用于低功耗的管理,因为是直接配置芯片的功耗,无视代码层的运作,时常出现其他任务执行导致无法正常进入对应的功耗状态,所以现在已经明确使用 pm.power(id, mode, chip)接口管理,由底层统一管理在进入低功耗时需要做的事情,确保进入对应功耗状态的可靠性,以下接口则处于废弃状态,仅供已使用以下接口量产的客户查询使用,新客户不可再使用!!!

5.1 核心示例

--[[
休眠模式简介

-- IDLE 正常运行模式
-- LIGHT 轻睡眠模式:
        CPU暂停
        RAM保持供电
        定时器/网络事件/IO中断均可自动唤醒
        唤醒后程序继续运行
        普通GPIO掉电,外设驱动掉电
        AON_GPIO保持电平
-- DEEP 深睡眠模式
        CPU暂停
        核心RAM掉电, 保留RAM维持供电
        普通GPIO掉电,外设驱动掉电
        AON_GPIO保持休眠前的电平
        dtimer定时器可唤醒
        wakeup脚可唤醒
        唤醒后程序从头运行,休眠前的运行时数据全丢
-- HIB 休眠模式
        CPU暂停
        RAM掉电, 保留RAM也掉电
        普通GPIO掉电,外设驱动掉电
        AON_GPIO保持休眠前的电平
        dtimer定时器可唤醒
        wakeup脚可唤醒
        唤醒后程序从头运行,休眠前的运行时数据全丢

对部分模块,例如Air780EXXX, DEEP/HIB对用户代码没有区别

除pm.shutdown()外, RTC总是运行的, 除非掉电
]]

-- 定时器唤醒, 请使用 pm.dtimerStart()
-- wakeup唤醒
    -- 如Air101/Air103, 有独立的wakeup脚, 不需要配置,可直接控制唤醒
    -- 如Air780EXXX系列, 有多个wakeup可用, 通过gpio.setup()配置虚拟GPIO进行唤醒配置,参考demo/gpio/virtualIO

pm.request(pm.IDLE) -- 通过切换不同的值请求进入不同的休眠模式
-- 对应Air780EXXX系列, 执行后并不一定马上进入休眠模式, 如无后续数据传输需求,可先进入飞行模式,然后快速休眠

5.2 常量详解

核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;

常量
类型
解释
pm.NONE
number
不休眠模式
pm.IDLE
number
IDLE模式
pm.LIGHT
number
LIGHT模式
pm.DEEP
number
DEEP模式
pm.HIB
number
HIB模式
pm.CAMERA
number
camera电源,CAM_VCC输出
pm.DAC_EN
number

Air780EXXX的DAC_EN(新版硬件手册的LDO_CTL,同一个PIN,命名变更),注意audio的默认配置会自动使用这个脚来控制CODEC的使能
pm.LDO_CTL
number
Air780EXXX的LDO_CTL(老版硬件手册的DAC_EN,同一个PIN,命名变更),Air780EXXX的LDO_CTL, 注意audio的默认配置会自动使用这个脚来控制CODEC的使能

pm.request(mode, chip)

请求进入指定的休眠模式

参数

传入值类型
解释
int
休眠模式,例如pm.IDLE/LIGHT/DEEP/HIB.
int
休眠芯片的ID, 默认是0, 大部分型号都只有0

返回值

返回值类型
解释
boolean
处理结果,即使返回成功,也不一定会进入, 也不会马上进入

例子

-- 请求进入休眠模式
--[[
IDLE   正常运行,就是无休眠
LIGHT  轻休眠, CPU停止, RAM保持, 外设保持, 可中断唤醒. 部分型号支持从休眠处继续运行
DEEP   深休眠, CPU停止, RAM掉电, 仅特殊引脚保持的休眠前的电平, 大部分管脚不能唤醒设备.
HIB    彻底休眠, CPU停止, RAM掉电, 仅复位/特殊唤醒管脚可唤醒设备.
]]

pm.request(pm.HIB)

pm.force(mode)

强制进入指定的休眠模式,忽略某些外设的影响,比如 USB

参数

传入值类型
解释
int
休眠模式

返回值

返回值类型
解释
boolean
处理结果,若返回成功,大概率会马上进入该休眠模式

例子

-- 请求进入休眠模式
pm.force(pm.HIB)
-- 针对Air780EXXX, 该操作会关闭USB通信
-- 唤醒后如需开启USB, 请打开USB电压
--pm.power(pm.USB, true)

pm.check()

检查休眠状态

参数

返回值

返回值类型
解释
boolean
处理结果,如果能顺利进入休眠,返回true,否则返回false
int
底层返回值,0代表能进入最底层休眠,其他值代表最低可休眠级别

例子

-- 请求进入休眠模式,然后检查是否能真的休眠
pm.request(pm.HIB)
if pm.check() then
    log.info("pm", "it is ok to hib")
else
    -- 针对Air780EXXX, 该操作会关闭USB通信
    pm.force(pm.HIB) -- 强制休眠
    -- 唤醒后如需开启USB, 请打开USB电压
    --sys.wait(100)
    --pm.power(pm.USB, true)
end