低功耗管理
概述
SOC低功耗模式:
- 全速运行,SOC的CPU和外设全开
- CPU睡眠,可以被任意中断唤醒。这种模式完全由OS控制,对于应用是透明的。tick或tickless低功耗属于这个模式,对应到hobbit芯片为wait模式
- SOC深度睡眠,能保持运行上下文。除了CPU睡眠,SOC大部分外设(peripheral)也睡眠,进入这种低功耗,首先确保外设不在传输过程中,接着设置RTC和其它必要外设作为唤醒源,唤醒后读取RTC补偿系统时间。因为要设置必要的唤醒源,需要用户部分干预。这种模式对应到hobbit芯片为doze、stop模式。
- SOC待机,不能维持运行上下文,唤醒后相当于重启。这是最深度的睡眠,除了唤醒机构工作,其它都睡眠。进入这种低功耗,系统没有继续执行的能力,所以这种低功耗模式,完全交由用户管理,设置唤醒时间,并执行关机。对应到hobbit为standby模式
板级设备的低功耗管理:
- 板级设备的低功耗由应用管理,或间接通过YoC的设备管理进入低功耗模式,此过程需要用户实现设备的lpm接口。
对于SOC深度睡眠,SOC进入深度睡眠前,要挂起板级设备,唤醒后,需要恢复板级设备,因此编写设备驱动的时候,需要实现设备低功耗驱动接口。 对于SOC待机,SOC进入待机的时候,用户要先close之前打开的设备。
接口定义
初始化低功耗模块
void pm_init(lpm_event_cb_t pm_cb)
- 参数: pm_cb: lpm(低功耗管理)进入及唤醒时的回调函数
- 返回值: 无
typedef void (*lpm_event_cb_t)(pm_policy_t policy, lpm_event_e event)
typedef enum {
LPM_EVENT_WAKUP,
LPM_EVENT_SUSPEND,
} lpm_event_e;
配置低功耗设备的掩码
void pm_config_mask(uint32_t lpm_dev_mask);
配置低功耗设备的掩码,掩码位置对应的模块不进入低功耗
- 参数:
- lpm_dev_mask: 低功耗设备掩码
- 返回值: 无
配置低功耗策略
void pm_config_policy(int policy)
支持三种低功耗策略:正常模式、CPU睡眠模式和深度睡眠模式。此配置决定系统可以进入何种低功耗模式
enum {
LPM_POLICY_NO_POWER_SAVE,
LPM_POLICY_LOW_POWER,
LPM_POLICY_DEEP_SLEEP,
} pm_policy_t;
- 参数:
- policy: 低功耗策略
- 返回值: 无
允许系统待机
void pm_agree_halt(uint32_t ms)
用户程序完成业务后,调用此接口允许系统进入待机模式。如果系统同时运行多个业务,待所有业务完成后,再调用此接口
- 参数:
- ms: 以毫秒为单位设置RTC唤醒时间。设置为AOS_WAIT_FOREVER表示一直待机
- 返回值: 无
示例代码
让设备进入待机状态
pm_init(cb);
pm_config_policy(LPM_POLICY_DEEP_SLEEP);
... //用户代码
pm_agree_halt(20000); //待机20s后重启设备
获取低功耗策略
pm_policy_t pm_get_policy(void);
获取低功耗的策略
- 返回值:
- 成功,返回低功耗的策略,失败返回LPM_POLICY_NO_POWER_SAVE
其它
SOC对接接口
使用者为低功耗管理模块,具体实现在各自的平台代码中。 SOC的低功耗模式可能各种各样,YoC低功耗管理模块不会限定SOC的低功耗模式,所以在SOC对接层实现各自的低功耗模式。
int sys_soc_init(void)
初始化soc lpm相关资源
int sys_soc_suspend(pm_ctx_t *pm_ctx)
soc 进入低功耗状态
int sys_soc_resume(pm_ctx_t *pm_ctx, int pm_state)
soc 从低功耗状态恢复
低功耗模块对于驱动编写的要求
实现设备驱动的低功耗接口
实现driver_t结构体的lpm接口,一个设备包含了四种电源模式,分别为
#define DEVICE_PM_ACTIVE_STATE 1 // 正常运行
#define DEVICE_PM_LOW_POWER_STATE 2
#define DEVICE_PM_SUSPEND_STATE 3 // 深度睡眠时挂起这个设备,唤醒后可继续运行
#define DEVICE_PM_OFF_STATE 4 // 关闭设备电源
标识设备是否繁忙
设置dev_t结构体的busy变量,如果设备正在传输数据,设置busy为1,否则为0