简介

设备电源管理由设备驱动程序模型的接口组成。系统提供API设备驱动程序发送控制命令,以更新其电源状态获取其当前电源状态
Zephyr RTOS支持两种进行设备电源管理的方法。

  • 运行时设备电源管理
  • 系统电源管理

运行时设备电源管理

其实就是设备驱动自身来维护自己是否需要进入省电模式,而不需要通过应用程序进行参与,但应用程序可以决定设备是否可以启用运行时设备电源管理。

系统电源管理

设备的系统电源管理其实就是在进行系统电源管理的时候同时将设备也进行管理。

忙碌状态指示

如果设备此时正在进行操作,那由于设备电源管理导致设备进入了休眠状态,此时可能导致设备的数据丢失,更加糟糕的是可能导致系统死机。因此Zephyr给我们提供了API,可以控制设备的忙碌标志,当设备忙碌标志设置的时候,那么此设备就无法进入休眠状态。

  1. /**
  2. * @brief Indicate that the device is in the middle of a transaction
  3. *
  4. * Called by a device driver to indicate that it is in the middle of a
  5. * transaction.
  6. *
  7. * @param dev Pointer to device structure of the driver instance.
  8. */
  9. void pm_device_busy_set(const struct device *dev);
  10. /**
  11. * @brief Indicate that the device has completed its transaction
  12. *
  13. * Called by a device driver to indicate the end of a transaction.
  14. *
  15. * @param dev Pointer to device structure of the driver instance.
  16. */
  17. void pm_device_busy_clear(const struct device *dev);
  18. /**
  19. * @brief Check if any device is in the middle of a transaction
  20. *
  21. * Called by an application to see if any device is in the middle
  22. * of a critical transaction that cannot be interrupted.
  23. *
  24. * @retval false if no device is busy
  25. * @retval true if any device is busy
  26. */
  27. bool pm_device_is_any_busy(void);
  28. /**
  29. * @brief Check if a specific device is in the middle of a transaction
  30. *
  31. * Called by an application to see if a particular device is in the
  32. * middle of a critical transaction that cannot be interrupted.
  33. *
  34. * @param dev Pointer to device structure of the specific device driver
  35. * the caller is interested in.
  36. * @retval false if the device is not busy
  37. * @retval true if the device is busy
  38. */
  39. bool pm_device_is_busy(const struct device *dev);
  • pm_device_busy_set: 设置设备忙碌标志
  • pm_device_busy_clear:清除设备忙碌标志
  • pm_device_is_any_busy:检查任何设备的忙碌标志
  • pm_device_is_busy:检查设备的忙碌标志

设备的唤醒功能

某些设备能够将系统从睡眠状态唤醒。当设备具有此类功能时,应用程序可以使用pm_device_wakeup_enable()在设备上动态启用禁用此功能。
也可以在设备树设备节点中声明wakeup-source属性,来表明此设备可以唤醒系统。例如:

  1. gpio0: gpio@40022000 {
  2. compatible = "ti,cc13xx-cc26xx-gpio";
  3. reg = <0x40022000 0x400>;
  4. interrupts = <0 0>;
  5. status = "disabled";
  6. label = "GPIO_0";
  7. gpio-controller;
  8. wakeup-source;
  9. #gpio-cells = <2>;
  10. };

应用程序可以在以后调用pm_device_wakeup_enable()来让设备唤醒系统。

电源域

这个电源域的概念其实就是当一个电源芯片上外接了很多的设备,此时如果只将电源芯片进行休眠,那外部设备此时并没有休眠,那么就可能导致一些问题的发生,但如果说我将外部设备休眠后在来休眠电源芯片,那程序的设计复杂度就会很高,那么这个时候电源域就有用处了,比如说我将电源芯片设置成一个域,外围设备都是这个域内的成员,那么当电源芯片休眠的时候,外围设备也会调用休眠函数;当电源设备恢复的时候,外围设备也会调用。虽然这个例子并不能完全说明域的概念。
在启用CONFIG_PM_DEVICE_RUNTIME后,每次挂起恢复设备时,都会在设备所属的域中执行相同的操作。