Keil Logo

ARM: RTOS delay accuracy

Information in this knowledgebase article applies to:



In our RTOS based application we use delay functions provided by the RTOS. However, when we verify the actually passed time until the delayed thread continues, we noticed, that time is always shorter than the specified timeout. This is particularly critical, when the minimal possible timeout 1 was specified in the delay function call. Examples are:

osDelay(/* in ms */ 1) ;  /* in CMSIS RTOS */
os_dly_wait(/* in ticks */ 1) ;  /* in KEIL RL-ARM RTX */

Then we see, sometimes the actual timeout is almost 0, which is shorter than the actually required timeout. What is the reason for this?


The RTOS has a minimal time resolution of the tick interval time, which is specified in the RTOS configuration. It can only execute delays, which count in n multiple of this time. On each completed tick interval the delay count gets decremented by 1 and if it reaches 0, the timeout is expired and the delayed thread resumes.

The call to the delay function happens now somewhere in the middle of this tick interval. So the first waited interval is not a complete tick interval time, but only the rest of the current tick interval time. This can also be almost no time until the next tick happens, which also explains the observed behaviour.


To wait at least the minimal specifiable delay time, add the time equivalent of 1 tick interval to the requested timeout. It can look like this:

osDelay((1 + (OS_TICK /* from RTX config */ + 1000 - 1) / 1000) ;  /* in CMSIS RTOS */
os_dly_wait(1 /* rest of current tick */ + 1) ;  /* in KEIL RL-ARM RTX */

Or, if you require more accurate time, use custom wait functions.


The CMSIS-RTOS version 4.80, which was released with the CMSIS pack 4.5.0, reverts the change made in the previous version 4.79. From now on the timeouts will be handled again as in CMSIS-RTOS version 4.78 and before. So, the actual timeout will be shorter than the requested timeout, as discussed in this article. See also the CMSIS-RTOS revision history for reference.
To retain the behaviour of CMSIS-RTOS version 4.79, the CMSIS RTOS source can be edited to guarantee a minimum delay time, in the function, rt_ms2tick(), defined in rt_CMSIS.c:

tick = (((1000U * millisec) + os_clockrate - 1U)  / os_clockrate) + 1 /*4.79 adds 1*/;

The CMSIS-RTOS version 4.79, which was released with the CMSIS pack 4.4.0, behaves uniquely, enforcing a minimum. In this version the internal ms to tick conversion adds 1 tick to the result, which makes sure the program waits at least the requested timeout without needing to adjust the timeout parameter in the application. See also the CMSIS-RTOS revision history for reference.



The following Discussion Forum threads may provide information related to this topic.

Last Reviewed: Wednesday, January 25, 2017

Did this article provide the answer you needed?
Not Sure
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.