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. JS如何判断一个对象是否为空、是否有某个属性

    一.js判断一个对象是否为空 方法一: let obj1 = {} let obj2 = {a:1} function empty(obj){ for (let key in obj){ return ...

  2. Django Rest framework 之 认证

    django rest framework 官网 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest fra ...

  3. 【转】MySQL:日期函数、时间函数总结(MySQL 5.X)

    转自:http://www.cnblogs.com/she27/articles/1377089.html 一.MySQL 获得当前日期时间 函数1.1 获得当前日期+时间(date + time)函 ...

  4. NoHttp封装--05 文件下载

    xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:la ...

  5. git本地仓库关联多个remote,怎么用本地一个分支向不同remote不同分支推送代码

    我想这个问题,是大家关注的问题,这个问题,我非常关注. 背景:在公司开发项目,我们一般都要把项目推送到公司领导创建的一个远程仓库里边去,但是我们同时也有自己的小仓库,这样的话,如何方便的将我们的代码, ...

  6. python中关于类隐藏属性的三种处理方法

    关于隐藏属性 引子: 当类的属性或者类实例对象的属性隐藏的时候必须通过存取器方法来获取和设置这些隐藏的属性. 例如: def get_name(self,name):     #存取器方法 self. ...

  7. IP地址及子网划分

    1.IP地址 2.子网掩码 网络号全转为1,主机号全转为0,之后再转化为10进制表示. 3.无分类编址

  8. Python零基础学习系列之三--Python编辑器选择

    上一篇文章记录了怎么安装Python环境,同时也成功的在电脑上安装好了Python环境,可以正式开始自己的编程之旅了.但是现在又有头疼的事情,该用什么来写Python程序呢,该用什么来执行Python ...

  9. C# 动态方法和静态方法的区别

    C# 动态方法和静态方法的区别 (转) 动态方法与静态方法的区别: 1,使用方法上的区别:动态方法,在使用时需要先创建实例,才能调用实例方法,而静态方法则不需要,直接使用即可. 示例代码如下:静态方法 ...

  10. ccf题库20170903--Json查询

    题目如下: 试题编号: - 试题名称: JSON查询 时间限制: .0s 内存限制: .0MB 问题描述: 问题描述 JSON (JavaScript Object Notation) 是一种轻量级的 ...