1 关于Zephyr

Zephyr是Linux基金会维护的微内核项目,来源于WindRiver向Zephyr捐赠的Rocket RTOS内核。主要用于开发针对物联网设备的实时操作系统。

Zephyr操作系统很小、具有扩展性并且专为小型物联网设备设计,它的模块化设计使不论采用哪个架构创建物联网方案,都能满足所有设备的需求。

相关资源:

Zephyr官网提供了相关帮助文档,并且在github维护了Zephyr KernelZephyr 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_STATESYS_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的更多相关文章

  1. Power Management开发的一般流程

    本文作为一个提纲挈领的介绍性文档,后面会以此展开,逐渐丰富. 开发流程 针对一个PM feature进行开发,设计模型是第一步.模型设计好之后,还要保留参数接口,可以基于这些参数针对特殊个体进行优化. ...

  2. Linux下Power Management开发总结

    本文作为一个提纲挈领的介绍性文档,后面会以此展开,逐渐丰富. 1. 前言 在 <开发流程>中介绍了PM开发的一般流程,重点是好的模型.简单有效的接口参数.可量化的测试环境以及可独性强的输出 ...

  3. System and Device power management.

    Advanced Configuration and Power Management Interface(ACPI)是由Intel,Microsoft等厂家订的一套Spec,规范了OS,APP对于电 ...

  4. PatentTips - Power management implementation in an optical link

    BACKGROUND INFORMATION Embodiments of the present invention are directed to optical links and, more ...

  5. Power management in semiconductor memory system

    A method for operating a memory module device. The method can include transferring a chip select, co ...

  6. 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 ...

  7. Xen之初体验:XenMotion、 StorageMotion、Site Recovery、Power Management 各种新、高级功能免费

    Xenserver 的新版本6.2现在已经全面开源,省掉了原有的序列号,也能免费体验曾经标题中的付费高级功能. 安装镜像:http://downloadns.citrix.com.edgesuite. ...

  8. Hackintosh Power Management

    Also, be aware that hibernation (suspend to disk or S4 sleep) is not supported on hackintosh. You sh ...

  9. Device Drivers Should Not Do Power Management

    有人对现有的电源管理提出了意见,认为驱动程序不应该做电源管理,paper地址在这里: http://www.ruf.rice.edu/~mobile/publications/xu2014apsys. ...

随机推荐

  1. 微信小程序 数组索引 data-“”解释

    按照官方最新文档循环的方式,索引值是以  wx:for-index="index" 方式写的, 以   parseInt(event.currentTarget.dataset.i ...

  2. ionic 项目签名

    一.ionic 自动签名的好处与坏处(ionic build android/ios)  好处在于:可以直接安装手机上进行安装测试,也可以上传Android或者iOS平台 不好的地方在于:你的电脑环境 ...

  3. Android 高德地图定位

    创建Key 打开高德开发平台 → 我的应用 → 创建应用 → 创建新Key 说明: 1.发布版安全码获取:用自己的签名打包成apk安装软件,用SHA1工具查看 2.调试版安全码获取: 直接运行安装软件 ...

  4. Django中ORM介绍和字段及字段参数 Object Relational Mapping(ORM)

    Django中ORM介绍和字段及字段参数   Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简 ...

  5. [20180413]热备模式相关问题2.txt

    [20180413]热备模式相关问题2.txt --//上午测试热备模式相关问题,就是如果打开热备模式,如果中间的归档丢失,oracle在alter database end   backup ;时并 ...

  6. sql server全文索引使用中的小坑 (转载)

    一.业务场景 我们在实际生产环境中遇到了这样一种需求,即需要检索一个父子关系的子树数据 估计大家也遇到过类似的场景,最典型的就是省市数据,其中path字段是按层级关系生成的行政区路径: 如果我们已知某 ...

  7. SQL Server 临时表和表变量系列之选择篇

    原文地址:https://yq.aliyun.com/articles/69187 摘要: # 摘要 通过前面的三篇系列文章,我们对临时表和表变量的概念.对比和认知误区已经有了非常全面的认识.其实,我 ...

  8. sql server 如何查询出数据库作业所有者的信息并完成批量替换

    今天数据库对入职一年的我建立了独立的数据库账号,之前我是和其他同事共享的,之前的所有者账号被废弃了,这时导致很多数据库作业执行失败. 下面是说明如何把之前所有的作业的所有者替换成正在使用的账号: 下面 ...

  9. Android (checkBox)

    1.使用 setOnCheckedChangeListener()方法对checkBox进行事件监听 2.重写方法 public void onCheckedChanged(CompoundButto ...

  10. git merge 步骤

    这两天用git比较多,自己学习的过程踩了不少误区,特意记录下来. 当多人合作开发使用git作为代码管理仓库时,要注意自己的更新不能冲掉别人的更新,因为自己一开始不了解的时候就出现了这种情况.首先一定要 ...