7.39. 系统休眠

Overview

介绍系统休眠


7.39.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_IDLESYS_SLEEP_EN

7.39.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.39.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唤醒回调函数

        ....
}