From f5c930753d5ca878a5044045f7513b5178760c9e Mon Sep 17 00:00:00 2001 From: William Emfinger Date: Tue, 28 May 2024 09:17:48 -0500 Subject: [PATCH] feat(timer): allow `skip_unhandled_events` and timer dispatch configuration for `HighResolutionTimer` (#246) --- .../timer/example/main/timer_example.cpp | 4 ++ .../timer/include/high_resolution_timer.hpp | 47 ++++++++++++------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/components/timer/example/main/timer_example.cpp b/components/timer/example/main/timer_example.cpp index d6d0a8f09..9626547ce 100644 --- a/components/timer/example/main/timer_example.cpp +++ b/components/timer/example/main/timer_example.cpp @@ -201,6 +201,10 @@ extern "C" void app_main(void) { high_resolution_timer.set_period(period_us); logger.info("Periodic timer period: {}us", high_resolution_timer.get_period()); + // NOTE: only if CONFIG_ESP_TIMER_PROFILING is enabled will this show more + // than address, period and alarm. + esp_timer_dump(stdout); // dump timer stats + std::this_thread::sleep_for(500ms); logger.info("High resolution timer is running: {}", high_resolution_timer.is_running()); logger.info("Stopping timer"); diff --git a/components/timer/include/high_resolution_timer.hpp b/components/timer/include/high_resolution_timer.hpp index 3e789e657..c5179e704 100644 --- a/components/timer/include/high_resolution_timer.hpp +++ b/components/timer/include/high_resolution_timer.hpp @@ -33,8 +33,12 @@ class HighResolutionTimer : public espp::BaseComponent { /// Configuration of the timer struct Config { - std::string name; ///< Name of the timer - Callback callback{nullptr}; ///< Callback to be called when the timer expires + std::string name; ///< Name of the timer + Callback callback{nullptr}; ///< Callback to be called when the timer expires + bool skip_unhandled_events{false}; ///< Skip unhandled events. If true, will skip unhandled + ///< events in light sleep for periodic timers. + esp_timer_dispatch_t dispatch_method = + ESP_TIMER_TASK; ///< Dispatch method, TIMER_TASK or TIMER_ISR. espp::Logger::Verbosity log_level = espp::Logger::Verbosity::WARN; ///< Log level }; @@ -42,6 +46,8 @@ class HighResolutionTimer : public espp::BaseComponent { /// @param config Configuration of the timer explicit HighResolutionTimer(const Config &config) : BaseComponent(config.name, config.log_level) + , skip_unhandled_events_(config.skip_unhandled_events) + , dispatch_method_(config.dispatch_method) , callback_(config.callback) { using namespace std::chrono_literals; // set a default logger rate limit (can always be set later by caller) @@ -49,7 +55,13 @@ class HighResolutionTimer : public espp::BaseComponent { } /// Destructor - ~HighResolutionTimer() { stop(); } + ~HighResolutionTimer() { + stop(); + if (timer_handle_) { + esp_timer_delete(timer_handle_); + timer_handle_ = nullptr; + } + } /// Start the timer /// @param period_us Period of the timer in microseconds, or timeout if @@ -64,18 +76,21 @@ class HighResolutionTimer : public espp::BaseComponent { // store whether the timer is oneshot or periodic oneshot_ = oneshot; - esp_timer_create_args_t timer_args; - timer_args.callback = timer_callback; - timer_args.arg = this; - timer_args.dispatch_method = ESP_TIMER_TASK; // TIMER_TASK or TIMER_ISR - timer_args.name = get_name().c_str(); - esp_err_t err = ESP_OK; - err = esp_timer_create(&timer_args, &timer_handle_); - if (err != ESP_OK) { - logger_.error("Failed to create timer: {}", esp_err_to_name(err)); - return false; + if (timer_handle_ == nullptr) { + esp_timer_create_args_t timer_args; + timer_args.callback = timer_callback; + timer_args.arg = this; + timer_args.dispatch_method = dispatch_method_; + timer_args.name = get_name().c_str(); + timer_args.skip_unhandled_events = skip_unhandled_events_; + + err = esp_timer_create(&timer_args, &timer_handle_); + if (err != ESP_OK) { + logger_.error("Failed to create timer: {}", esp_err_to_name(err)); + return false; + } } if (oneshot) { @@ -106,10 +121,6 @@ class HighResolutionTimer : public espp::BaseComponent { if (is_running()) { esp_timer_stop(timer_handle_); } - if (timer_handle_) { - esp_timer_delete(timer_handle_); - timer_handle_ = nullptr; - } } /// Check if the timer is running @@ -183,6 +194,8 @@ class HighResolutionTimer : public espp::BaseComponent { } } + bool skip_unhandled_events_{false}; + esp_timer_dispatch_t dispatch_method_{ESP_TIMER_TASK}; esp_timer_handle_t timer_handle_{nullptr}; std::atomic oneshot_{false}; Callback callback_{nullptr};