|
ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
|
Pluggable monotonic clock for all library timing. More...
#include "protocore_config.h"Go to the source code of this file.
Classes | |
| struct | ClockSrcArgs |
Install a custom clock running at ticks_per_second; the library divides it down to its internal 1000 Hz. Pass (NULL, 0) to revert to the platform default. More... | |
| struct | ClockNs |
| struct | protocore_latency_stat |
| Rolling latency statistics in microseconds: sample count, min / max / mean, and how many samples blew a budget. Fixed size, no heap; a subsystem (the preempting queue, a DMA path, a forwarding rule) keeps one and reports it for real-time visibility. More... | |
Functions | |
| PROTOCORE_INLINE void | pcdelay (uint32_t ms) |
| The library's monotonic time at 1000 Hz (milliseconds). | |
| PROTOCORE_INLINE void | protocore_delay_us (uint32_t us) |
Install a custom microsecond clock running at ticks_per_second; the library divides it down to 1 MHz. Pass (NULL, 0) for the platform default. | |
| PROTOCORE_INLINE void | protocore_lat_reset (protocore_latency_stat *s) |
| Zero a stat (min seeded high so the first sample sets it). | |
| PROTOCORE_INLINE uint32_t | protocore_lat_begin (void) |
| Start of a measured span: capture the current microsecond time. | |
| PROTOCORE_INLINE void | protocore_lat_end (protocore_latency_stat *s, uint32_t start_us, uint32_t budget_us) |
End of a span started at start_us: record its latency, counting it as over-budget when budget_us is non-zero and exceeded. Wrap-safe. | |
| PROTOCORE_INLINE uint32_t | protocore_lat_avg_us (const protocore_latency_stat *s) |
| Mean latency (us) over the recorded samples, 0 if none. | |
| PROTOCORE_INLINE uint32_t | protocore_cycles_to_ns (uint32_t delta_cycles, uint32_t cpu_mhz) |
Free-running CPU cycle count. ISR-safe. On a part that has one this is the hardware cycle counter; on host it falls back to protocore_micros() scaled by host_fallback_mhz (a coarse stand-in - override with a real cycle source in a host test that needs nanosecond precision). | |
Variables | |
| PROTOCORE_BEGIN_DECLS typedef uint32_t(* | protocore_clock_fn )(void) |
| User clock: returns a free-running monotonic tick count. | |
| ClockNs | Clock |
| The one symbol this module exports. | |
Pluggable monotonic clock for all library timing.
The library's internal timing runs at 1000 Hz - one tick is one millisecond, the cadence the test suite asserts and every timeout / poll is expressed in. Clock.millis() is that single time source, leaving the reading in Clock.ms; by default it is the platform millis().
To drive the library from your own clock (a hardware timer, an external RTC, a simulation clock), call:
Clock.src.fn = my_clock_fn; Clock.src.ticks_per_second = my_ticks_per_second; Clock.set_ms(Clock.internal);
Your clock reports a free-running tick count at ticks_per_second. The library divides it down to its internal 1000 Hz, so timeouts and polling keep the exact 1 ms granularity the tests verify regardless of how fast your clock runs. Pass a rate >= 1000, ideally a multiple of 1000 for exact division (e.g. a 1 MHz timer -> ticks_per_second = 1000000, divided by 1000). Pass NULL to revert to the platform default. One source covers everything - swap it once and every subsystem follows.
The worker poll cadence is fixed at 1000 Hz (the tested default); a build can trade latency for idle power with PROTOCORE_WORKER_POLL_TICKS - see protocore_config.h.
The installed clocks live in clock.c, one instance for the whole program, so a build that reads the clock links that translation unit.
Definition in file clock.h.
| PROTOCORE_INLINE void pcdelay | ( | uint32_t | ms | ) |
| PROTOCORE_INLINE void protocore_delay_us | ( | uint32_t | us | ) |
Install a custom microsecond clock running at ticks_per_second; the library divides it down to 1 MHz. Pass (NULL, 0) for the platform default.
Monotonic microseconds - the high-resolution time base for ISR timestamps and sub-millisecond latency. Safe to call from an ISR. Wraps roughly every 71 minutes, so use it only for short deltas (unsigned subtraction is wrap-safe).
Block for at least us microseconds of REAL time - a hardware settle.
pcdelay sleeps the task one RTOS tick at a time and a tick is a millisecond, so it cannot express a shorter wait: asking it for 500 us waits 1 ms.
This reads ::protocore_platform_micros, the raw counter, and NOT ::protocore_micros. The library clock is pluggable: an application can install one that runs at its own rate, and a test can install one it steps by hand. A part that needs 500 us to settle needs 500 us of real time, so a clock the application controls cannot be what decides when the wait ends - against a stepped clock this returns at once or never returns. The subtraction is unsigned, so the counter's wrap is safe.
This SPINS: it does not yield, and nothing else on the core runs while it does. That holds only where the wait is part of bringing a device up. On the request path it stalls handle() for its whole duration, which the pump's latency budget then records.
| PROTOCORE_INLINE void protocore_lat_reset | ( | protocore_latency_stat * | s | ) |
Zero a stat (min seeded high so the first sample sets it).
Definition at line 181 of file clock.h.
References protocore_latency_stat::count, protocore_latency_stat::max_us, protocore_latency_stat::min_us, protocore_latency_stat::over_budget, and protocore_latency_stat::sum_us.
| PROTOCORE_INLINE uint32_t protocore_lat_begin | ( | void | ) |
Start of a measured span: capture the current microsecond time.
Definition at line 191 of file clock.h.
References Clock, ClockNs::internal, ClockNs::micros, and ClockNs::us.
| PROTOCORE_INLINE void protocore_lat_end | ( | protocore_latency_stat * | s, |
| uint32_t | start_us, | ||
| uint32_t | budget_us | ||
| ) |
End of a span started at start_us: record its latency, counting it as over-budget when budget_us is non-zero and exceeded. Wrap-safe.
Definition at line 201 of file clock.h.
References Clock, protocore_latency_stat::count, ClockNs::internal, protocore_latency_stat::max_us, ClockNs::micros, protocore_latency_stat::min_us, protocore_latency_stat::over_budget, protocore_latency_stat::sum_us, and ClockNs::us.
| PROTOCORE_INLINE uint32_t protocore_lat_avg_us | ( | const protocore_latency_stat * | s | ) |
Mean latency (us) over the recorded samples, 0 if none.
Definition at line 222 of file clock.h.
References protocore_latency_stat::count, and protocore_latency_stat::sum_us.
| PROTOCORE_INLINE uint32_t protocore_cycles_to_ns | ( | uint32_t | delta_cycles, |
| uint32_t | cpu_mhz | ||
| ) |
Free-running CPU cycle count. ISR-safe. On a part that has one this is the hardware cycle counter; on host it falls back to protocore_micros() scaled by host_fallback_mhz (a coarse stand-in - override with a real cycle source in a host test that needs nanosecond precision).
Convert a cycle-count delta to nanoseconds at cpu_mhz (the running CPU frequency, as the platform reports it). delta_cycles must come from a wrap-safe unsigned subtraction of two protocore_cycles() reads.
| PROTOCORE_BEGIN_DECLS typedef uint32_t(* protocore_clock_fn) (void) | ( | void | ) |
|
extern |
The one symbol this module exports.
Referenced by protocore_lat_begin(), and protocore_lat_end().