1. Topic
The differences between vTaskDelay(), vTaskDelayUntil(), esp_timer, GPTimer, RMT and MCPWM/LEDC on ESP32, and TIM/Input Capture/Output Compare/DMA on STM32. Main idea: vTaskDelay() is not a precise physical timer.
2. Why this matters in a project
Accurate timing is needed for phase timestamps, sync/PPS/20 Hz, IR illumination, HIL, watchdog heartbeats and measuring input -> event -> transport latency.
3. Theory
Four levels of timing:
1. FreeRTOS delay: vTaskDelay/vTaskDelayUntil, ms-level periodic tasks.
2. Software timer: esp_timer, timestamp/timeouts.
3. Hardware timer: GPTimer/TIM, precise interrupts/counters.
4. Specialized peripheral: RMT/MCPWM/LEDC/TIM PWM/Input Capture/Output Compare/DMA.vTaskDelay() means that a task does not run for the requested N ticks. It runs again when the scheduler gives it CPU time. This can be suitable for polling inputs every 1-5 ms, but not for a precise 200 us pulse. For periodic tasks, prefer:
TickType_t last = xTaskGetTickCount();
while (1) {
do_input_poll();
vTaskDelayUntil(&last, pdMS_TO_TICKS(2));
}An ESP32 timestamp:
int64_t now_us = esp_timer_get_time();Hardware timing:
- Input Capture latches the timer counter in hardware at an edge.
- Output Compare generates an event when counter == CCR.
- PWM + DMA can update CCR/duty without involving the CPU at each edge.
- RMT is useful for accurately timed pulse sequences.
4. Common mistakes
- Generating a precise pulse with vTaskDelay().
- Performing I2C/MQTT/logging in a timer callback or ISR.
- Adding the timestamp after expensive processing.
- Sharing one timer between PWM, profiling, capture and scheduling without a policy.
- Capturing noisy AC input without a Schmitt trigger/comparator.
- Ignoring timer counter overflow.
5. Practical task
Create TIMING_POLICY.md:
# Timing policy
| Need | ESP32 tool | STM32 tool |
|---|---|---|
| Periodic task | vTaskDelayUntil | osDelayUntil |
| Timestamp | esp_timer_get_time | TIM counter |
| Precise interrupt | GPTimer | TIM update IRQ |
| PWM | LEDC/MCPWM/RMT | TIM PWM |
| Input timestamp | GPIO ISR/RMT/GPTimer | TIM input capture |
| Output event | GPTimer/MCPWM/RMT | TIM output compare |Add raw_sample_us, detected_us, confirmed_us, queued_us and sent_us to phase_event_t.
6. Further reading and experiments
ESP-IDF esp_timer, GPTimer and LEDC/MCPWM/RMT; STM32 HAL TIM; ST AN4013; experiments with input capture and output compare.
Exercise
Choose a mechanism for housekeeping every 100 ms, a physical 200 us pulse, and timing an external edge. Explain what vTaskDelayUntil() does not guarantee.
Self-check criteria: Name a mechanism for every role, distinguish capture from ISR timestamping, and state the scheduler limitation.
Show the supplied answer
Housekeeping: vTaskDelayUntil or an appropriate software timer. Pulse: a hardware timer/specialized peripheral. Edge: hardware Input Capture where supported, or a GPIO ISR with evaluated latency. vTaskDelayUntil maintains a tick-based period but does not remove scheduler/interrupt latency or make a task a physical timer.