High Resolution Timer¶
Overview¶
Although FreeRTOS provides software timers, these timers have a few limitations:
- Maximum resolution is equal to RTOS tick period
- Timer callbacks are dispatched from a low-priority task
Hardware timers are free from both of the limitations, but often they are less convenient to use. For example, application components may need timer events to fire at certain times in the future, but the hardware timer only contains one “compare” value used for interrupt generation. This means that some facility needs to be built on top of the hardware timer to manage the list of pending events can dispatch the callbacks for these events as corresponding hardware interrupts happen.
esp_timer
set of APIs provides one-shot and periodic timers, microsecond time resolution, and 64-bit range.
Internally, esp_timer
uses a 64-bit hardware timer CONFIG_ESP_TIMER_IMPL:
- LAC timer (ESP32)
- (legacy) FRC2 timer (ESP32)
- SYSTIMER for (ESP32-S2)
Timer callbacks are dispatched from a high-priority esp_timer
task. Because all the callbacks are dispatched from the same task, it is recommended to only do the minimal possible amount of work from the callback itself, posting an event to a lower priority task using a queue instead.
If other tasks with priority higher than esp_timer
are running, callback dispatching will be delayed until esp_timer
task has a chance to run. For example, this will happen if a SPI Flash operation is in progress.
Creating and starting a timer, and dispatching the callback takes some time. Therefore there is a lower limit to the timeout value of one-shot esp_timer
. If esp_timer_start_once()
is called with a timeout value less than 20us, the callback will be dispatched only after approximately 20us.
Periodic esp_timer
also imposes a 50us restriction on the minimal timer period. Periodic software timers with period of less than 50us are not practical since they would consume most of the CPU time. Consider using dedicated hardware peripherals or DMA features if you find that a timer with small period is required.
Using esp_timer
APIs¶
Single timer is represented by esp_timer_handle_t
type. Timer has a callback function associated with it. This callback function is called from the esp_timer
task each time the timer elapses.
- To create a timer, call
esp_timer_create()
. - To delete the timer when it is no longer needed, call
esp_timer_delete()
.
The timer can be started in one-shot mode or in periodic mode.
- To start the timer in one-shot mode, call
esp_timer_start_once()
, passing the time interval after which the callback should be called. When the callback gets called, the timer is considered to be stopped. - To start the timer in periodic mode, call
esp_timer_start_periodic()
, passing the period with which the callback should be called. The timer keeps running untilesp_timer_stop()
is called.
Note that the timer must not be running when esp_timer_start_once()
or esp_timer_start_periodic()
is called. To restart a running timer, call esp_timer_stop()
first, then call one of the start functions.
Obtaining Current Time¶
esp_timer
also provides a convenience function to obtain the time passed since start-up, with microsecond precision: esp_timer_get_time()
. This function returns the number of microseconds since esp_timer
was initialized, which usually happens shortly before app_main
function is called.
Unlike gettimeofday function, values returned by esp_timer_get_time()
:
- Start from zero after the chip wakes up from deep sleep
- Do not have timezone or DST adjustments applied
Application Example¶
The following example illustrates usage of esp_timer
APIs: system/esp_timer.
API Reference¶
Header File¶
Functions¶
-
esp_err_t
esp_timer_init
(void)¶ Initialize esp_timer library.
- Note
- This function is called from startup code. Applications do not need to call this function before using other esp_timer APIs.
- Return
- ESP_OK on success
- ESP_ERR_NO_MEM if allocation has failed
- ESP_ERR_INVALID_STATE if already initialized
- other errors from interrupt allocator
-
esp_err_t
esp_timer_deinit
(void)¶ De-initialize esp_timer library.
- Note
- Normally this function should not be called from applications
- Return
- ESP_OK on success
- ESP_ERR_INVALID_STATE if not yet initialized
-
esp_err_t
esp_timer_create
(const esp_timer_create_args_t *create_args, esp_timer_handle_t *out_handle)¶ Create an esp_timer instance.
- Note
- When done using the timer, delete it with esp_timer_delete function.
- Return
- ESP_OK on success
- ESP_ERR_INVALID_ARG if some of the create_args are not valid
- ESP_ERR_INVALID_STATE if esp_timer library is not initialized yet
- ESP_ERR_NO_MEM if memory allocation fails
- Parameters
create_args
: Pointer to a structure with timer creation arguments. Not saved by the library, can be allocated on the stack.out_handle
: Output, pointer to esp_timer_handle_t variable which will hold the created timer handle.
-
esp_err_t
esp_timer_start_once
(esp_timer_handle_t timer, uint64_t timeout_us)¶ Start one-shot timer.
Timer should not be running when this function is called.
- Return
- ESP_OK on success
- ESP_ERR_INVALID_ARG if the handle is invalid
- ESP_ERR_INVALID_STATE if the timer is already running
- Parameters
timer
: timer handle created using esp_timer_createtimeout_us
: timer timeout, in microseconds relative to the current moment
-
esp_err_t
esp_timer_start_periodic
(esp_timer_handle_t timer, uint64_t period)¶ Start a periodic timer.
Timer should not be running when this function is called. This function will start the timer which will trigger every ‘period’ microseconds.
- Return
- ESP_OK on success
- ESP_ERR_INVALID_ARG if the handle is invalid
- ESP_ERR_INVALID_STATE if the timer is already running
- Parameters
timer
: timer handle created using esp_timer_createperiod
: timer period, in microseconds
-
esp_err_t
esp_timer_stop
(esp_timer_handle_t timer)¶ Stop the timer.
This function stops the timer previously started using esp_timer_start_once or esp_timer_start_periodic.
- Return
- ESP_OK on success
- ESP_ERR_INVALID_STATE if the timer is not running
- Parameters
timer
: timer handle created using esp_timer_create
-
esp_err_t
esp_timer_delete
(esp_timer_handle_t timer)¶ Delete an esp_timer instance.
The timer must be stopped before deleting. A one-shot timer which has expired does not need to be stopped.
- Return
- ESP_OK on success
- ESP_ERR_INVALID_STATE if the timer is not running
- Parameters
timer
: timer handle allocated using esp_timer_create
-
int64_t
esp_timer_get_time
(void)¶ Get time in microseconds since boot.
- Return
- number of microseconds since esp_timer_init was called (this normally happens early during application startup).
-
int64_t
esp_timer_get_next_alarm
(void)¶ Get the timestamp when the next timeout is expected to occur.
- Return
- Timestamp of the nearest timer event, in microseconds. The timebase is the same as for the values returned by esp_timer_get_time.
-
esp_err_t
esp_timer_dump
(FILE *stream)¶ Dump the list of timers to a stream.
If CONFIG_ESP_TIMER_PROFILING option is enabled, this prints the list of all the existing timers. Otherwise, only the list active timers is printed.
The format is:
name period alarm times_armed times_triggered total_callback_run_time
where:
name — timer name (if CONFIG_ESP_TIMER_PROFILING is defined), or timer pointer period — period of timer, in microseconds, or 0 for one-shot timer alarm - time of the next alarm, in microseconds since boot, or 0 if the timer is not started
The following fields are printed if CONFIG_ESP_TIMER_PROFILING is defined:
times_armed — number of times the timer was armed via esp_timer_start_X times_triggered - number of times the callback was called total_callback_run_time - total time taken by callback to execute, across all calls
- Return
- ESP_OK on success
- ESP_ERR_NO_MEM if can not allocate temporary buffer for the output
- Parameters
stream
: stream (such as stdout) to dump the information to
Structures¶
-
struct
esp_timer_create_args_t
¶ Timer configuration passed to esp_timer_create.
Public Members
-
esp_timer_cb_t
callback
¶ Function to call when timer expires.
-
void *
arg
¶ Argument to pass to the callback.
-
esp_timer_dispatch_t
dispatch_method
¶ Call the callback from task or from ISR.
-
const char *
name
¶ Timer name, used in esp_timer_dump function.
-
esp_timer_cb_t