Merged from the three drifted hand-copies in TrackBackFwd, healthy-band-nrf and zephyr_gateway_fwd: - as_u8s(T&) overloads and deferrer (band/hub side) - hexdump, add_overflow, constrain_value_in_range_static, to_mac_string (TrackBackFwd side) - add_overflow now returns std::expected directly instead of the app_result alias; to_mac_string guarded by __cpp_lib_format for GCC 12 toolchains - app_clock.hpp now() selects k_uptime_ticks / esp_timer_get_time via __ZEPHYR__ / ESP_PLATFORM; fixed doc comment (microseconds, not ms) - dropped vestigial esp_err.h/esp_system.h/FreeRTOS.h includes Dual build glue: ESP-IDF component (root CMakeLists) + Zephyr module (zephyr/). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
106 lines
2.3 KiB
C++
106 lines
2.3 KiB
C++
#pragma once
|
|
|
|
#include <chrono>
|
|
#include <cstdint>
|
|
|
|
#include "app_clock.hpp"
|
|
|
|
namespace app::utils {
|
|
/**
|
|
* @brief A measurement of a monotonically nondecreasing clock.
|
|
* @tparam T the data type of the counter
|
|
* @sa https://doc.rust-lang.org/std/time/struct.Instant.html
|
|
*/
|
|
struct Instant {
|
|
public:
|
|
using clock = typename app::utils::clock_t;
|
|
using duration = typename clock::duration;
|
|
using time_point = typename clock::time_point;
|
|
using milliseconds = typename std::chrono::duration<uint32_t, std::milli>;
|
|
using ms_rep = typename milliseconds::rep;
|
|
|
|
|
|
Instant() {
|
|
time_ = clock::now();
|
|
}
|
|
|
|
static Instant now() {
|
|
return Instant{};
|
|
}
|
|
|
|
[[nodiscard]]
|
|
duration elapsed() const {
|
|
return clock::now() - time_;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
ms_rep elapsed_ms() const {
|
|
return std::chrono::duration_cast<milliseconds>(elapsed()).count();
|
|
}
|
|
|
|
template <typename Rep, typename Period>
|
|
[[nodiscard]]
|
|
bool has_elapsed(const std::chrono::duration<Rep, Period> duration) const {
|
|
return elapsed() >= duration;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
bool has_elapsed_ms(ms_rep ms) const {
|
|
return has_elapsed(milliseconds{ms});
|
|
}
|
|
|
|
/**
|
|
* @brief Check if the instant has elapsed and reset the time point if it has.
|
|
* @note use if periodic task to get some timer like behavior. (note that
|
|
* you might not want to busy wait to check this, although you are free to do so)
|
|
*
|
|
* @tparam Rep representation of the duration (int, uint32_t, uint64_t, etc.)
|
|
* @tparam Period unit of the duration (std::milli, std::micro, etc.)
|
|
* @param duration the duration to check against
|
|
* @return true if the instant has elapsed, and would be reset
|
|
* @return false if the instant has not elapsed
|
|
*/
|
|
template <typename Rep, typename Period>
|
|
[[nodiscard]]
|
|
bool mut_every(const std::chrono::duration<Rep, Period> duration) {
|
|
if (has_elapsed(duration)) {
|
|
mut_reset();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
bool mut_every_ms(ms_rep ms) {
|
|
return mut_every(milliseconds{ms});
|
|
}
|
|
|
|
void mut_reset() {
|
|
time_ = clock::now();
|
|
}
|
|
|
|
/**
|
|
* @deprecated use `mut_reset` instead
|
|
*/
|
|
[[deprecated("use `mut_reset` instead")]]
|
|
void reset() {
|
|
mut_reset();
|
|
}
|
|
|
|
[[nodiscard]]
|
|
duration mut_elapsed_and_reset() {
|
|
auto e = elapsed();
|
|
mut_reset();
|
|
return e;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
time_point last() const {
|
|
return time_;
|
|
}
|
|
|
|
private:
|
|
time_point time_;
|
|
};
|
|
}
|