Page 1 of 1

Watchdog being starved with sub-10ms high resolution timer

Posted: Fri Feb 09, 2024 1:30 am
by jrgilman95
Hi there - first post on here as I couldn't find a lot of information on this topic. We have a use case where items can move extremely quickly past a photo-eye which also requires some software debouncing. We've been using the standard 100Hz tick rate and an interrupt up to this point for previous projects, but this has been problematic on this one so I'm exploring other options.

One option I wanted to gauge was using a period timer to launch a callback that polls the GPIO every 5ms. Then using an algorithm to debounce as well as eliminate potential EMI.

I've configured FreeRTOS to use a 1000Hz tick rate, and have wrote the code below to just feasibility test this. At 10ms the watchdog is getting fed, but going down to 5ms has caused problems.

I'm not sure if I'm just doing something wrong here or what. As an aside, and I'm unsure if anyone knows the answer to this, but I'm curious what happens in FreeRTOS if the callback completes before a full tick is up, does that time get lost or does a new tick get started? I highly doubt the callback below takes more than 1 tick (1ms @ 1000Hz) to run, even with all the overhead, so I guess I'm confused why the IDLE task is failing o run in the 4 ticks it has before the next timer?
  1. #include <string.h>
  2.  
  3. #include "esp_timer.h"
  4. #include "esp_log.h"
  5.  
  6. #include "freertos/FreeRTOS.h"
  7.  
  8. static const char *TAG = "Timer Test";
  9.  
  10. void periodic_timer_callback(void* arg) {
  11.     ESP_LOGI(TAG, "Periodic timer called on core #%d, the time is %llu", xPortGetCoreID(), esp_timer_get_time());
  12. }
  13.  
  14. void app_main(void) {
  15.     esp_timer_handle_t periodic_timer;
  16.     esp_timer_create_args_t periodic_timer_args = {
  17.         .callback = &periodic_timer_callback,
  18.         .name = "test"
  19.     };
  20.  
  21.     esp_timer_create(&periodic_timer_args, &periodic_timer);
  22.     esp_timer_start_periodic(periodic_timer, 5 * 1000);
  23. }

Re: Watchdog being starved with sub-10ms high resolution timer

Posted: Fri Feb 09, 2024 2:15 am
by ESP_Sprite
Decently sure that at least in your example, the ESP_LOGI is the bottleneck; it will (also) output to the UART and that only has a limited speed.

Re: Watchdog being starved with sub-10ms high resolution timer

Posted: Fri Feb 09, 2024 2:26 am
by jrgilman95
ESP_Sprite wrote:
Fri Feb 09, 2024 2:15 am
Decently sure that at least in your example, the ESP_LOGI is the bottleneck; it will (also) output to the UART and that only has a limited speed.
I'm not a smart man. Switching it over to this solved it:
  1. static int count = 0;
  2.  
  3. void periodic_timer_callback(void* arg) {
  4.     if (count++ == 100) {
  5.         ESP_LOGI(TAG, "Periodic timer called on core #%d, the time is %llu", xPortGetCoreID(), esp_timer_get_time());
  6.         count = 0;
  7.     }
  8. }