简介
Zephyr
电源域是为了支持
由公共源
供电的设备分组
,以通用方式
通知电源状态更改
。Zephyr
上的电源域
是可选的,要启用此功能,必须设置选项CONFIG_PM_DEVICE_POWER_DOMAIN
。
当电源域
自行打开
或关闭
时,电源域
有责任通过PM_DEVICE_ACTION_TURN_ON
或PM_DEVICE_ACTION_TURN_OFF
来通知使用它的所有设备
。
内部电源域
SoC
中的大多数设备都具有独立的电源控制
,可以打开
或关闭
这些控制以降低功耗。但是,存在大量的静态电流泄漏
,仅使用设备电源管理无法控制
。为了解决这个问题,SoC通常被分成几个区域
,将通常一起使用的设备分组
,以便可以完全关闭未使用的区域以消除这种泄漏。这些区域称为电源域
,可以存在于层次结构中,并且可以嵌套
。
外部电源域
SoC外部
的设备可以从SoC主电源
以外的电源供电
。这些外部电源
通常是开关
、稳压器
或专用电源 IC
。可以从同一源为多个设备供电,这种设备分组通常称为电源域
。
电源域示例
首先,在设备树上充当电源域的设备需要声明power-domain
的兼容属性。
gpio_domain: gpio_domain@4 {
compatible = "power-domain";
...
};
电源域设备需要在挂起和恢复的时候通知整个域
。
static int mydomain_pm_action(const struct device *dev,
enum pm_device_action *action)
{
switch (action) {
case PM_DEVICE_ACTION_RESUME:
/* resume the domain */
...
/* notify children domain is now powered */
pm_device_children_action_run(dev, PM_DEVICE_ACTION_TURN_ON, NULL);
break;
case PM_DEVICE_ACTION_SUSPEND:
/* notify children domain is going down */
pm_device_children_action_run(dev, PM_DEVICE_ACTION_TURN_OFF, NULL);
/* suspend the domain */
...
break;
case PM_DEVICE_ACTION_TURN_ON:
/* turn on the domain (e.g. setup control pins to disabled) */
...
break;
case PM_DEVICE_ACTION_TURN_OFF:
/* turn off the domain (e.g. reset control pins to default state) */
...
break;
default:
return -ENOTSUP;
}
return 0;
}
属于此域的设备,需要在设备树中声明域:
&gpio0 {
compatible = "zephyr,gpio-emul";
gpio-controller;
power-domain = <&gpio_domain>;
};
&gpio1 {
compatible = "zephyr,gpio-emul";
gpio-controller;
power-domain = <&gpio_domain>;
};
当域
更改状态时,域下
的所有设备都将收到通知。这些通知
会发送到设备驱动的电源管理函数中。不过,这些通知也可以被忽略。
static int mydev_pm_action(const struct device *dev,
enum pm_device_action *action)
{
switch (action) {
case PM_DEVICE_ACTION_SUSPEND:
/* suspend the device */
...
break;
case PM_DEVICE_ACTION_RESUME:
/* resume the device */
...
break;
case PM_DEVICE_ACTION_TURN_ON:
// 域发出的运行操作
/* configure the device into low power mode */
...
break;
case PM_DEVICE_ACTION_TURN_OFF:
//域发出的挂起操作
/* prepare the device for power down */
...
break;
default:
return -ENOTSUP;
}
return 0;
}