# Implementing tickless idle on Cortex M4. 

**URL:** <https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603>\
**Category:** Kernel\
**Created:** [November 9, 2013, 3:39am UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603 "2013-11-09T03:39:27Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [September 16, 2014, 5:53am UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/21 "2014-09-16T05:53:40Z")

</div>

**[hilt0n](https://sourceforge.net/u/hilt0n/)** wrote on [Tuesday, September 16, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/72d095e3/#0cde):

Ha yes sorry, you need to add:  
#define CONF\_BOARD\_EIC  
in config/conf/board.h to unmask EIC gpio mux init in board init file.

---

<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, 2014, 10:38am UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/22 "2014-09-16T10:38:20Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Tuesday, September 16, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/72d095e3/#35ad):

Please try the following, then report back:

1. Find the function prvEnableAST() in SAM4L\_low\_power\_tick\_management().

2. Add the following line to the top of the function: “ast\_write\_counter\_value( AST, 0 );”

Regards.

---

<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, 2014, 12:22pm UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/23 "2014-09-16T12:22:15Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Tuesday, September 16, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/72d095e3/#bd19):

Actually - instead try the attached. Only one line different from the current release.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [September 16, 2014, 12:36pm UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/24 "2014-09-16T12:36:23Z")

</div>

**[hilt0n](https://sourceforge.net/u/hilt0n/)** wrote on [Tuesday, September 16, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/72d095e3/#52c6):

Ok thank you, I have found the same solution than you (reset the AST counter when the uC is awakened by external interrupt) however, I have sometimes some problems with timing and fall into the assert of the function vTaskStepTick because the actual time is bigger than the next unblock time.

Have you an idea, a direction to find the problem ?

Best regards

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [September 18, 2014, 9:54pm UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/25 "2014-09-18T21:54:22Z")

</div>

**[jpt106](https://sourceforge.net/u/jpt106/)** wrote on [Thursday, September 18, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/72d095e3/#e12c):

I believe I found the issue. The AST counter was not being reset and updated correctly. I was able to reliable reproduce the problem and the attached file fixes the issue on my system.

---

<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, 2014, 8:46am UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/26 "2014-09-19T08:46:35Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Friday, September 19, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/72d095e3/#9c3d):

Are you saying the fix I already posted did not fix your problem?

Regards.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [September 22, 2014, 2:33pm UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/27 "2014-09-22T14:33:51Z")

</div>

**[jpt106](https://sourceforge.net/u/jpt106/)** wrote on [Monday, September 22, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/72d095e3/#499c):

Sorry I was not clear. Yes the fix posted made the problem happen less often but I was to reproduce the issue still. I am using tickless configuration in my system. There is a task that runs periodically every 8 ticks (62.5 milliseconds). There is CLI interface through a UART. From the CLI I run different commands that cause other tasks to run processing the request for the CLI command. For testing, I have a script that continuously runs different CLI commands. This causes the other tasks to randomly run and generate other interrupts beside the AST interrupt.

Without your fix posted, running the test script my system fails the assert “configASSERT( ( xTickCount + xTicksToJump ) \<= xNextTaskUnblockTime )” within a minute. With the posted fix, it takes about 10 minutes running the test script.

Originally I found when the system was failing it was calculating a negative alarm value and programming that negative value into the alarm for the AST. The code I posted tried to prevent the negative alarm value issue. After further investigation, I found the root cause of the issue. The AST clear counter on alarm does not clear the counter on the same AST clock cycle as when the counter equals the alarm. The counter gets reset to one on the next clock cycle when the counter exceeds the alarm value. This caused a race condition where during the time of single AST clock cycle (61 microseconds) the counter equals the alarm value. I saw during debugging in the code “if( ulTickFlag != pdFALSE)”  
where ast\_read\_counter\_value( AST ) returned the same value as the alarm value. This caused a negative value to be calculated for ulAlarmValue.

The newly posted code fixes the root cause directly by detected when the race condition happens and taking action.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [September 29, 2014, 7:00pm UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/28 "2014-09-29T19:00:03Z")

</div>

**[hilt0n](https://sourceforge.net/u/hilt0n/)** wrote on [Monday, September 29, 2014](https://sourceforge.net/p/freertos/discussion/382005/thread/72d095e3/#d8cd):

Thanks Joe for your big work, I didn’t yet tested completely your solution but that sound promising.  
On my side, I have simply took the tickless implementation of the STM32L, it’s very similar to the SAM4L but there is 3 missing asynchronous counter clear on the SAM4L. I actually wonder why this porting difference…

---

<div class="post-metadata">

**Author:** ![Nil](https://avatars.discourse-cdn.com/v4/letter/n/a183cd/32.png) [@Nil](https://forums.freertos.org/u/Nil)\
**Post date:** [June 23, 2022, 3:24pm UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/29 "2022-06-23T15:24:03Z")

</div>

Hello Joe. I read that you posted fix for “negative value of Alarm 0” but unfortunately didn’t found where is particular. Would you help me to see that? 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:** [June 23, 2022, 4:52pm UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/30 "2022-06-23T16:52:13Z")

</div>

You are replying to an 8-year old post. Can you describe the issue you are having? Have you tried the latest code?

---

<div class="post-metadata">

**Author:** ![Nil](https://avatars.discourse-cdn.com/v4/letter/n/a183cd/32.png) [@Nil](https://forums.freertos.org/u/Nil)\
**Post date:** [June 23, 2022, 6:13pm UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/31 "2022-06-23T18:13:23Z")

</div>

I modifiting now a project of 2014 year basis on GCC - Freertos 8.1.2 - ATSAM4LS and have a problem with LOW POWER DEMO(TICKLESS IDLE). I can see problem existed before and previous engineer make modification of “tick\_mangmet.c”, this reduce frequency of problem but not fixed compleat. After ~30 minutes in RUN OS will supress ticks for almost maximum period of counter (68174084 ticks \* 3.85mS), however one of the my task should to be done regularly and has only 100mS delay. Next - no one task go to running. Also after interrupt on push button (GPIO) system wake up but no one task RUN, only interupts works. So, I have two points:

1. My application has not problem when LOW POWER DEMO is disable
2. I took only “tick\_mangmet.c” file from newest freertos version and replaced with them file in my project with the same name. But problem not disappear and looks simillar.

Would you suggest what is best thing of this situation?  
I compare my version of FreeRTOS and last. A lot of code different at “port.c” file. System Core is changed.

Is it possible to replace only one file “tick\_mangmet.c”, or is it necessary to update all files of the operating system to completely solve the problem with the tick suppression mode?

Thank you!

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [June 24, 2022, 6:02am UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/32 "2022-06-24T06:02:20Z")

</div>

> [@Nil](#):
>
> Is it possible to replace only one file “tick\_mangmet.c”, or is it necessary to update all files of the operating system to completely solve the problem with the tick suppression mode?

I am not familiar with this specific file but I’d suggest to update all the files as that is tested and known to work. Is it possible for you to update all the files?

---

<div class="post-metadata">

**Author:** ![Nil](https://avatars.discourse-cdn.com/v4/letter/n/a183cd/32.png) [@Nil](https://forums.freertos.org/u/Nil)\
**Post date:** [June 24, 2022, 6:45am UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/33 "2022-06-24T06:45:43Z")

</div>

Updating all files of the operating system is of course possible, but time-consuming, because I need to compare all the configuration settings. And another important point: in the latest version of FreeRTOS in the demo project to suppress ticks ATSAM4L, the AST(asynchronous timer) is clocked from an external crystal oscillator at 32 kHz, but in old version FreeRTOS - from the internal RC at the same frequency. Do you think this is an important difference or not?

---

<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:** [June 24, 2022, 7:11am UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/34 "2022-06-24T07:11:10Z")

</div>

The external crystal is probably more accurate.

---

<div class="post-metadata">

**Author:** ![Nil](https://avatars.discourse-cdn.com/v4/letter/n/a183cd/32.png) [@Nil](https://forums.freertos.org/u/Nil)\
**Post date:** [June 28, 2022, 8:08am UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/35 "2022-06-28T08:08:13Z")

</div>

I updated OS files and I was surprised that for my ATSAM4L (CortexM4 with MPU) should take port.c and other files from “ARM\_CM3” directory, but NOT from “ARM\_CM4\_MPU”!

1. What is the reason for this file location?

After update OS to last version I have the same wrong behaviour of my application in TICKLESS\_MODE if “configTICK\_RATE\_HZ = 256”, BUT my application works stable ( means OS does not sleep for a wrong long time = 72 hours ) if “configTICK\_RATE\_HZ = 128” ( exectly like at DEMO project orginal).

1. Could you tell me - for the stable operation of the system in the “tickless mode”, how important is this time interval exactly equals 128 and not equaling 256 for “configTICK\_RATE\_HZ” parameter?

---

<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:** [June 28, 2022, 6:26pm UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/36 "2022-06-28T18:26:49Z")

</div>

If you aren’t using the MPU, then using the non-MPU version will be smaller and a bit faster. The M3 and the M4 as far as the software is concerned are the same, the M4 just has options for an FPU and an MPU, so if not using them you just use the M3 port.

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [June 29, 2022, 5:50am UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/37 "2022-06-29T05:50:41Z")

</div>

> [@Nil](#):
>
> “ARM\_CM3” directory, but NOT from “ARM\_CM4\_MPU”!

As Richard mentioned, if you are not using MPU, you should use ARM\_CM4F. If you are not using FPU also, you can use ARM\_CM3.

> [@Nil](#):
>
> Could you tell me - for the stable operation of the system in the “tickless mode”, how important is this time interval exactly equals 128 and not equaling 256 for “configTICK\_RATE\_HZ” parameter?

I believe you are not using SysTick for tick interrupt - can you check how `configTICK_RATE_HZ` is used in your ISR configuration and if that can have any impact?

---

<div class="post-metadata">

**Author:** ![Nil](https://avatars.discourse-cdn.com/v4/letter/n/a183cd/32.png) [@Nil](https://forums.freertos.org/u/Nil)\
**Post date:** [June 30, 2022, 8:45am UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/38 "2022-06-30T08:45:18Z")

</div>

> [@aggarg](#):
>
> SysTick

Dear Guarav,  
I don’t use **SystemTimer** and **SysTickInterrupt** for context switch, but I use Asynchronous Timer of ATSAM4L which clocking from an external 32 kHz generator (AST) and its exeption “Alarm0” for set bit “portNVIC\_PENDSVSET\_BIT” and hence to calling “PortPendSVHandler” for context switch.

My settings the absolutely the same like on DEMO project:  
#define configCREATE\_LOW\_POWER\_DEMO 1

#if configCREATE\_LOW\_POWER\_DEMO == 1  
#define configCPU\_CLOCK\_HZ 16384  
#define configSYSTICK\_CLOCK\_HZ 16384  
#define configUSE\_TICKLESS\_IDLE 1  
#define configTICK\_RATE\_HZ ((os\_tick\_type\_t)128)

/\* Calculate how many clock increments make up a single tick period. \*/  
static const uint32\_t ulAlarmValueForOneTick = ( configSYSTICK\_CLOCK\_HZ / configTICK\_RATE\_HZ );

BUT if I customise #define configTICK\_RATE\_HZ ((os\_tick\_type\_t) **256** )  
I have the same problem like description in this chat by Richard Barry/jabad06/hilt0n/YanikL  
with “negative time” calculation for tickless idle task.

Remark:

1. I updated and now use the last version FREERTOS
2. I have not problem with my application when [use **SystemTimer** and **SysTickInterrupt** (#define configCREATE\_LOW\_POWER\_DEMO = 0)] OR [#define configCREATE\_LOW\_POWER\_DEMO=1 + configTICK\_RATE\_HZ = 128)]
3. I have to make a reliable and at the same time energy-saving device

As a result I would to know is it strict value **configTICK\_RATE\_HZ =128** setting for LOW\_POWER\_DEMO or I need looking for error in my application which appears only when configTICK\_RATE\_HZ = 256.

Thank you!

---

<div class="post-metadata">

**Author:** ![aggarg](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/aggarg/32/4245_2.png) [@aggarg](https://forums.freertos.org/u/aggarg)\
**Post date:** [June 30, 2022, 9:27am UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/39 "2022-06-30T09:27:41Z")

</div>

I do not think that tick frequency should cause this impact. Can you step through the `vPortSuppressTicksAndSleep` function in both the cases and try to see the difference?

---

<div class="post-metadata">

**Author:** ![jefftenney](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/jefftenney/32/1314_2.png) [@jefftenney](https://forums.freertos.org/u/jefftenney)\
**Post date:** [June 30, 2022, 6:18pm UTC](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/40 "2022-06-30T18:18:47Z")

</div>

Are you using [SAM4L\_low\_power\_tick\_management.c](https://github.com/FreeRTOS/FreeRTOS/blob/main/FreeRTOS/Demo/CORTEX_M4_ATSAM4L_Atmel_Studio/src/SAM4L_low_power_tick_management.c)? If so, it seems the issue [identified above](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603/27) has not been addressed.

Can you try this experiment?

[EXISTING CODE:](https://github.com/FreeRTOS/FreeRTOS/blob/cfb32b4f62ed2b4e1b3f70e807438860fa49195f/FreeRTOS/Demo/CORTEX_M4_ATSAM4L_Atmel_Studio/src/SAM4L_low_power_tick_management.c#L309-L316)

```auto
if( ulTickFlag != pdFALSE )
{
    /* The tick interrupt has already executed, although because this
    function is called with the scheduler suspended the actual tick
    processing will not occur until after this function has exited.
    Reset the alarm value with whatever remains of this tick period. */
    ulAlarmValue = ulAlarmValueForOneTick - ast_read_counter_value( AST );
    ast_write_alarm0_value( AST, ulAlarmValue );

```

PROPOSED EXPERIMENTAL CODE:

```auto
if( ulTickFlag != pdFALSE )
{
    /* The tick interrupt has already executed, although because this
    function is called with the scheduler suspended the actual tick
    processing will not occur until after this function has exited.
    Reset the alarm value with whatever remains of this tick period. */
    ulAlarmValue = ulAlarmValueForOneTick - ast_read_counter_value( AST );
    if( ulAlarmValue > ulAlarmValueForOneTick ) /* LINE ADDED */
    { /* LINE ADDED */
        ulAlarmValue = ulAlarmValueForOneTick; /* LINE ADDED */
    } /* LINE ADDED */
    ast_write_alarm0_value( AST, ulAlarmValue );

```

[Previous page](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603.md?page=1)

[Next page](https://forums.freertos.org/t/implementing-tickless-idle-on-cortex-m4/2603.md?page=3)
