Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training


Enter Tickless Idle on portMAX_DELAY / Problem with xNextTaskUnblockTime holding wrong value.

Posted by christophneukom on November 3, 2014

I'm using FreerTOS 8.0.0 on a PIC24 and am attempting to use the tickless idle mode. It works fine except for one thing I don't quite understand.

FreeRTOS is used for a simple data logger which is in sleep mode most of the time. It wakes up on an RTCC alarm every 10 seconds and takes a measurement which should take around 200ms. There are multiple UART interfaces used for communication during the measurement phase using queues to report their status to the main task. In the main task I'm using xQueueReceive timeouts to block until data has been sent or received by the UART drivers. Once the measurement is done, the main task blocks indefinitely on a semaphore given by the RTCC alarm ISR.

What I see happen is that the system does not call portSUPPRESSTICKSANDSLEEP() immediately after the main task blocks, but stays awake for the last used timeout time that was unequal to portMAXDELAY.

When stepping through the code with the debugger I can see that the main task is placed in the overflow list when calling xSemaphoreTake( intervaltimer, portMAXDELAY ). In this case NextTaskUnblockTime is not changed and still holds the timeout time from the last xQueueReceive call from one of the UART drivers. When moving on to portTASKFUNCTION(), the tickless idle feature checks xExpectedIdleTime which is equal to xNextTaskUnblockTime and still holds the previous timeout time instead of portMAXDELAY. Once the system was idle for xNextTaskUnblockTime, its value gets updated and the system finally enters sleep mode.

To me it seems to be a problem with blocking on portMAX_DELAY and xNextTaskUnblockTime not getting updated in that case. Is there something I'm missing?

As workaround I could set configEXPECTEDIDLETIMEBEFORESLEEP lower than my last timeout time or insert a vTaskDelay(0) before my infinite block to force-update xNextTaskUnblockTime, but those aren't solutions I'm keen to use.

Thanks, Chris

Enter Tickless Idle on portMAX_DELAY / Problem with xNextTaskUnblockTime holding wrong value.

Posted by rtel on November 3, 2014

Interesting - I will have to look into this scenario. It is understandable that the main task gets placed into the overflow list if you are using a max delay, at that point the idea would be (assuming no other tasks have shorter delays) for the next wake time to be at the time the in-use and overflow lists get switched.


Enter Tickless Idle on portMAX_DELAY / Problem with xNextTaskUnblockTime holding wrong value.

Posted by rtel on November 7, 2014

So looking at this....xNextTaskUnblockTime is updated when it is either reached (at which point it is reset to the next value), or when it is moved closer in time by a task blocking with a block period that is shorted than the current xNextTaskUnblockTime value. If the actual next unblock time is moved back in time xNextTaskUnblockTime is not updated because, when the xNextTaskUnblockTime value is reached, it will automatically get corrected without the integrity of the system being compromised. That is, there will be one wasted call to vTaskSwitchContext(), but the scheduling pattern and timing will still be correct. In the 'normal' case that is deemed to be the best solution as the expense of constantly resetting the value each time a task blocks is greater.

So that is fine for most applications, but for low power tickless applications it can have the effect of delaying the time at which the tick is turned off, so depending on the application it might not be fine if entry into sleep mode at the earliest possible time is a key system requirement.

The question then is what to do about it. prvResetNextTaskUnblockTime() could be called from vTaskPlaceOnEventList(), or even prvAddCurrentTaskToDelayedList() [I would have to work through the examples to see which was most appropriate], but if that were done I think it should be guarded by the pre-processor, so the additional calls to prvResetNextTaskUnblockTime() only got compiled in when configUSETICKLESSIDLE was set to 1 - otherwise it will add expense to non-low power applications for no good reason.

Does that match with your own assessment?


Enter Tickless Idle on portMAX_DELAY / Problem with xNextTaskUnblockTime holding wrong value.

Posted by rtel on November 8, 2014

Having discussed this we are considering adding the following code to the very end of xTaskRemoveFromEventList(). It is not tested yet. Please comment on this with respect to your application:

#if( configUSE_TICKLESS_IDLE == 1 )
  /* If a task is blocked on a kernel object then 
  xNextTaskUnblockTime might be set to the blocked 
  task's time out time.  If the task is unblocked for 
  a reason other than a timeout xNextTaskUnblockTime is
  normally left unchanged, because it will automatically 
  get reset to a new value when the tick count equals   
  xNextTaskUnblockTime.  However if tickless idling is 
  used it might be more important to enter sleep mode
  at the earliest possible time - so reset 
  xNextTaskUnblockTime here to ensure it is updated at 
  the earliest possible time. */

Enter Tickless Idle on portMAX_DELAY / Problem with xNextTaskUnblockTime holding wrong value.

Posted by christophneukom on November 11, 2014

I've just tested my device with the modification and compared it to the old revision. It seems to solve the problem, the device now goes to sleep immediately after the last task is blocked on max delay.

Amazing support, thanks a lot!

[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]

Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.

Free TCP/IP and file system demos for the RTOS

Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑

FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists