|
ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
|
Pluggable monotonic clock for all library timing. More...
#include <Arduino.h>#include <stdint.h>Go to the source code of this file.
Classes | |
| struct | pc_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... | |
Typedefs | |
| typedef uint32_t(* | pc_clock_fn) (void) |
| User clock: returns a free-running monotonic tick count. | |
Functions | |
| pc_clock_fn & | _pc_clock_fn_ref () |
| uint32_t & | _pc_clock_div_ref () |
| void | pc_set_clock (pc_clock_fn fn, uint32_t ticks_per_second) |
Install a custom clock running at ticks_per_second; the library divides it down to its internal 1000 Hz. Pass (nullptr, 0) to revert to the platform default. | |
| uint32_t | pc_millis (void) |
| The library's monotonic time at 1000 Hz (milliseconds). | |
| void | pcdelay (uint32_t ms) |
Block for at least ms milliseconds - the library's single delay primitive. | |
| pc_clock_fn & | _pc_micros_fn_ref () |
| uint32_t & | _pc_micros_div_ref () |
| void | pc_set_micros_clock (pc_clock_fn fn, uint32_t ticks_per_second) |
Install a custom microsecond clock running at ticks_per_second; the library divides it down to 1 MHz. Pass (nullptr, 0) for the platform default. | |
| uint32_t | pc_micros (void) |
| 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). | |
| void | pc_lat_reset (pc_latency_stat *s) |
| Zero a stat (min seeded high so the first sample sets it). | |
| uint32_t | pc_lat_begin (void) |
| Start of a measured span: capture the current microsecond time. | |
| void | pc_lat_end (pc_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. | |
| uint32_t | pc_lat_avg_us (const pc_latency_stat *s) |
| Mean latency (us) over the recorded samples, 0 if none. | |
| uint32_t | pc_cycles (void) |
Free-running CPU cycle count. ISR-safe. On ARDUINO/ESP32 this is the hardware cycle counter (CCOUNT); on host it falls back to pc_micros() scaled by host_fallback_mhz (a coarse stand-in - override with a real cycle source in a host test that needs nanosecond precision). | |
| uint32_t | pc_cycles_to_ns (uint32_t delta_cycles, uint32_t cpu_mhz) |
Convert a cycle-count delta to nanoseconds at cpu_mhz (the running CPU frequency, e.g. getCpuFrequencyMhz() on ESP32). delta_cycles must come from a wrap-safe unsigned subtraction of two pc_cycles() reads. | |
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. pc_millis() is that single time source; 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:
pc_set_clock(my_clock_fn, my_ticks_per_second);
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 nullptr 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 PC_WORKER_POLL_TICKS - see protocore_config.h.
Header-only (the override state lives in inline-function-local statics, a single instance across the whole program), so there is nothing extra to compile or link.
Definition in file clock.h.
| typedef uint32_t(* pc_clock_fn) (void) |
|
inline |
Definition at line 48 of file clock.h.
Referenced by pc_millis(), and pc_set_clock().
|
inline |
Definition at line 53 of file clock.h.
Referenced by pc_millis(), and pc_set_clock().
|
inline |
Install a custom clock running at ticks_per_second; the library divides it down to its internal 1000 Hz. Pass (nullptr, 0) to revert to the platform default.
Definition at line 64 of file clock.h.
References _pc_clock_div_ref(), and _pc_clock_fn_ref().
|
inline |
The library's monotonic time at 1000 Hz (milliseconds).
Definition at line 71 of file clock.h.
References _pc_clock_div_ref(), and _pc_clock_fn_ref().
Referenced by DeterministicAsyncTCP::check_timeouts(), PC::http_poll_slot(), listener_accept_cb(), lowlevel_recv_cb(), lowlevel_sent_cb(), pc_conn_begin_close(), pc_conn_touch_active(), pc_micros(), pc_ssh_conn_poll(), pcdelay(), PC::service_once(), and ssh_newkeys_complete().
|
inline |
Block for at least ms milliseconds - the library's single delay primitive.
src/ never calls the platform delay() directly; every wait goes through this so timing stays centralized and portable. On device it yields to the RTOS one tick at a time until ms has elapsed on the monotonic clock (so it sleeps the task and feeds the watchdog, never starving the scheduler); on host it spins on the same clock. Measured against pc_millis, so a custom clock governs it too.
Definition at line 89 of file clock.h.
References pc_millis().
|
inline |
Definition at line 120 of file clock.h.
Referenced by pc_micros(), and pc_set_micros_clock().
|
inline |
Definition at line 125 of file clock.h.
Referenced by pc_micros(), and pc_set_micros_clock().
|
inline |
Install a custom microsecond clock running at ticks_per_second; the library divides it down to 1 MHz. Pass (nullptr, 0) for the platform default.
Definition at line 136 of file clock.h.
References _pc_micros_div_ref(), and _pc_micros_fn_ref().
|
inline |
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).
Definition at line 148 of file clock.h.
References _pc_micros_div_ref(), _pc_micros_fn_ref(), and pc_millis().
Referenced by pc_cycles(), pc_lat_begin(), and pc_lat_end().
|
inline |
Zero a stat (min seeded high so the first sample sets it).
Definition at line 182 of file clock.h.
References pc_latency_stat::count, pc_latency_stat::max_us, pc_latency_stat::min_us, pc_latency_stat::over_budget, and pc_latency_stat::sum_us.
|
inline |
Start of a measured span: capture the current microsecond time.
Definition at line 192 of file clock.h.
References pc_micros().
|
inline |
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 pc_latency_stat::count, pc_latency_stat::max_us, pc_latency_stat::min_us, pc_latency_stat::over_budget, pc_micros(), and pc_latency_stat::sum_us.
|
inline |
Mean latency (us) over the recorded samples, 0 if none.
Definition at line 221 of file clock.h.
References pc_latency_stat::count, and pc_latency_stat::sum_us.
|
inline |
Free-running CPU cycle count. ISR-safe. On ARDUINO/ESP32 this is the hardware cycle counter (CCOUNT); on host it falls back to pc_micros() scaled by host_fallback_mhz (a coarse stand-in - override with a real cycle source in a host test that needs nanosecond precision).
Definition at line 248 of file clock.h.
References pc_micros().
|
inline |
Convert a cycle-count delta to nanoseconds at cpu_mhz (the running CPU frequency, e.g. getCpuFrequencyMhz() on ESP32). delta_cycles must come from a wrap-safe unsigned subtraction of two pc_cycles() reads.