RIOT icon indicating copy to clipboard operation
RIOT copied to clipboard

Add Board-Level Power Mangement

Open maribu opened this issue 3 months ago • 3 comments

Motivation

RIOT's PM system only considers MCU power levels. But boards may have external power domains as well, for example:

  1. A CAN transceiver may have an enable pin. Only with the enable pin at the "enable" level, the CAN transceiver will function.
  2. A board may use some MOSFETs to enable/disable the power supply to an external sensor. Using that sensor requires to enable that power domain.
  3. A board may use some MOSFETs to enable/disable the power supply to multiple external sensors at once. Using any of the sensors connected to the same power domain requires enabling that power domain.

The problem is that while it is trivial to implement some board_enable_power_domain_foo() / board_disable_power_domain_foo() for every power domain of the board, actually using this is non trivial:

  1. The board does not know when the hardware is used. It would have to enable the power domains in board_init() and keep them enabled.
  2. An application would know when e.g. it does an saul_read() ... and one could enable/disable the power domains there. However...
    • We ideally want applications to be (as much as possible) board agnostic and not know about board details
    • We ideally want applications to not know about driver and hardware details. But power cycle the hardware without informing the driver of that hardware can cause issue (e.g. because configuration values are lost)
  3. The device driver would know exactly when it requires the hardware to be powered or not. But it (rightfully) has no knowledge about board details

maribu avatar Sep 04 '25 10:09 maribu

Solution Proposal: "Board Power Hooks"

I propose to add for each driver foo to add two functions:

bool board_power_foo_acquire(size_t params_idx); and void board_power_foo_release(size_t params_idx); with the default implementations of:

#if !HAVE_BOARD_POWER_FOO
/**
 * Ensure that the instance @p params_idx of the foo hardware is powered.
 * @param params_idx Index of the *foo* hardware instances (as index in the `foo_params_t` array)
 * @retval true The hardware instance now is powered
 * @retval false The hardware instance could not be powered due to board constraints
 */
static inline bool board_power_foo_acquire(size_t params_idx)
{
    (void)params_idx;
    return true;
}

/**
 * Allow the instance @p params_idx of the foo hardware to unpowered.
 * @param params_idx Index of the *foo* hardware instances (as index in the `foo_params_t` array)
 */
static inline void board_power_foo_release(size_t params_idx)
{
    (void)params_idx;
}
#endif /* !HAVE_BOARD_POWER_FOO */

A board could then provide a custom implementation of those two functions that can be as complex as needed (e.g. having a reference counter for when multiple external devices share the same board power domain or refusing to enable a board power domain when some board power domains are mutually exclusive due to board constraints), or be a trivial gpio_set(BOARD_PWR_ENABLE_FOO_PIN) / gpio_clear(BOARD_PWR_ENABLE_FOO_PIN) when that is sufficient.

A module with helper functions can be added to provide generic infrastructure. E.g. enabling/disabling a MOSFET to power multiple external devices is pretty common, so some references counter + setting (clearing) a MOSFET when the refcount is positive and clearing (setting) it when it reaches zero will be useful to multiple boards.

Pros (please extend)

  • Flexible: No limitations to how complex/sophisticated boards want to be
  • Trivial: It's hard to dump the concept down more
  • No flag day, drivers can be extended as needed

Cons (please extend)

  • No clear road map to completion. Drivers likely end up being extended whenever someone runs into a board that can benefit from it.
  • Code reuse between boards is a bit more involved, board authors need to be aware and use of common infrastructure

maribu avatar Sep 04 '25 10:09 maribu

@gtnoob14: Ping :)

maribu avatar Sep 05 '25 07:09 maribu

im new to open source contributions and i want to contribute to RIOT OS. can you assign me to something so i could work on it

spnirmal avatar Oct 27 '25 11:10 spnirmal