Skip to content

Commit

Permalink
feat(timer): allow skip_unhandled_events and timer dispatch configu…
Browse files Browse the repository at this point in the history
…ration for `HighResolutionTimer` (#246)
  • Loading branch information
finger563 authored May 28, 2024
1 parent c9f236c commit f5c9307
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 17 deletions.
4 changes: 4 additions & 0 deletions components/timer/example/main/timer_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
47 changes: 30 additions & 17 deletions components/timer/include/high_resolution_timer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,35 @@ 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
};

/// Constructor
/// @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)
set_log_rate_limit(100ms);
}

/// 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
Expand All @@ -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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<bool> oneshot_{false};
Callback callback_{nullptr};
Expand Down

0 comments on commit f5c9307

Please sign in to comment.