µC/OS-III provides a number of services to manage time as summarized in the table below, and the code is found in os_time.c
.
The application programmer should refer to µC-OS-III API Reference for a detailed description of these services.
OSTimeDly() – Delay a Task
A task calls this function to suspend execution until some time expires. The calling function will not execute until the specified time expires. This function allows three modes: relative, periodic and absolute.
The listing below shows how to use OSTimeDly()
in relative mode.
As mentioned above, the delay is not accurate. Refer to the figure below and its description below to understand why.
OSTimeDly()
can also be called with the OS_OPT_TIME_PERIODIC
option as shown in the listing below . This option allows delaying the task until the tick counter reaches a certain periodic match value and thus ensures that the spacing in time is always the same as it is not subject to CPU load variations.
µC/OS-III determines the “match value” of OSTickCtr
to determine when the task will need to wake up based on the desired period. This is shown in the figure below. µC/OS-III checks to ensure that if the match is computed such that it represents a value that has already gone by then, the delay will be zero.
Relative and Periodic modes might not look different, but they are. In Relative mode, it is possible to miss one of the ticks when the system is heavily loaded, missing a tick or more on occasion. In Periodic mode, the task may still execute later, but it will always be synchronized to the desired number of ticks. In fact, Periodic mode is the preferred mode to use to implement a time-of-day clock.
Finally, you can use the absolute mode to perform a specific action at a fixed time after power up. For example, turn off a light 10 seconds after the product powers up. In this case, you would specify OS_OPT_TIME_MATCH
while “dly
” actually corresponds to the desired value of OSTickCtr
you want to reach. However, you should use the OS_OPT_TIME_MATCH
with care because somewhere else in your code you can change the value of OSTickCtr
by calling OSTimeSet()
as described in Time Services.
To summarize, the task will wake up when OSTickCtr
reaches the following value:
Value of “opt” | Task wakes up when |
---|---|
OS_OPT_TIME_DLY | OSTickCtr + dly |
OS_OPT_TIME_PERIODIC | OSTCBCurPtr->TickCtrPrev + dly |
OS_OPT_TIME_MATCH | dly |
OSTimeDlyHMSM() – Delay a Task for a Specified Time
If enabled, a task may call this function to suspend execution until some time expires by specifying the length of time in a more user-friendly way. Specifically, you can specify the delay in hours, minutes, seconds, and milliseconds (thus the HMSM
). This function only works in “Relative” mode.
The listing below indicates how to use OSTimeDlyHMSM()
.
Even though µC/OS-III allows for very long delays for tasks, it is actually not recommended to delay tasks for a long time. The reason is that there is no indication that the task is actually “alive” unless it is possible to monitor the amount of time remaining for the delay. It is better to have the task wake up approximately every minute or so, and have it “tell you” that it is still ok.
OSTimeDly()
is often used to create periodic tasks (tasks that execute periodically). For example, it is possible to have a task that scans a keyboard every 50 milliseconds and another task that reads analog inputs every 10 milliseconds, etc.
OSTimeDlyResume() – Resume a Delayed Task
A task can resume another task that called OSTimeDly()
or OSTimeDlyHMSM()
by calling OSTimeDlyResume()
. The listing below shows how to use OSTimeDlyResume()
. The task that delayed itself will not know that it was resumed, but will think that the delay expired. Because of this, use this function with great care.
OSTimeGet() – Get Value of the Tick Counter
µC/OS-III increments a tick counter every time a tick interrupt occurs. This counter allows the application to make coarse time measurements and have some notion of time (after power up).
OSTimeGet()
allows the user to take a snapshot of the tick counter. You can use this value to delay a task for a specific number of ticks and repeat this periodically without losing track of time.
OSTimeSet()
allows the user to change the current value of the tick counter. Although µC/OS-III allows for this, it is recommended to use this function with great care especially if you use ‘match’ time delays.
OSTimeSet() and OSTimeGet()
µC/OS-III increments a tick counter every time a tick interrupt occurs. This counter allows the application to make coarse time measurements and have some notion of time (after power up).
OSTimeGet()
allows the user to take a snapshot of the tick counter. You can use this value to delay a task for a specific number of ticks and repeat this periodically without losing track of time.
OSTimeSet()
allows the user to change the current value of the tick counter. Although µC/OS-III allows for this, it is recommended to use this function with great care especially if you use ‘match’ time delays.
OSTimeTick() – Signal a Clock Tick
The tick Interrupt Service Routine (ISR) must call this function every time a tick interrupt occurs. μC/OS-III uses this function to update time delays and timeouts used by other system calls. OSTimeTick() is considered an internal function to μC/OS-III.
OSTimeDynTick() – Signal multiple Ticks (Dynamic Tick Mode Only)
The dynamic tick Interrupt Service Routine (ISR) must call this function with the number of ticks that timer was last configured to delay. μC/OS-III uses this function to update time delays and timeouts used by other system calls. OSTimeDynTick() is considered an internal function to μC/OS-III.