pw_clock_tree#
Clock tree management for embedded devices
Unstable C++17
Constinit compatible: Clock tree elements can be declared as
constinit
Platform independent: Clock tree management sits above the platform layer
Handles complex topologies: Clock tree elements can be used to model complex clock tree topologies
pw_clock_tree
provides class definitions to implement a platform
specific clock tree management solution. By passing the clock tree element
that clocks a particular device to the corresponding device driver, the
device driver can ensure that the clock is only enabled when required to
maximize power savings.
For example the clock tree functionality could be integrated into a uart device driver like this:
1#include "pw_clock_tree/clock_tree.h"
2
3class UartStreamMcuxpresso {
4 public:
It could be initialized and used like this:
1 // Declare the uart clock source
2 ClockSourceUart uart_clock_source;
3 UartStreamMcuxpresso uart(&uart_clock_source);
4
5 // Initialize the uart which enables the uart clock source.
6 PW_TRY(uart.Init());
7 PW_CHECK(uart_clock_source.ref_count() > 0);
8
9 // Do something with uart
10
11 // Deinitialize the uart which disable the uart clock source.
12 uart.Deinit();
Overview#
Pigweed’s clock tree module provides the ability to represent the clock tree of an embedded device, and to manage the individual clocks and clock tree elements.
The Element
abstract base class is the root of the pw_clock_tree class hierarchy, and
represents a single node in the clock tree.
The public (consumer) API includes two basic methods which apply to all clock tree elements:
Acquire()
Release()
The Element
abstract class implements basic reference counting methods
IncRef()
and DecRef()
, but requires derived classes to use the reference
counting methods to properly acquire and release references to clock tree elements.
Three derived abstract classes are defined for Element
:
ElementBlocking
for clock tree elements that might block when acquired or released. Acquiring or releasing such a clock tree element might fail.ElementNonBlockingCannotFail
for clock tree elements that will not block when acquired or released. Acquiring or releasing such a clock tree element will always succeed.ElementNonBlockingMightFail
for clock tree elements that will not block when acquired or released. Acquiring or releasing such a clock tree element might fail.
ElementNonBlockingCannotFail
and ElementsNonBlockingMightFail
elements can
be acquired from an interrupt context.
All classes representing a clock tree element should be implemented as a template and accept
ElementBlocking
, ElementNonBlockingCannotFail
or
ElementNonBlockingMightFail
as a template argument. Only if it is known at compile time
that a clock tree element can only be either blocking or non-blocking, one can directly derive the
class from ElementBlocking
or ElementNonBlockingCannotFail
/
ElementNonBlockingMightFail
, respectively.
For convenience, OptionalElement
represents a null-safe pointer to an
:Element
. This allows drivers to easily support an optional Element
pointer argument.
If it does not point to an Element, then its Acquire()
and Release()
methods
do nothing and return pw::OkStatus()
.
Synchronization#
Element
objects are individually internally synchronized.
ElementBlocking
objects use a Mutex.ElementNonBlockingCannotFail
andElementNonBlockingMightFail
objects use an InterruptSpinLock.