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

Power-profiling helper – implementation. More...

#include "ra8_power_profile.h"
#include <string.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_log.h"
Include dependency graph for ra8_power_profile.c:

Go to the source code of this file.

Macros

#define RA8_POWER_PROFILE_TAG   "PWRPROF"
 Logging tag passed to ra8_log_* from this TU.

Functions

static ra8_err_t internal_validate_region (ra8_power_profile_region_id_t region_id)
 Validate a region ID against the static array bound.
static uint64_t internal_now_us (void)
 Read the current timestamp via the configured clock hook.
static void internal_fire_pulse (ra8_power_profile_region_id_t region_id, bool entering)
 Fire the GPIO pulse hook if one was configured.
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).

Variables

static bool s_initialized = false
 Module initialisation flag.
static ra8_power_profile_config_t s_cfg = {}
 Cached copy of the caller-supplied configuration.
static ra8_power_profile_stats_t s_stats = {}
 Per-region accumulator array (NASA Rule 3 – static).

Detailed Description

Power-profiling helper – implementation.

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

See ra8_power_profile.h for the public contract. The implementation is a flat array of accumulators plus two function-pointer hooks (GPIO pulse, microsecond clock). Nothing in this file touches the RA8D2 register map directly; that decoupling keeps the helper trivially testable on the host.

Definition in file ra8_power_profile.c.

Macro Definition Documentation

◆ RA8_POWER_PROFILE_TAG

#define RA8_POWER_PROFILE_TAG   "PWRPROF"

Logging tag passed to ra8_log_* from this TU.

Centralised so all log lines emitted by the profiler use a single, grep-friendly prefix. Allowed by CLAUDE.md "Constants and Macros" because it deduplicates the same string literal across multiple callsites.

Since
0.1.0

Definition at line 40 of file ra8_power_profile.c.

Referenced by internal_validate_region(), ra8_power_profile_get_stats(), ra8_power_profile_init(), ra8_power_profile_mark_enter(), ra8_power_profile_mark_exit(), and ra8_power_profile_reset_stats().

Function Documentation

◆ internal_fire_pulse()

void internal_fire_pulse ( ra8_power_profile_region_id_t region_id,
bool entering )
static

Fire the GPIO pulse hook if one was configured.

Wrapper around the function-pointer dispatch so the public APIs can call a single helper instead of repeating the null guard.

Parameters
[in]region_idRegion whose edge is being marked.
[in]enteringtrue for an enter edge, false for exit.
Precondition
Module is initialized.
Postcondition
Either the hook ran exactly once, or no hook was configured.
Note
Internal helper; not exported.
Since
0.1.0
Precondition
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.

Definition at line 175 of file ra8_power_profile.c.

References RA8_INTERNAL, and s_cfg.

Referenced by ra8_power_profile_mark_enter(), and ra8_power_profile_mark_exit().

◆ internal_now_us()

uint64_t internal_now_us ( void )
static

Read the current timestamp via the configured clock hook.

Returns 0 if no clock hook was supplied. Centralising the null check here keeps the enter/exit fast paths free of branches that never change after init.

Returns
Current monotonic timestamp in microseconds, or 0 if no clock hook was configured.
Precondition
Module is initialized.
Postcondition
Return value is monotonically non-decreasing across calls.
Note
Internal helper; not exported.
Since
0.1.0
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.

Definition at line 148 of file ra8_power_profile.c.

References RA8_INTERNAL, and s_cfg.

Referenced by ra8_power_profile_mark_enter(), and ra8_power_profile_mark_exit().

◆ internal_validate_region()

ra8_err_t internal_validate_region ( ra8_power_profile_region_id_t region_id)
static

Validate a region ID against the static array bound.

Pulled out of the public API path so each entry point has the same single-source-of-truth bounds check, and so coverage of the out-of-range branch only needs to be exercised once.

Parameters
[in]region_idRegion identifier to validate.
Returns
ra8_err_t Error code.
Return values
k_ra8_okregion_id is in range.
k_ra8_err_range_check_failedregion_id is out of range.
Precondition
None.
Postcondition
Return value is one of the documented retvals.
Note
Internal helper; not exported.
Since
0.1.0
Precondition
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.

Definition at line 118 of file ra8_power_profile.c.

References k_ra8_err_range_check_failed, k_ra8_ok, k_ra8_power_profile_max_regions, RA8_INTERNAL, ra8_log_error, and RA8_POWER_PROFILE_TAG.

Referenced by ra8_power_profile_mark_enter(), and ra8_power_profile_mark_exit().

◆ 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.

Variable Documentation

◆ s_cfg

ra8_power_profile_config_t s_cfg = {}
static

Cached copy of the caller-supplied configuration.

Holds the GPIO pulse hook, microsecond-clock hook, and the two opaque user contexts. Copied verbatim from ra8_power_profile_init's argument so the caller is free to release the source buffer afterwards.

Note
File-scope, accessed only after s_initialized == true.
Warning
Do not modify outside ra8_power_profile_init.
Since
0.1.0

Definition at line 75 of file ra8_power_profile.c.

Referenced by internal_fire_pulse(), internal_now_us(), main(), and ra8_power_profile_init().

◆ s_initialized

bool s_initialized = false
static

Module initialisation flag.

Set to true by ra8_power_profile_init and never cleared. Every public API except init rejects calls when this is false via RA8_VALIDATE_INIT.

Note
Single-threaded access only – the entire profiler API is documented as not thread-safe.
Warning
Direct modification by other TUs is forbidden; use the public ra8_power_profile_init entry point.
Since
0.1.0

Definition at line 58 of file ra8_power_profile.c.

◆ s_stats

ra8_power_profile_stats_t s_stats = {}
static

Per-region accumulator array (NASA Rule 3 – static).

Indexed by ra8_power_profile_region_id_t value. Capacity is k_ra8_power_profile_max_regions (16) so the entire structure fits well within Cortex-M85 SRAM with room to spare.

Invariant
For every index, entries >= exits.
Note
File-scope, single-threaded access only.
Warning
Reset via ra8_power_profile_reset_stats, not by direct modification.
Since
0.1.0

Definition at line 93 of file ra8_power_profile.c.

Referenced by ra8_power_profile_get_stats(), ra8_power_profile_init(), ra8_power_profile_mark_enter(), ra8_power_profile_mark_exit(), and ra8_power_profile_reset_stats().