Zephyr的Power Management
1 关于Zephyr
Zephyr是Linux基金会维护的微内核项目,来源于WindRiver向Zephyr捐赠的Rocket RTOS内核。主要用于开发针对物联网设备的实时操作系统。
Zephyr操作系统很小、具有扩展性并且专为小型物联网设备设计,它的模块化设计使不论采用哪个架构创建物联网方案,都能满足所有设备的需求。
相关资源:
Zephyr官网提供了相关帮助文档,并且在github维护了Zephyr Kernel和Zephyr SDK Tools。
2 Zephyr的Power Management介绍
参考Zephyr的Power Management帮助文档总结如下。
首先对Zephyr功耗管理相关属于进行了介绍Terminology,然后是对Zephyr功耗管理总体介绍Overview,包括Tickless Idle、系统层面的功耗管理System Power Management和设备功耗管理Device Power Management Infrastructure。
平台级的功耗机制Power Schemes包括两种SYS_PM_LOW_POWER_STATE和SYS_PM_DEEP_SLEEP两种。
最后是对Zephyr功耗管理配置Power Management Configuration Flags包括一个总开关CONFIG_SYS_POWER_MANAGEMENT和针对Tickless Idle、SoC和Device的配置。
Power Management APIs单独对System和Device相关API进行了介绍。
2.1 相关术语
CPU LPS(Low Power State):可以指任何CPU支持的低功耗状态。
Deep SLeep State:此时CPU供电被切断并且会丢失执行上下文,大部分外设被断电,RAM可能处于自刷新状态。
Idle Thread:在所有其他线程都不运行时,进入Idle线程。这里面进行了低功耗相关处理。
Power Gating:通过关闭不被使用模块的供电来达到降低功耗。
2.2 概述
Zephyr的PM子系统采用了分层思想,剥离特定架构和SoC相关部分,提取公共部分作为核心。SoC特殊部分被抽象到HAL层。
Zephyr的功耗管理主要分为三部分:Tickless Idle、System Power Management和Device Power Management。
2.3 Tickless Idle
Zephyr的调度器可以运行在两种模式。
在有线程执行的正常模式,使用周期性定时器,调度器运行在周期调度模式。
当Idle线程被调度到的时候,idle线程会将定时器修改成单次触发模式,并将睡眠值取最近一次timeout值。
这就保证在timeout超时之前调度器已经进入周期性工作模式。
Zephyr(Cortex-M) 初始化的时候创建了idle线程,idle线程是系统功耗处理的主要入口。
_PrepC(reset.S)-->
_Cstart(prep_c.c)-->
prepare_multithreading(init.c)-->初始化内核数据结构,包括main/idle线程以及架构相关初始化
_IntLibInit
_main
idle(idle.c)-->idle线程函数
_sys_power_save_idle-->
_sys_soc_suspend-->
initialize_timeouts
kernel_arch_init
switch_to_main_thread(init.c)-->
_sys_power_save_idle的参数是系统最近一次timer超时tick数。这个参数通过_get_next_timeout_expiry获取。
/* find the closest deadline in the timeout queue */ static inline s32_t _get_next_timeout_expiry(void)
{
struct _timeout *t = (struct _timeout *)
sys_dlist_peek_head(&_timeout_q);------------从_timeout_q获取最近一次timer的_timeout return t ? t->delta_ticks_from_prev : K_FOREVER;
}
2.4 System Power Management
系统进入退出退出Idle的时候,会调用相关钩子函数进行suspend/resume处理。
2.4.1 进入低功耗模式
_sys_soc_suspend是进入系统级低功耗的入口,入参是idle可以持续时间。
里面具体的实现是SoC相关的,根据SoC的特性采取不同的睡眠策略,在某些情况下甚至需要关闭外设。
一般情况下都会在真正睡眠前,设置一个唤醒事件,然后才会进入睡眠。
prepare_multithreading-->
idle-->Idle线程
_sys_power_save_idle-->
_sys_soc_suspend-->SoC相关低功耗钩子函数
__sys_soc_suspend的实现一般根据可睡眠时间来决定睡眠状态,时间长可以进入深度睡眠。
Parameters
ticks: the upcoming kernel idle time
Return Value
SYS_PM_NOT_HANDLED: If low power state was not entered.
SYS_PM_LOW_POWER_STATE: If CPU low power state was entered.
SYS_PM_DEEP_SLEEP: If SOC low power state was entered.
2.4.2 退出低功耗模式
_sys_soc_resume和_sys_soc_resume_from_deep_sleep是两个弱类型钩子函数,都是在退出低功耗模式时回调。
_sys_soc_resume是否执行要根据_sys_pm_idle_exit_notify是否有效,在_sys_soc_suspend返回SYS_PM_NOT_HANDLED情况下需要进行特殊处理。
_timer_int_handler-->
_arch_isr_direct_pm-->
_isr_wrapper-->
_sys_power_save_idle_exit-->
_sys_soc_resume
_sys_soc_pm_idle_exit_notification_disable用于关闭退出低功耗模式通知。
系统级别的低功耗模式有三种:
状态 | 注释 |
SYS_PM_ACTIVE_STATE | 正常工作状态。 |
SYS_PM_LOW_POWER_STATE | 浅度低功耗模式,CPU上下文没有丢失。 |
SYS_PM_DEEP_SLEEP | 深度低功耗模式,CPU会被断电,并且需要保存恢复上下文。甚至需要关闭外设。 |
2.5 Device Power Management Infrastructure
Zephyr关于设备的功耗管理有两种方式:一种是各设备自觉维护的分布式方式,另一种是在suspend过程中对所有设备进行suspend处理的集中管理方式。
每个设备自觉维护本身的低功耗状态,不但在系统运行时更加节省功耗,同时也能加速系统进入suspend状态的流程。
设备的低功耗状态有四种:
状态 | 注释 |
DEVICE_PM_ACTIVE_STATE | 正常工作模式,设备上下文都保持。 |
DEVICE_PM_LOW_POWER_STATE | 设备自身维护设备上下文,不需要驱动恢复。 |
DEVICE_PM_SUSPEND_STATE | 设备丢失上下文,驱动需要保存然后恢复上下文。 |
DEVICE_PM_OFF_STATE | 对设备断电,上下文丢失,需要重新初始化设备。 |
Device Model with Power Management Support
在注册设备的时候,如果使能Device PM的话,需要实现功耗处理函数。
DEVICE_DEFINE在初始化驱动的时候填充pm_control_fn,就提供了设备功耗管理的接口。
如果设备不需要功耗管理接口,使用DEVICE_AND_API_INIT。默认功耗接口就是一个空函数device_pm_control_nop。
#define DEVICE_DEFINE(dev_name, drv_name, init_fn, pm_control_fn, \
data, cfg_info, level, prio, api) \
\
static struct device_config _CONCAT(__config_, dev_name) __used \
__attribute__((__section__(".devconfig.init"))) = { \
.name = drv_name, .init = (init_fn), \
.device_pm_control = (pm_control_fn), \
.config_info = (cfg_info) \
}; \
static struct device _CONCAT(__device_, dev_name) __used \
__attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \
.config = &_CONCAT(__config_, dev_name), \
.driver_api = api, \
.driver_data = data \
} struct device_config {
char *name;
int (*init)(struct device *device);
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
int (*device_pm_control)(struct device *device, u32_t command,
void *context);
#endif
const void *config_info;
};
每个驱动都需要实现device_pm_control,其中command是DEVICE_PM_SET_POWER_STATE或者DEVICE_PM_GET_POWER_STATE,用于设置或者获取当前设备功耗状态。context是device的功耗状态。
Device Power Management API
获取当前系统设备列表:
void device_list_get(struct device **device_list, int *device_count)
设置当前设备状态:
int device_set_power_state(struct device *device, u32_t device_power_state);
获取当前设备状态:
int device_get_power_state(struct device *device, u32_t * device_power_state);
其他相关API:
void device_busy_set(struct device *busy_dev)----------置当前设备忙位
void device_busy_clear(struct device *busy_dev)--------清当前设备忙位
int device_any_busy_check(void)------------------------检查所有设备忙状态
int device_busy_check(struct device *chk_dev)----------检查当前设备忙位
2.6 Zephyr PM配置
Flag | 解释 |
CONFIG_SYS_POWER_MANAGEMENT | 功耗管理子系统的开关 |
CONFIG_TICKLESS_IDLE | Tickless Idle功能开关 |
CONFIG_SYS_POWER_LOW_POWER_STATE | SYS_PM_LOW_POWER_STATE机制的开关 |
CONFIG_SYS_POWER_DEEP_SLEEP | SYS_PM_DEEP_SLEEP 机制的开关 |
CONFIG_DEVICE_POWER_MANAGEMENT | 各种外设的低功耗管理开关 |
3 其他相关资料
Zephyr Project Document 1.3.0介绍了Zephyr的开发环境、内核以及应用程序开发方方面面。
Zephyr的Power Management的更多相关文章
- Power Management开发的一般流程
本文作为一个提纲挈领的介绍性文档,后面会以此展开,逐渐丰富. 开发流程 针对一个PM feature进行开发,设计模型是第一步.模型设计好之后,还要保留参数接口,可以基于这些参数针对特殊个体进行优化. ...
- Linux下Power Management开发总结
本文作为一个提纲挈领的介绍性文档,后面会以此展开,逐渐丰富. 1. 前言 在 <开发流程>中介绍了PM开发的一般流程,重点是好的模型.简单有效的接口参数.可量化的测试环境以及可独性强的输出 ...
- System and Device power management.
Advanced Configuration and Power Management Interface(ACPI)是由Intel,Microsoft等厂家订的一套Spec,规范了OS,APP对于电 ...
- PatentTips - Power management implementation in an optical link
BACKGROUND INFORMATION Embodiments of the present invention are directed to optical links and, more ...
- Power management in semiconductor memory system
A method for operating a memory module device. The method can include transferring a chip select, co ...
- Power Management of Hybrid DRAM/PRAM-Based Main Memory
0.ABSTRACT (1)non-volatile memory——low standby power DRAM——high performance and better active power ...
- Xen之初体验:XenMotion、 StorageMotion、Site Recovery、Power Management 各种新、高级功能免费
Xenserver 的新版本6.2现在已经全面开源,省掉了原有的序列号,也能免费体验曾经标题中的付费高级功能. 安装镜像:http://downloadns.citrix.com.edgesuite. ...
- Hackintosh Power Management
Also, be aware that hibernation (suspend to disk or S4 sleep) is not supported on hackintosh. You sh ...
- Device Drivers Should Not Do Power Management
有人对现有的电源管理提出了意见,认为驱动程序不应该做电源管理,paper地址在这里: http://www.ruf.rice.edu/~mobile/publications/xu2014apsys. ...
随机推荐
- 微信小程序 数组索引 data-“”解释
按照官方最新文档循环的方式,索引值是以 wx:for-index="index" 方式写的, 以 parseInt(event.currentTarget.dataset.i ...
- ionic 项目签名
一.ionic 自动签名的好处与坏处(ionic build android/ios) 好处在于:可以直接安装手机上进行安装测试,也可以上传Android或者iOS平台 不好的地方在于:你的电脑环境 ...
- Android 高德地图定位
创建Key 打开高德开发平台 → 我的应用 → 创建应用 → 创建新Key 说明: 1.发布版安全码获取:用自己的签名打包成apk安装软件,用SHA1工具查看 2.调试版安全码获取: 直接运行安装软件 ...
- Django中ORM介绍和字段及字段参数 Object Relational Mapping(ORM)
Django中ORM介绍和字段及字段参数 Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简 ...
- [20180413]热备模式相关问题2.txt
[20180413]热备模式相关问题2.txt --//上午测试热备模式相关问题,就是如果打开热备模式,如果中间的归档丢失,oracle在alter database end backup ;时并 ...
- sql server全文索引使用中的小坑 (转载)
一.业务场景 我们在实际生产环境中遇到了这样一种需求,即需要检索一个父子关系的子树数据 估计大家也遇到过类似的场景,最典型的就是省市数据,其中path字段是按层级关系生成的行政区路径: 如果我们已知某 ...
- SQL Server 临时表和表变量系列之选择篇
原文地址:https://yq.aliyun.com/articles/69187 摘要: # 摘要 通过前面的三篇系列文章,我们对临时表和表变量的概念.对比和认知误区已经有了非常全面的认识.其实,我 ...
- sql server 如何查询出数据库作业所有者的信息并完成批量替换
今天数据库对入职一年的我建立了独立的数据库账号,之前我是和其他同事共享的,之前的所有者账号被废弃了,这时导致很多数据库作业执行失败. 下面是说明如何把之前所有的作业的所有者替换成正在使用的账号: 下面 ...
- Android (checkBox)
1.使用 setOnCheckedChangeListener()方法对checkBox进行事件监听 2.重写方法 public void onCheckedChanged(CompoundButto ...
- git merge 步骤
这两天用git比较多,自己学习的过程踩了不少误区,特意记录下来. 当多人合作开发使用git作为代码管理仓库时,要注意自己的更新不能冲掉别人的更新,因为自己一开始不了解的时候就出现了这种情况.首先一定要 ...