# Preventing entry to sleep when using tickless idle

**URL:** <https://forums.freertos.org/t/preventing-entry-to-sleep-when-using-tickless-idle/6266>\
**Category:** Kernel\
**Created:** [November 15, 2016, 10:23pm UTC](https://forums.freertos.org/t/preventing-entry-to-sleep-when-using-tickless-idle/6266 "2016-11-15T22:23:31Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 15, 2016, 10:23pm UTC](https://forums.freertos.org/t/preventing-entry-to-sleep-when-using-tickless-idle/6266/1 "2016-11-15T22:23:31Z")

</div>

**[bryce78](https://sourceforge.net/u/bryce78/)** wrote on [Tuesday, November 15, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/0bded84a/#ce27):

Hello Community,

I have a question about preventing (“turning off”) entry to sleep during specific idle periods. For example, suppose I am performing a network provisioning task which involves a lot of waiting during which the MCU could go to sleep. But, for simplicity and to prevent continuous sleep-wake cycles, I wish to have the idle task run (skipping entry to sleep mode) until the network provisioning completes or timesout. Essentially I would like to control (select) either entry to low-power sleep, or simply remain idling.

Here is a little background on my project: I am using Keil uVision v5.20 for development with FreeRTOS v9.0.0 on STM32L471 ARM Cortex M4 MCU. My RTOS project defines 5 tasks, 4 of which use a Queue and wait for events to process, and the fifth uses Task Notifications to block until something happens. Some relevant configuration:

```auto
#define configOVERRIDE_DEFAULT_TICK_CONFIGURTION 1
#define configUSE_TICKLESS_IDLE 2
#define configUSE_IDLE_HOOK 0

```

I use 32.768kHz oscillator to drive low-power timer and generate the RTOS tick. I have the RTOS tick independent of the MCU SYSCLK so I can achieve longer sleep periods, and also I need to keep SYSCLK running at a low frequency while in SLEEP. To do all this I had to implemented my own portSUPPRESS\_TICKS\_AND\_SLEEP() for tickless idle.

Back to the question of selecting either idle or sleep: I am thinking of introducing a simple global variable into the idle task which will determine whether the tickless idle code is skipped or run.

I think it’s pretty simple but wouldn’t mind a little feedback about this approach or more generally how to control entry to sleep mode. (For example, if portSUPPRESS\_TICKS\_AND\_SLEEP() is to be skipped, perhaps I should call vApplicationIdleHook() to increment an idle time counter that could be cleared when any task wakes. It could be used to ensure a “minimum idle time” before allowing entry to sleep in general circumstances.)

Thanks for any suggestions!  
Bryce

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 15, 2016, 11:31pm UTC](https://forums.freertos.org/t/preventing-entry-to-sleep-when-using-tickless-idle/6266/2 "2016-11-15T23:31:14Z")

</div>

**[edwards3](https://sourceforge.net/u/edwards3/)** wrote on [Tuesday, November 15, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/0bded84a/#b5af):

The expected way would be to define a portPRE\_SLEEP\_PROCESSING( x ) macro in FreeRTOSConfig.h. If sleep should not be entered set x to 0 in the macro.

What does setting configUSE\_TICKLESS\_IDLE to 2 do?

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 16, 2016, 12:25am UTC](https://forums.freertos.org/t/preventing-entry-to-sleep-when-using-tickless-idle/6266/3 "2016-11-16T00:25:34Z")

</div>

**[bryce78](https://sourceforge.net/u/bryce78/)** wrote on [Wednesday, November 16, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/0bded84a/#b5af/9f63):

Thanks for the reply!

Ah, yes, now I see that option to set x = 0 and cause the sleep to be skipped. I think that could work – though the code will run right “up to” the sleep instruction and skip at the last possible chance. I think I’m looking for something a bit more “coarse” – i.e. not stop the scheduler at all. I will keep this in mind and trying some other options. Thanks for reminding me of this possibility.

The #define configUSE\_TICKLESS\_IDLE 2 setting doesn’t add anything – from what I saw looking at the code it just ensures the default vPortSetupTimerInterrupt() and portSUPPRESS\_TICKS\_AND\_SLEEP() and anything related to the default config\_USE\_TICKLESS\_IDLE == 1 setting (which assumes that SysTick is the source for RTOS tick) _isn’t_ compiled. According to website notes it appropriate when defining your own clock other than SysTick to generate the RTOS tick interrupt. There’s some notes about it [here](http://www.freertos.org/low-power-ARM-cortex-rtos.html) and [here](http://www.freertos.org/low-power-tickless-rtos.html).

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 16, 2016, 12:52am UTC](https://forums.freertos.org/t/preventing-entry-to-sleep-when-using-tickless-idle/6266/4 "2016-11-16T00:52:55Z")

</div>

**[bryce78](https://sourceforge.net/u/bryce78/)** wrote on [Wednesday, November 16, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/0bded84a/#fc53):

To be more clear, I’m thinking more of an higher “application level” approach to preventing the idle task from entering into sleep, rather than lower “RTOS level”. For example, during configuration of peripherals or devices there might be periods of idle (e.g. waiting for sensor to initialize), during which the application can be considered “busy waiting”.

Is it possible (safe?) to suspend the idle task using vTaskSuspend()? Any special considerations for doing that?

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 16, 2016, 1:15am UTC](https://forums.freertos.org/t/preventing-entry-to-sleep-when-using-tickless-idle/6266/5 "2016-11-16T01:15:04Z")

</div>

**[edwards3](https://sourceforge.net/u/edwards3/)** wrote on [Wednesday, November 16, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/0bded84a/#f3ec):

You must always have a task to run, so if you suspend the idle task you must have an application task that can run. If all the tasks are blocked or suspended it will crash.

This will help [http://www.freertos.org/a00021.html#xTaskGetCurrentTaskHandle](http://www.freertos.org/a00021.html#xTaskGetCurrentTaskHandle)

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 16, 2016, 1:22am UTC](https://forums.freertos.org/t/preventing-entry-to-sleep-when-using-tickless-idle/6266/6 "2016-11-16T01:22:15Z")

</div>

**[edwards3](https://sourceforge.net/u/edwards3/)** wrote on [Wednesday, November 16, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/0bded84a/#2924):

Correct link is [http://www.freertos.org/a00021.html#xTaskGetIdleTaskHandle](http://www.freertos.org/a00021.html#xTaskGetIdleTaskHandle)

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 16, 2016, 12:51pm UTC](https://forums.freertos.org/t/preventing-entry-to-sleep-when-using-tickless-idle/6266/7 "2016-11-16T12:51:05Z")

</div>

**[mrazoun](https://sourceforge.net/u/mrazoun/)** wrote on [Wednesday, November 16, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/0bded84a/#ce27/a001):

Hi,  
I asked few weeks ago maybe the same question. You can look : [https://sourceforge.net/p/freertos/discussion/382005/thread/063d54e8/](https://sourceforge.net/p/freertos/discussion/382005/thread/063d54e8/)  
The conclusion was that you can move the responsibily to sleep\_sleep which is EnergyMicro library function in our case. The usage of macros in FreeRTOS give you very strong possibilities.  
Thank’s to FreeRTOS developers.  
Zdenek

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 17, 2016, 5:24pm UTC](https://forums.freertos.org/t/preventing-entry-to-sleep-when-using-tickless-idle/6266/8 "2016-11-17T17:24:55Z")

</div>

**[bryce78](https://sourceforge.net/u/bryce78/)** wrote on [Thursday, November 17, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/0bded84a/#2924/663a):

Thanks for the info on what can happen if Idle task is suspended and there’s nothing to run! I’ll keep this information in mind!

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 18, 2016, 3:18am UTC](https://forums.freertos.org/t/preventing-entry-to-sleep-when-using-tickless-idle/6266/9 "2016-11-18T03:18:28Z")

</div>

**[bryce78](https://sourceforge.net/u/bryce78/)** wrote on [Friday, November 18, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/0bded84a/#ce27/a001/5dce):

Hello and thanks for the pointer to your thread! Definitely it’s a question on the same topic. I’ve had a read from your thread and got further ideas! Plenty to work with now 🙂

---

<div class="post-metadata">

**Author:** ![McuOnEclipse](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/mcuoneclipse/32/32_2.png) [@McuOnEclipse](https://forums.freertos.org/u/McuOnEclipse)\
**Post date:** [November 18, 2016, 6:39am UTC](https://forums.freertos.org/t/preventing-entry-to-sleep-when-using-tickless-idle/6266/10 "2016-11-18T06:39:46Z")

</div>

**[xz8987f](https://sourceforge.net/u/xz8987f/)** wrote on [Friday, November 18, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/0bded84a/#cbfd):

Hi Bryce,  
I had the problem that I need to prevent entering low power or tickless idle mode in case there is some communication pending (e.g. UART). For this I have extended FreeRTOS with two defines:

```auto
#define configUSE_TICKLESS_IDLE_DECISION_HOOK 1 /* set to 1 to enable application hook, zero otherwise */
#define configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME xEnterTicklessIdle /* function name of decision hook */

```

The first one turns on an extra hook, and the second one provides the name.

You can find an implementation on GitHub here: [https://github.com/ErichStyger/Hexiwear\_v2/tree/master/KDS/Hexiwear\_SDKv2/freertos/Source](https://github.com/ErichStyger/Hexiwear_v2/tree/master/KDS/Hexiwear_SDKv2/freertos/Source)

The extension is in task.c

> <https://github.com/ErichStyger/Hexiwear_v2/blob/master/KDS/Hexiwear_SDKv2/freertos/Source/tasks.c>

  
around line 3336:

```auto
		/* This conditional compilation should use inequality to 0, not equality
		to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when
		user defined low power mode	implementations require
		configUSE_TICKLESS_IDLE to be set to a value other than 1. */
		#if ( configUSE_TICKLESS_IDLE != 0 )
		#if configUSE_TICKLESS_IDLE_DECISION_HOOK /* << EST */
		if (configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME()) /* ask application if it shall enter tickless idle mode */
		#endif
		{
		TickType_t xExpectedIdleTime;

			/* It is not desirable to suspend then resume the scheduler on
			each iteration of the idle task. Therefore, a preliminary
			test of the expected idle time is performed without the
			scheduler suspended. The result here is not necessarily
			valid. */
xExpectedIdleTime = prvGetExpectedIdleTime();

```

Basically this extra hook allows the application to decide if the idle (and low power) mode really shall be entered. That approach worked really well for me. See as well [https://mcuoneclipse.com/2014/02/09/iot-freertos-down-to-the-micro-amps/](https://mcuoneclipse.com/2014/02/09/iot-freertos-down-to-the-micro-amps/) and [https://mcuoneclipse.com/2013/07/06/low-power-with-freertos-tickless-idle-mode/](https://mcuoneclipse.com/2013/07/06/low-power-with-freertos-tickless-idle-mode/)

I hope this helps,  
Erich

---

<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:** [November 18, 2016, 7:46pm UTC](https://forums.freertos.org/t/preventing-entry-to-sleep-when-using-tickless-idle/6266/11 "2016-11-18T19:46:24Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Friday, November 18, 2016](https://sourceforge.net/p/freertos/discussion/382005/thread/0bded84a/#cbfd/e9ee):

I think there might be an easier way because  
portSUPPRESS\_TICKS\_AND\_SLEEP() is declared in a way that allows the user  
to override its default implementation by providing their own.

The default definition is as follows:

```
#ifndef portSUPPRESS_TICKS_AND_SLEEP
     extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
     #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) 
vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif
```

To override the definition you can add your own implementation of  
portSUPPRESS\_TICKS\_AND\_SLEEP into FreeRTOSConfig.h, and can use that  
definition to decide if you want to go into sleep mode or not.  
Something like the following to be added to FreeRTOSConfig.h:

```
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) \
     if( AppWantsToEnterSleepMode() == pdTRUE ) \
     { \
         vPortSuppressTicksAndSleep( xExpectedIdleTime ); \
     }
```
