ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_power_profile.h File Reference

Power-profiling helper – public API. More...

#include <stdint.h>
#include "ra8_err.h"
Include dependency graph for ra8_power_profile.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_power_profile_region_stats_t
 Per-region accumulator returned by ra8_power_profile_get_stats. More...
struct  ra8_power_profile_stats_t
 Aggregate snapshot of all per-region accumulators. More...
struct  ra8_power_profile_config_t
 Initialisation configuration. More...

Typedefs

typedef void(* ra8_power_profile_gpio_pulse_fn_t) (void *ctx, ra8_power_profile_region_id_t region_id, bool entering)
 GPIO-toggle hook used to emit profiler edges.
typedef uint64_t(* ra8_power_profile_now_us_fn_t) (void *ctx)
 Wall-clock timestamp hook (microseconds since some epoch).

Enumerations

enum  ra8_power_profile_limits_t : uint8_t { k_ra8_power_profile_max_regions = 16 }
 Static sizing constants for the profiler. More...
enum  ra8_power_profile_region_id_t : uint8_t {
  k_ra8_power_profile_region_active = 0 ,
  k_ra8_power_profile_region_sleep = 1 ,
  k_ra8_power_profile_region_software_standby = 2 ,
  k_ra8_power_profile_region_deep_standby = 3 ,
  k_ra8_power_profile_region_snooze = 4 ,
  k_ra8_power_profile_region_user_0 = 5
}
 Default named region IDs. More...

Functions

ra8_err_t ra8_power_profile_init (const ra8_power_profile_config_t *cfg)
 Initialise the power profiler.
ra8_err_t ra8_power_profile_mark_enter (ra8_power_profile_region_id_t region_id)
 Mark entry into a tracked region.
ra8_err_t ra8_power_profile_mark_exit (ra8_power_profile_region_id_t region_id)
 Mark exit from a tracked region.
ra8_err_t ra8_power_profile_get_stats (ra8_power_profile_stats_t *out_stats)
 Copy the current statistics snapshot to the caller.
ra8_err_t ra8_power_profile_reset_stats (void)
 Zero every accumulator (preserves the configured hooks).

Detailed Description

Power-profiling helper – public API.

Tag
[Ring 4 / Service] {World: NS}

Lightweight Dynamic-Trace-Style (DTS) power-profiling helper. The library lets application code wrap regions of execution with ra8_power_profile_mark_enter / ra8_power_profile_mark_exit pairs so that an external power analyser (e.g. a Joulescope or a scope+shunt) can correlate measured current draw with named code regions. Each enter/exit edge pulses a configured GPIO so the analyser sees a clean trigger; on the firmware side the helper also accumulates per-region elapsed time and entry counts, which doubles as a coarse wall-clock budget tracker.

The library is decoupled from any concrete GPIO or RTC HAL via function-pointer hooks (Dependency Inversion – see CLAUDE.md "SOLID Principles for C"). Production code wires the hooks to ra8_gpio_* and ra8_rtc_*; unit tests inject mocks. There are no calls into ra8_hal/ from this translation unit.

Layout in this firmware:

Region IDs are a fixed-size C23 typed enum capped at k_ra8_power_profile_max_regions (16) to satisfy NASA Power-of-10 Rule 3 (no dynamic allocation): all per-region counters live in a static array sized at compile time.

Definition in file ra8_power_profile.h.

Typedef Documentation

◆ ra8_power_profile_gpio_pulse_fn_t

typedef void(* ra8_power_profile_gpio_pulse_fn_t) (void *ctx, ra8_power_profile_region_id_t region_id, bool entering)

GPIO-toggle hook used to emit profiler edges.

Called twice per region transition (rising + falling edges) so the external analyser can detect a precise boundary. The implementation is expected to drive a single GPIO pin from the configured pulse level back to the idle level.

Parameters
[in]ctxOpaque hook context (passed through from cfg).
[in]region_idRegion being entered or exited.
[in]enteringtrue if marking entry, false if marking exit.
Note
Must not block. Must be safe to call from the same context as ra8_power_profile_mark_enter / _exit.
Since
0.1.0

Definition at line 106 of file ra8_power_profile.h.

◆ ra8_power_profile_now_us_fn_t

typedef uint64_t(* ra8_power_profile_now_us_fn_t) (void *ctx)

Wall-clock timestamp hook (microseconds since some epoch).

Returns a monotonically non-decreasing 64-bit microsecond timestamp. The profiler subtracts the enter timestamp from the exit timestamp to compute time-in-region. The hook is typically backed by RTC sub-second counters or by AGT/GPT.

Parameters
[in]ctxOpaque hook context (passed through from cfg).
Returns
Current time, in microseconds.
Note
Must be monotonically non-decreasing across calls.
Since
0.1.0

Definition at line 127 of file ra8_power_profile.h.

Enumeration Type Documentation

◆ ra8_power_profile_limits_t

Static sizing constants for the profiler.

Used to bound the per-region accumulator array at compile time (NASA Rule 3). Region IDs must be in [0, k_ra8_power_profile_max_regions).

Invariant
k_ra8_power_profile_max_regions is exactly 16.
See also
ra8_power_profile_region_id_t
Enumerator
k_ra8_power_profile_max_regions 

Maximum number of distinct regions tracked.

Definition at line 61 of file ra8_power_profile.h.

◆ ra8_power_profile_region_id_t

Default named region IDs.

Applications are free to use raw integer values in [0, k_ra8_power_profile_max_regions) instead of these names. The enumeration provides a few suggested labels that match common low-power-mode regions on the RA8D2: active, sleep, software- standby, deep-software-standby, and snooze.

Invariant
Values fit in uint8_t.
Enumerator
k_ra8_power_profile_region_active 

CPU active / running mode.

k_ra8_power_profile_region_sleep 

Sleep mode (CPU clock stopped).

k_ra8_power_profile_region_software_standby 

Software-standby mode.

k_ra8_power_profile_region_deep_standby 

Deep-software-standby mode.

k_ra8_power_profile_region_snooze 

Snooze (peripheral-driven wake).

k_ra8_power_profile_region_user_0 

First freely-assignable user slot.

Definition at line 78 of file ra8_power_profile.h.

Function Documentation

◆ ra8_power_profile_get_stats()

ra8_err_t ra8_power_profile_get_stats ( ra8_power_profile_stats_t * out_stats)

Copy the current statistics snapshot to the caller.

Performs a structure copy of the internal accumulator array. The snapshot reflects all enter/exit calls observed so far, including still-open regions (whose total_time_us has not yet been updated for the current open span).

Parameters
[out]out_statsCaller-supplied buffer to receive the snapshot.
Returns
ra8_err_t Error code.
Return values
k_ra8_okSuccess.
k_ra8_err_null_ptrout_stats is nullptr.
k_ra8_err_not_initializedModule not initialized.
Precondition
Module is initialized.
out_stats is non-NULL.
Postcondition
*out_stats is a consistent snapshot of internal state.
Note
Safe to call between mark_enter / mark_exit pairs.
See also
ra8_power_profile_reset_stats
Since
0.1.0
Postcondition
Caller-visible state matches the documented contract.

Definition at line 239 of file ra8_power_profile.c.

References k_ra8_ok, memcpy(), RA8_CHECK_NULL_PTR, RA8_POWER_PROFILE_TAG, RA8_VALIDATE_INIT, s_initialized, and s_stats.

Referenced by main().

◆ ra8_power_profile_init()

ra8_err_t ra8_power_profile_init ( const ra8_power_profile_config_t * cfg)

Initialise the power profiler.

Stores the supplied hooks, zeroes every per-region accumulator, and marks the module as initialized. Calling ra8_power_profile_init a second time re-initialises (the previous accumulators are discarded). The function never touches hardware directly; all side effects flow through the hooks in cfg.

Algorithm:

  1. Validate cfg is non-NULL.
  2. Copy cfg into the module-static state.
  3. Zero s_stats so subsequent get_stats returns a clean snapshot.
  4. Set s_initialized = true.
Parameters
[in]cfgPointer to a fully-populated config descriptor.
Returns
ra8_err_t Error code.
Return values
k_ra8_okSuccess.
k_ra8_err_null_ptrcfg is nullptr.
Precondition
cfg is non-NULL.
Caller is single-threaded (init context).
Postcondition
The module is initialized.
All per-region accumulators are zeroed.
Note
Not thread-safe. Run from system init.
See also
ra8_power_profile_mark_enter
ra8_power_profile_reset_stats
Since
0.1.0

Definition at line 183 of file ra8_power_profile.c.

References k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_POWER_PROFILE_TAG, s_cfg, s_initialized, and s_stats.

Referenced by pp_demo_modules_or_halt().

◆ ra8_power_profile_mark_enter()

ra8_err_t ra8_power_profile_mark_enter ( ra8_power_profile_region_id_t region_id)

Mark entry into a tracked region.

Pulses the configured GPIO with entering=true and records the current timestamp. If a previous enter for the same region had no matching exit, the previous open timestamp is silently overwritten (the entries counter still increments so the imbalance is detectable in the snapshot).

Algorithm:

  1. Validate module is initialized and region_id is in range.
  2. Increment regions[region_id].entries.
  3. Stamp last_enter_us from the time hook (if any).
  4. Set is_open = true.
  5. Fire the GPIO hook with entering=true (if any).
Parameters
[in]region_idRegion identifier in [0, k_ra8_power_profile_max_regions).
Returns
ra8_err_t Error code.
Return values
k_ra8_okSuccess.
k_ra8_err_not_initializedra8_power_profile_init was not called.
k_ra8_err_range_check_failedregion_id is out of range.
Precondition
Module is initialized.
region_id < k_ra8_power_profile_max_regions.
Postcondition
regions[region_id].entries increased by 1.
regions[region_id].is_open == true.
Note
Not thread-safe – callers must serialise enter/exit per region.
See also
ra8_power_profile_mark_exit
Since
0.1.0

Definition at line 193 of file ra8_power_profile.c.

References ra8_power_profile_region_stats_t::entries, internal_fire_pulse(), internal_now_us(), internal_validate_region(), ra8_power_profile_region_stats_t::is_open, k_ra8_ok, ra8_power_profile_region_stats_t::last_enter_us, RA8_POWER_PROFILE_TAG, RA8_VALIDATE_INIT, s_initialized, and s_stats.

Referenced by pp_demo_cycle_modes().

◆ ra8_power_profile_mark_exit()

ra8_err_t ra8_power_profile_mark_exit ( ra8_power_profile_region_id_t region_id)

Mark exit from a tracked region.

Pulses the configured GPIO with entering=false, computes the elapsed time since the matching mark_enter (using the time hook), and folds the delta into total_time_us. If no enter is outstanding for region_id the function still increments exits and returns k_ra8_err_invalid_state so the caller can surface the imbalance.

Algorithm:

  1. Validate module is initialized and region_id is in range.
  2. Increment regions[region_id].exits.
  3. If region was open, accumulate now - last_enter_us and clear is_open.
  4. Fire the GPIO hook with entering=false (if any).
Parameters
[in]region_idRegion identifier in [0, k_ra8_power_profile_max_regions).
Returns
ra8_err_t Error code.
Return values
k_ra8_okSuccess: matching enter was open.
k_ra8_err_invalid_stateNo matching open enter for this region.
k_ra8_err_not_initializedra8_power_profile_init was not called.
k_ra8_err_range_check_failedregion_id is out of range.
Precondition
Module is initialized.
region_id < k_ra8_power_profile_max_regions.
Postcondition
regions[region_id].exits increased by 1.
regions[region_id].is_open == false.
Note
Not thread-safe – callers must serialise enter/exit per region.
See also
ra8_power_profile_mark_enter
Since
0.1.0

Definition at line 211 of file ra8_power_profile.c.

References ra8_power_profile_region_stats_t::exits, internal_fire_pulse(), internal_now_us(), internal_validate_region(), ra8_power_profile_region_stats_t::is_open, k_ra8_err_invalid_state, k_ra8_ok, ra8_power_profile_region_stats_t::last_enter_us, ra8_log_error, RA8_POWER_PROFILE_TAG, RA8_VALIDATE_INIT, s_initialized, s_stats, and ra8_power_profile_region_stats_t::total_time_us.

Referenced by pp_demo_cycle_modes().

◆ ra8_power_profile_reset_stats()

ra8_err_t ra8_power_profile_reset_stats ( void )

Zero every accumulator (preserves the configured hooks).

Useful between profiling phases when the application wants a fresh window of measurements without paying the cost of a full re-init.

Returns
ra8_err_t Error code.
Return values
k_ra8_okSuccess.
k_ra8_err_not_initializedModule not initialized.
Precondition
Module is initialized.
Postcondition
Every region's entries/exits/total_time_us is 0.
Every region's is_open is false.
Note
Not thread-safe.
Since
0.1.0
Precondition
Module state is consistent.

Definition at line 248 of file ra8_power_profile.c.

References k_ra8_ok, RA8_POWER_PROFILE_TAG, RA8_VALIDATE_INIT, s_initialized, and s_stats.