# Be careful when using xTaskAbortDelay() along vTaskDelayUntil()

**URL:** <https://forums.freertos.org/t/be-careful-when-using-xtaskabortdelay-along-vtaskdelayuntil/13467>\
**Category:** Kernel\
**Created:** [September 16, 2021, 1:49am UTC](https://forums.freertos.org/t/be-careful-when-using-xtaskabortdelay-along-vtaskdelayuntil/13467 "2021-09-16T01:49:28Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Xavier](https://avatars.discourse-cdn.com/v4/letter/x/2bfe46/32.png) [@Xavier](https://forums.freertos.org/u/Xavier)\
**Post date:** [September 16, 2021, 1:49am UTC](https://forums.freertos.org/t/be-careful-when-using-xtaskabortdelay-along-vtaskdelayuntil/13467/1 "2021-09-16T01:49:28Z")

</div>

This is an advice.

`xTaskAbortDelay()` breaks `vTaskDelayUntil()` unless you have a way to recompute `lastWakeUp`. Let’s look at this example:

```auto
void task1( void* pvParameters )
{
   pinMode( 13, OUTPUT );
   TickType_t last_wakeup = xTaskGetTickCount();
   bool state = false;

   while( 1 )
   {
      vTaskDelayUntil( &last_wakeup, pdMS_TO_TICKS( 500 ) );
      digitalWrite( 13, (state=!state) );
      xTaskNotifyGive( task0_handler );
   }
}

void task0( void* pvParameters )
{
   uint16_t cont = 6;
   bool state = false;

   while( 1 )
   {
      ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
      digitalWrite( 2, (state=!state) );
      if( --cont == 0 )
      {
         cont = 6;
         vTaskDelay( pdMS_TO_TICKS( 250 ) );
         xTaskAbortDelay( task1_handler );
      }
   }
}

```

Task0 (that has priority 0) wakes up Task1 (that has priority 1) earlier every 6 counts, as seen. However, there’s no way that Task1 is aware it was woke up before time, so strange things might happen. My system (Arduino UNO using the 8bit chip atmega328) resets or hangs, nobody knows which one will happen!

Output:

```auto
31
32
33
4081516544S4
35
36
37
38
39
40
41
42
43
44
45
46
47
48
  OUT OF RESET
1
2

```

It always resets at the count of 48, and after some resets the system hangs.

And don’t even think about using `xTaskDelayUntil()`:

```auto
void task1( void* pvParameters )
{
   pinMode( 13, OUTPUT );
   TickType_t last_wakeup = xTaskGetTickCount();
   bool state = false;

   while( 1 )
   {
      if( xTaskDelayUntil( &last_wakeup, pdMS_TO_TICKS( 500 ) == pdFALSE ) )
      {
         last_wakeup = xTaskGetTickCount();
      }

      digitalWrite( 13, (state=!state) );
      xTaskNotifyGive( task0_handler );
   }
}

```

It just doesn’t work at all! The system doesn’t even start.

Yes, I know that this example is a corner case, but you can’t say I didn’t tell you so.

BTW, there is not an interrupt safe version of `xTaskAbortDelay()`. Developers say they don’t see why should it exist (look for it in the forum).

There are a good news, after all: It seems that`xTaskAbortDelay()` works correctly along `vTaskDelay()`.

Happy coding!

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [September 16, 2021, 3:50pm UTC](https://forums.freertos.org/t/be-careful-when-using-xtaskabortdelay-along-vtaskdelayuntil/13467/2 "2021-09-16T15:50:50Z")

</div>

Is this just an eccentric way of reporting a bug, or are you asking for help? In either case you will need to be more explicit.

In regards to vTaskDelayUntil() working and xTaskDelayUntil() not working at all - you will see [here](https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/V10.4.5/include/task.h#L862) that they are the same function. One is just a macro that calls the other to maintain backward compatibility.

In regards to vTaskDelayUntil() behavior when unblocked using xTaskAbortDelay() - if your application is coded to wake the task early then your application will also need to manually adjust the time at which the task should next unblock on subsequent calls. The function itself is designed for periodic execution - if it adjusted the next unblock time itself when it was forced out of the blocked state it would be arbitrary as to whether it adjusted it to the time it should have unblocked or the time it should unblock after that - in both cases it would not be running with a fixed period.

---

<div class="post-metadata">

**Author:** ![richard-damon](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/richard-damon/32/38_2.png) [@richard-damon](https://forums.freertos.org/u/richard-damon)\
**Post date:** [September 16, 2021, 6:41pm UTC](https://forums.freertos.org/t/be-careful-when-using-xtaskabortdelay-along-vtaskdelayuntil/13467/3 "2021-09-16T18:41:46Z")

</div>

My thought on this is that if you abort the delay, the recorded wake up time might be in the future, which gets interpreted as the distant past, and the function will go into ‘catch-up’ mode for a very long time (especially with a 32-bit tick) which might seem like it is broken.

---

<div class="post-metadata">

**Author:** ![Xavier](https://avatars.discourse-cdn.com/v4/letter/x/2bfe46/32.png) [@Xavier](https://forums.freertos.org/u/Xavier)\
**Post date:** [September 17, 2021, 5:01am UTC](https://forums.freertos.org/t/be-careful-when-using-xtaskabortdelay-along-vtaskdelayuntil/13467/4 "2021-09-17T05:01:41Z")

</div>

Hi,

Now I’m able to debug the atmega328 chip stable and fluently and I found something weird: when calling the function `xTaskAbortDelay()` along the function `vTaskDelayUntil()` the system halts (fires an assertion) because of the variable `uxSchedulerSuspended` got a value other than 0:

```auto
(gdb) monitor reset halt
Resetting MCU...
(gdb) c
Continuando.
^C // HERE THE SYSTEM HALTS SO I EXECUTE A CTRL-C
Program received signal SIGINT, Interrupt.
0x00001cca in xTaskDelayUntil (pxPreviousWakeTime=0x8003cf, xTimeIncrement=500)
    at /home/fjrg76/arduino-1.8.13/libraries/FreeRTOS/src/tasks.c:1257
1257 configASSERT( uxSchedulerSuspended == 0 );
(gdb) p *pxPreviousWakeTime 
$9 = 8000
(gdb) p xTimeIncrement 
$10 = 500
(gdb) p uxSchedulerSuspended 
$11 = 43 '+' // IS THAT NORMAL?
(gdb) backtrace 
#0 0x00001cca in xTaskDelayUntil (pxPreviousWakeTime=0x8003cf, xTimeIncrement=500)
    at /home/fjrg76/arduino-1.8.13/libraries/FreeRTOS/src/tasks.c:1257
#1 0x000001a2 in task1 (pvParameters=0x0 <__vectors>) at main.cpp:58
#2 0x00006644 in ?? ()
(gdb) list
1252 TickType_t xTimeToWake;
1253 BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE;
1254	
1255 configASSERT( pxPreviousWakeTime );
1256 configASSERT( ( xTimeIncrement > 0U ) );
1257 configASSERT( uxSchedulerSuspended == 0 ); // THIS IS THE ASSERT THAT FIRES
1258	
1259 vTaskSuspendAll();
1260 {
1261 /* Minor optimisation. The tick count cannot change in this
(gdb) 

```

This is the complete code (well, only the main.cpp file where I coded the sample): [main.cpp](https://forums.freertos.org/uploads/short-url/4s9Nzp9cVeF8cMGnQ8wwTtiqjSy.cpp) (3.5 KB)

> [@rtel](#):
>
> Is this just an eccentric way of reporting a bug, or are you asking for help? In either case you will need to be more explicit.

Both =) Posts ago I asked you for the atmega323 maintainer so I can address my issue directly with the programmer but I received no answers.

I try to be as explicit as I can, but I know that sometimes isn’t enough.

> [@rtel](#):
>
> In regards to vTaskDelayUntil() working and xTaskDelayUntil() not working at all - you will see [here](https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/V10.4.5/include/task.h#L862) that they are the same function. One is just a macro that calls the other to maintain backward compatibility.

Yeah, I saw that in the source code, so I have no idea why the system crashes. I want to create a video showing you what’s going on.

> [@rtel](#):
>
> In regards to vTaskDelayUntil() behavior when unblocked using xTaskAbortDelay() - if your application is coded to wake the task early then your application will also need to manually adjust the time at which the task should next unblock on subsequent calls.

But the reason to exist for the `xTaskAbortDelay()` is to wake the task up before time, so from time to time one will need to call it, but if one isn’t aware of such situation, problems will arise.

Thank you!

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [September 18, 2021, 1:45am UTC](https://forums.freertos.org/t/be-careful-when-using-xtaskabortdelay-along-vtaskdelayuntil/13467/5 "2021-09-18T01:45:28Z")

</div>

> [@Xavier](#):
>
> `uxSchedulerSuspended` got a value other than 0

Could this be just a data corruption caused by something like a stack overflow? What value does uxSchedulerSuspended get - if it were something other than 1 corruption would be a likely cause.

---

<div class="post-metadata">

**Author:** ![Xavier](https://avatars.discourse-cdn.com/v4/letter/x/2bfe46/32.png) [@Xavier](https://forums.freertos.org/u/Xavier)\
**Post date:** [September 19, 2021, 3:10am UTC](https://forums.freertos.org/t/be-careful-when-using-xtaskabortdelay-along-vtaskdelayuntil/13467/6 "2021-09-19T03:10:07Z")

</div>

Hi,

(Source code at the end.)

> [@rtel](#):
>
> Could this be just a data corruption caused by something like a stack overflow?

The Arduino’s serial print utility (`Serial.print()`) seems to be causing a stack overflow, so I’ve eliminated it from the project… **but the problem still exists**.

**Facts:**

If I use `vTaskDelay()`, instead of `vTaskDelayUntil()`, along `xTaskAbortDelay()`, the program runs smoothly. 🙂

If I use `vTaskDelayUntil()` without `xTaskAbortDelay()`, the program runs smoothly. 🙂

If I use `vTaskDelayUntil()` along `xTaskAbortDelay()`, the program fails. ☹

In such case apparently there’s not any stack overflow. After I execute a Ctrl-c in GDB I got this:

```auto
(gdb) p *task1_handler 
$6 = {pxTopOfStack = 0x8002b7 "\034", xStateListItem = {xItemValue = 32568, pxNext = 0x800160 <pxReadyTasksLists+12>, 
    pxPrevious = 0x800160 <pxReadyTasksLists+12>, pvOwner = 0x8002f3, pvContainer = 0x80015d <pxReadyTasksLists+9>}, xEventListItem = {xItemValue = 2, 
    pxNext = 0x0 < __vectors>, pxPrevious = 0x0 <__ vectors>, pvOwner = 0x8002f3, pvContainer = 0x0 <__vectors>}, uxPriority = 1 '\001', 
  pxStack = 0x8001f1 "", pcTaskName = "T1\000\000", ulNotifiedValue = {0}, ucNotifyState = "", ucStaticallyAllocated = 0 '\000', 
  ucDelayAborted = 0 '\000'}
(gdb) p/x (*task1_handler->pxStack)@32
$17 = {0xa5 <repeats 32 times>} // I might presume there aren't any overflows

```

But more important, the variable `uxSchedulerSuspended` gets corrupted somewhere. The program runs as expected for some time, and then it fails:

```auto
...
Breakpoint 2, xTaskAbortDelay (xTask=<optimized out>) at /home/fjrg76/arduino-1.8.13/libraries/FreeRTOS/src/tasks.c:2720
2720 }
1: uxSchedulerSuspended = 0 '\000'
(gdb) c
Continuando.

Breakpoint 2, xTaskAbortDelay (xTask=<optimized out>) at /home/fjrg76/arduino-1.8.13/libraries/FreeRTOS/src/tasks.c:2720
2720 }
1: uxSchedulerSuspended = 0 '\000'
(gdb) c
Continuando.

Breakpoint 2, xTaskAbortDelay (xTask=<optimized out>) at /home/fjrg76/arduino-1.8.13/libraries/FreeRTOS/src/tasks.c:2720
2720 }
1: uxSchedulerSuspended = 0 '\000'
(gdb) c
Continuando.
^C // HERE THE PROGRAM HAS FAILED
Program received signal SIGINT, Interrupt.
0x00000eda in xTaskDelayUntil (pxPreviousWakeTime=0x8002e4, xTimeIncrement=500) at /home/fjrg76/arduino-1.8.13/libraries/FreeRTOS/src/tasks.c:1257
1257 configASSERT( uxSchedulerSuspended == 0 );
1: uxSchedulerSuspended = 169 '\251'
(gdb)

```

Unfortunately the GDB for the atmega328 is limited and watchpoints don’t work.

Any hint why or where `uxSchedulerSuspended` gets corrupted or how I can catch the moment in which it gets corrupted without using the “watching” GDB’s utility?

I cannot write any application for this chip as long as this problem isn’t solved.

Thank you!

**Source code:**

```auto
#include <Arduino.h>
void initVariant() __attribute__ ((weak));
void setupUSB() __attribute__ ((weak));
int atexit(void (* /*func*/ )()) { return 0; }
void initVariant() { }
void setupUSB() { }

#include <FreeRTOS.h>
#include <task.h>

TaskHandle_t task0_handler;
TaskHandle_t task1_handler;

void task1( void* pvParameters )
{
   pinMode( 13, OUTPUT );
   uint16_t cont = 0;
   TickType_t last_wakeup = xTaskGetTickCount();
   bool state = false;

   while( 1 )
   {
      vTaskDelayUntil( &last_wakeup, pdMS_TO_TICKS( 500 ) );

      digitalWrite( 13, (state=!state) );

      xTaskNotifyGive( task0_handler );
   }
}

void task0( void* pvParameters )
{
   uint16_t cont = 5;
   bool state = false;

   while( 1 )
   {
      ulTaskNotifyTake( pdTRUE, portMAX_DELAY );

      digitalWrite( 2, (state=!state) );

      --cont;
      if( cont == 0 )
      {
         cont = 6;
         vTaskDelay( pdMS_TO_TICKS( 100 ) );

         xTaskAbortDelay( task1_handler ); // HERE IS THE CALLING
      }
   }
}

int main(void)
{
   cli();
   init();
	initVariant();
#if defined(USBCON)
	USBDevice.attach();
#endif

   if( xTaskCreate( task1, "T1", 128 * 2, 0, tskIDLE_PRIORITY+1, &task1_handler ) != pdPASS ) 
      configASSERT( 0 );

   if( xTaskCreate( task0, "T0", 128 * 4, 0, tskIDLE_PRIORITY, &task0_handler ) != pdPASS ) 
      configASSERT( 0 );

   pinMode( 2, OUTPUT );
   digitalWrite( 2, LOW );
   vTaskStartScheduler();

   while( 1 )
   {
   }

   return 0;
}

#ifdef __cplusplus
extern "C"
{
#endif

   void vApplicationStackOverflowHook( TaskHandle_t task, char* pcTaskName )
   {
      digitalWrite( 2, HIGH );
   }

   void vApplicationIdleHook()
   {
   }

   void vApplicationMallocFailedHook()
   {
      cli();

      pinMode( 13, OUTPUT );

      while( 1 )
      {
         digitalWrite( 13, HIGH );
         for( size_t i = 65000; i > 0; --i);
         digitalWrite( 13, LOW );
         for( size_t i = 65000; i > 0; --i);
      }
   }

#ifdef __cplusplus
}
#endif

```

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [September 19, 2021, 4:18pm UTC](https://forums.freertos.org/t/be-careful-when-using-xtaskabortdelay-along-vtaskdelayuntil/13467/7 "2021-09-19T16:18:03Z")

</div>

In your case [this](https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/V10.4.5/tasks.c#L1278) line is going to see that the last wake time is ahead of the current time (because the task’s delay was aborted) and so assume the tick count overflowed since the task last entered the function.

What is it you are actually trying to achieve - there is probably a different method you can use.

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [September 19, 2021, 5:09pm UTC](https://forums.freertos.org/t/be-careful-when-using-xtaskabortdelay-along-vtaskdelayuntil/13467/8 "2021-09-19T17:09:31Z")

</div>

I have some experimental code that attempts to handle aborted delays within xTaskDelayUntil() - it makes your code work but I’m not sure of other implications - corner cases in particular.

---

<div class="post-metadata">

**Author:** ![Xavier](https://avatars.discourse-cdn.com/v4/letter/x/2bfe46/32.png) [@Xavier](https://forums.freertos.org/u/Xavier)\
**Post date:** [September 19, 2021, 7:25pm UTC](https://forums.freertos.org/t/be-careful-when-using-xtaskabortdelay-along-vtaskdelayuntil/13467/9 "2021-09-19T19:25:49Z")

</div>

> [@rtel](#):
>
> What is it you are actually trying to achieve

I already know why, how and when to use the delay functions; however, incredibly I did’nt know that the function `xTaskAbortDelay()` did exist (at least I haven’t paid so much attention to it) so I wanted to experiment with it in simple programs, and I never thought it would turn into a nightmare.

I can think of scenarios where `xTaskDelayUntil()` and `xTaskAbortDelay()` can coexist in peace, but, as my example has shown, I can’t even think to use them along in the same program.

> [@rtel](#):
>
> I have some experimental code that attempts to handle aborted delays within xTaskDelayUntil()

If a task is aware it can be waken-up earlier then it’s easy to implement code that re synchronize it; otherwise such situation might cause serious problems (you might include a warning in the documentation).

Thank you anyway for your time 🙂 . I’ll come back sooner than later with more awkard questions. Meanwhile I’ll give up for the atmega328 port (it had potential).
