7.38. 系统休眠
Overview
介绍系统休眠
7.38.1. 系统休眠配置与API
系统休眠配置:配置文件在
app_config.h
,参考:apps/wifi_story_machine/include/app_config.h
。wifi处于STA模式或者开启蓝牙情况下,整个系统自动休眠。
①在打开app_config.h打开如下宏,没有则添加上
#define CONFIG_LOW_POWER_ENABLE //低功耗开关
。②在打开app_config.h修改
TCFG_LOWPOWER_LOWPOWER_SEL
宏,没有则添加上#define TCFG_LOWPOWER_LOWPOWER_SEL (RF_SLEEP_EN | SYS_SLEEP_EN | RF_FORCE_SYS_SLEEP_EN)
。Note
一般只开启
(RF_SLEEP_EN)
或者(RF_SLEEP_EN | SYS_SLEEP_EN | RF_FORCE_SYS_SLEEP_EN)
,SYS_SLEEP_EN
:操作系统时休眠使能,需要使操作系统空闲休眠或跟随RF休眠的必须使能。SYS_SLEEP_BY_IDLE
:允许操作系统时空闲休眠使能,前提使能SYS_SLEEP_EN
。RF_SLEEP_EN
:允许wifi和蓝牙的RF休眠。RF_FORCE_SYS_SLEEP_EN
:允许RF休眠时强制操作系统休眠,前提使能SYS_SLEEP_EN
。操作系统空闲休眠则RF必须处于休眠。以上配置是根据系统状态进行的休眠,最好的效果是
(RF_SLEEP_EN | SYS_SLEEP_EN | RF_FORCE_SYS_SLEEP_EN)
。③在打开board.c需添加上:低功耗配置和版籍电源初始化加上power_init()函数,参考
apps/wifi_story_machine/board/wl82/board_7911B.c
。/************************** LOW POWER config ****************************/ static const struct low_power_param power_param = { .config = TCFG_LOWPOWER_LOWPOWER_SEL, .btosc_disable = TCFG_LOWPOWER_BTOSC_DISABLE, //进入低功耗时BTOSC是否保持 .vddiom_lev = TCFG_LOWPOWER_VDDIOM_LEVEL, //强VDDIO等级,可选:2.2V 2.4V 2.6V 2.8V 3.0V 3.2V 3.4V 3.6V .vddiow_lev = TCFG_LOWPOWER_VDDIOW_LEVEL, //弱VDDIO等级,可选:2.1V 2.4V 2.8V 3.2V .vdc14_dcdc = TRUE, //打开内部1.4VDCDC,关闭则用外部 .vdc14_lev = VDC14_VOL_SEL_LEVEL, //VDD1.4V配置 .sysvdd_lev = SYSVDD_VOL_SEL_LEVEL, //内核、sdram电压配置 .vlvd_enable = TRUE, //TRUE电压复位使能 .vlvd_value = VLVD_SEL_25V, //低电压复位电压值 }; static void board_power_init(void) { power_init(&power_param);//电源初始化,包括休眠的参数 .... }
强制整个系统休眠API函数
u8 low_power_all_group_force_sleep(u32 us);//强制休眠API函数
Note
注意 :强制休眠API函数,单位us,返回值:0正常休眠,大于0被io唤醒(值和board.c的唤醒IO配置的.attribute相关),小于0休眠失败(两次休眠时间间隔小于10ms,应用层需要在返回值小于0情况下,可多次尝试请求休眠,或者延时10ms后即可)
low_power_all_group_force_sleep()
休眠函数使用不能使用在开启蓝牙,可以使用在开启wifi,但开启wifi情况下需要注意掉线等问题(休眠时间不能过长,一般1秒内) 使用该函数是wifi的RF和操作系统都会进入休眠状态。禁止和允许wifi或蓝牙的RF硬件自动休眠API函数
void low_power_hw_unsleep_lock(void);//RF硬件禁止休眠 void low_power_hw_unsleep_unlock(void);//RF硬件允许休眠
Note
RF硬件休眠的禁止和允许函数,和强制休眠函数
low_power_all_group_force_sleep()
无关,当强制休眠则禁止RF硬件休眠函数也无效。 当需要禁止RF硬件自动休眠,则调用low_power_hw_unsleep_lock(); 当需要允许RF硬件自动休眠,则调用low_power_hw_unsleep_unlock(); 当开启禁止RF硬件自动休眠,则操作系统不会进入休眠。设置系统idle空闲休眠时间API函数
void power_set_sys_sleep_internal_us(u32 sys_sleep_internal_us);//设置系统的idle空闲休眠时间
Note
设置系统空闲休眠时间和操作系统相关,只有当操作系统都处于空闲状态才能进入休眠,休眠时间也根据操作系统空闲时间进行休眠,一般为20ms-50ms,用户需要加大休眠时间达到降低功耗,则使用power_set_sys_sleep_internal_us()函数自定义时间, 同时app_config.h的
TCFG_LOWPOWER_LOWPOWER_SEL
需要或上SYS_SLEEP_BY_IDLE
和SYS_SLEEP_EN
。
7.38.2. 低功耗时候进行io保持
参考
apps/wifi_story_machine/board/wl82/board_7911B.c
在使用的板级文件board.c中对于进低功耗前和退出低功耗时候的回调函数中进行io的配置
//退出低功耗时候回调函数
static void sleep_exit_callback(u32 usec)
{
}
//进入低功耗前回调函数,此函数禁止添加打印
static void sleep_enter_callback(u8 step)
{
if (step == 1) {
dac_power_off();
} else { //在此处step == 2进行保持某些 IO 状态
gpio_direction_output(IO_PORTA_07, 1); //进低功耗前设置为高电平,硬件外部没有上下拉,则使用内部上下拉:根据输出1开上拉关下拉,输出0关上拉开下拉
gpio_set_pull_up(IO_PORTA_07, 1); //打开上拉
gpio_set_pull_down(IO_PORTA_07, 0); //关下拉
gpio_set_direction(IO_PORTA_07, 1); //设置引脚方向为输入
gpio_set_die(IO_PORTA_07, 0); //设置引脚为跟电压相关的模拟功能
}
}
//设置进出低功耗时回调函数
static void board_power_init(void)
{
...
...
power_init(&power_param);
power_set_callback(TCFG_LOWPOWER_LOWPOWER_SEL, sleep_enter_callback, sleep_exit_callback, NULL); //第三个参数为设置进soft poweroff软关机前配置,此处为说明休眠低功耗powerdown,故设为空
...
...
}
如果想保证修改之后不被任何地方更改 IO 的值,则可以加 gpio_latch_en()函数锁定,前提修改先需要解锁 gpio_latch_en(x, 0),修改后锁住 gpio_latch_en(x,1),才能有效,注意:在修改 IO 状态先务必解锁对应 IO 才有效。应用层在休眠后时,需要保持某些 IO 状态,在 power_set_callback()函数第三个参数函数里面完成,如下sleep_exit_callback()函数进行恢复
//退出低功耗时候回调函数
static void sleep_exit_callback(u32 usec)
{
gpio_latch_en(IO_PORTA_07, 0); //解锁PA7
}
//进入低功耗前回调函数,此函数禁止添加打印
static void sleep_enter_callback(u8 step)
{
if (step == 1) {
dac_power_off();
} else {
gpio_latch_en(IO_PORTA_07, 0); //解锁PA7
gpio_direction_output(IO_PORTA_07, 1); //进低功耗前设置为高电平,硬件外部没有上下拉,则使用内部上下拉:根据输出1开上拉关下拉,输出0关上拉开下拉
gpio_set_pull_up(IO_PORTA_07, 1); //打开上拉
gpio_set_pull_down(IO_PORTA_07, 0); //关下拉
gpio_set_direction(IO_PORTA_07, 1); //设置引脚方向为输入
gpio_set_die(IO_PORTA_07, 0); //设置引脚为跟电压相关的模拟功能
gpio_latch_en(IO_PORTA_07, 1); //锁定PA7
}
}
7.38.3. 低功耗IO唤醒时获取具体的IO唤醒源
板级配置需要设置IO唤醒源
#define PORT_WAKEUP_IO IO_PORTB_01 //软关机和休眠唤醒引脚
#define PORT_WAKEUP_NUM (PORT_WAKEUP_IO/IO_GROUP_NUM)//默认:0-7:GPIOA-GPIOH, 可以指定0-7组
static const struct port_wakeup port0 = {
.edge = FALLING_EDGE, //唤醒方式选择,可选:上升沿\下降沿
.attribute = BLUETOOTH_RESUME, //不能屏蔽
.iomap = PORT_WAKEUP_IO, //唤醒口选择
.low_power = POWER_SLEEP_WAKEUP | POWER_OFF_WAKEUP, //低功耗IO唤醒,不需要写0
};
static void io_wakeup_callback(void)
{
//休眠时IO唤醒会进去这个回调函数
int wakeup_io = hw_power_get_last_wakeup_io(); //获取上一次IO唤醒源
}
static void board_power_init(void)
{
power_init(&power_param);
set_port_wakeup_cb(io_wakeup_callback); //需要设置IO唤醒回调函数
....
}