| Сравнение функций xthal_get_ccount() и esp_timer_get_time() |
|
| Добавил(а) microsin | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
xthal_get_ccount() и esp_timer_get_time() служат для измерения времени, но делают это на совершенно разных уровнях. Первая предоставляет сырые циклы процессора, вторая — готовое время в микросекундах. Вот их основные отличия, представленные в таблице для удобства:
[Рекомендации по выбору функции] Для задачи обработки кадрового синхроимпульса выбор зависит от точности, которая требуется для временной метки в обработчике прерывания. esp_timer_get_time(): идеальный выбор в большинстве случаев. Она даст время в микросекундах, что удобно для логирования или проверки интервалов между кадрами. // В обработчике прерывания xthal_get_ccount(): стоит выбрать только если вам критически важна наносекундная точность для измерения промежутка между самими прерываниями. static uint32_t last_cycle_count = 0; Важное замечание: используйте эту функцию только в коде, закреплённом за одним ядром (например, в ISR), чтобы избежать проблем из-за разных счетчиков на разных ядрах. [Важные предостережения] - Избегайте смешивания: не вычитайте значения xthal_get_ccount(), полученные в разные моменты, если между ними мог произойти сон процессора или переключение ядра — результат будет неверным. - Функция esp_timer_get_time() не идеальна: при очень частых вызовах (с интервалом в десятки микросекунд) в некоторых версиях ESP-IDF наблюдалась погрешность. [Обзор различных возможностей по измерению времени] В ESP-IDF и FreeRTOS есть несколько функций для измерения времени, каждая с уникальными возможностями. Для выбора важно понимать требуемый уровень точности, поведение при режимах сна и удобство использования. В таблице ниже приведено сравнение основных функций:
Детальные сценарии применения. Вот конкретные ситуации для использования разных функций: - Задача с кадровым синхроимпульсом: для измерения интервалов между кадрами с высокой точностью внутри обработчика прерывания (ISR) лучшим выбором будет esp_timer_get_time(). Она проста в использовании, а разрешения в 1 микросекунду (при частоте 60 FPS период ~16.6 мс) обычно достаточно. `xthal_get_ccount()` стоит использовать только если важна наносекундная точность. - Работа с календарным временем: для получения текущей даты и времени (например, для логов) используйте gettimeofday() или time(). Эти функции могут синхронизироваться с NTP-серверами через сеть. - Создание периодических событий: для запуска кода по расписанию удобны программные таймеры FreeRTOS (функции xTimerCreate, xTimerStart) или, для большей точности, аппаратные таймеры общего назначения (GPTimer). - Организация задержек в задачах: для этого предназначены vTaskDelay() (относительная задержка) и vTaskDelayUntil() (точный периодический интервал). Для задержек короче системного тика требуются аппаратные таймеры. - Можно рассмотреть аппаратный таймер (GPTimer) для измерения интервала напрямую.
|