How to compensate for the time it takes to run the task in VtaskDelay

zazas321
Posts: 231
Joined: Mon Feb 01, 2021 9:41 am

How to compensate for the time it takes to run the task in VtaskDelay

Postby zazas321 » Fri Oct 29, 2021 8:52 am

Hello. I have a complicated task running on my ESP32 device. I would like this task to repeat itself every 2 seconds.
I have set vTaskDelay(2000/portTICK_RATE_MS); at the end of the task but realised that this is not exactly what I need.
Since my task takes approximately 0.1 seconds to run and the vtaskDelay is set to 2 seconds, that means that the next time this task will be scheduled after 2.1 seconds which is not what I want. I want it to be 2 seconds regardless of how long the task took to execute.

For example my task execution time may vary from 0.15s to 0.05s and I want to compensate. Please suggest the most appropriate way to handle that.

vanBassum
Posts: 68
Joined: Sun Jan 17, 2021 11:59 am

Re: How to compensate for the time it takes to run the task in VtaskDelay

Postby vanBassum » Fri Oct 29, 2021 9:07 am

There are a few options, depending on the requirements.
1. https://www.freertos.org/vtaskdelayuntil.html
2. Run a timer, let the timer set a semaphore every 2 second, wait in the task for the semaphore and execute work.

saigajul37
Posts: 7
Joined: Tue Apr 27, 2021 12:07 pm
Location: pune

Re: How to compensate for the time it takes to run the task in VtaskDelay

Postby saigajul37 » Fri Oct 29, 2021 12:27 pm

  1. Just give it a try hope it will help you...
  1.  
  2. #define msdelay(tick_t) (vTaskDelay(tick_t / portTICK_PERIOD_MS))
  3. xTaskHandle vip_task_t;
  4. BaseType_t  isvip_task ;
  5.  
  6. void vip_task(void * arg) {
  7.    
  8.    // no forever loop
  9.    // do work 0.1 seconds
  10.    msdelay(1);
  11.    isvip_task = pdFAIL;
  12.    vTaskDelete( vip_task_t );                                          
  13.    vTaskDelete( NULL );
  14.  
  15. }
  16.  
  17. void app_main(void)  {
  18.  
  19.  int count_delay = 0;
  20.  
  21. while(1) {
  22.    
  23.             while ( isvip_task != pdPASS) {         // wait till task is created properly
  24.  
  25.             vip_task= xTaskCreate(vip_task, "vip_task", 1024*2, NULL, 16, &vip_task_t);
  26.                         count_delay += 100;
  27.             msdelay(100);
  28.         }
  29.            if ( count_delay <= 2000 ) {
  30.  
  31.                 msdelay(2000 - count_delay );
  32.             }
  33.            count_delay  = 0;
  34.  
  35. }
  36.  
  37. }
Sainath Gajul

zazas321
Posts: 231
Joined: Mon Feb 01, 2021 9:41 am

Re: How to compensate for the time it takes to run the task in VtaskDelay

Postby zazas321 » Wed Nov 03, 2021 5:18 am

Thanks for the response. I have also found another way. Do you think this is appropriate?

I check the time using esp_timer_get_time() at the beggining of my task and again at the end of my task. Then I take the difference of two and I know how long the task took to execute. Now I can substract this number in VtaskDelay :

Code: Select all

                vTaskDelay((2000-timestamp_difference)/portTICK_RATE_MS); // need to compensate here because the task will took some time to run


vanBassum
Posts: 68
Joined: Sun Jan 17, 2021 11:59 am

Re: How to compensate for the time it takes to run the task in VtaskDelay

Postby vanBassum » Wed Nov 03, 2021 12:48 pm

That is wat the code does suggested in my previous post.
Your solution has a few possible problems:
1. What if timestamp_difference > 2000, you now get a negative or a very large positive. Waiting will now be practically infinate.
2. You don't account for rollover of the esp_timer_get_time(), not sure how often this happens, probably not very often.

I suggest to just use the functions in freertos that where made to do this. No need to reinvent the wheel and you can be sure those functions are tested very well.

Code: Select all

 // Perform an action every 10 ticks.
 void vTaskFunction( void * pvParameters )
 {
 TickType_t xLastWakeTime;
 const TickType_t xFrequency = 10;

     // Initialise the xLastWakeTime variable with the current time.
     xLastWakeTime = xTaskGetTickCount();

     for( ;; )
     {
         // Wait for the next cycle.
         vTaskDelayUntil( &xLastWakeTime, xFrequency );

         // Perform action here.
     }
 }

Who is online

Users browsing this forum: No registered users and 115 guests