Skip to end of metadata
Go to start of metadata

You are viewing an old version of this content. View the current version.

Compare with Current View Version History

« Previous Version 14 Next »

The Clock Tick section established that µC/OS-II requires (as do most kernels) that you provide a periodic interrupt to keep track of time delays and timeouts. This periodic time source is called a clock tick and should occur between 10 and 1,000 times per second, or Hertz. The actual frequency of the clock tick depends on the desired tick resolution of your application. However, the higher the frequency of the ticker, the higher the overhead.

The section  Interrupts Under µC/OS-II  discussed the tick ISR (Interrupt Service Routine) as well as the function that it needs to call to notify µC/OS-II about the tick interrupt — OSTimeTick() .

Contents of this Section

Time Services

This chapter describes five services that deal with time issues:

  • OSTimeDly()
  • OSTimeDlyHMSM()
  • OSTimeDlyResume()
  • OSTimeGet()
  • OSTimeSet()

The functions described in this chapter are found in the file OS_TIME.C.

Some of the time management services must be enabled by seting configuration constants in OS_CFG.H. Specifically, table 5.1 shows which services are compiled based on the value of configuration constants found in OS_CFG.H.

Delaying a Task, OSTimeDly()

µC/OS-II provides a service that allows the calling task to delay itself for a user-specified number of clock ticks. This function is called OSTimeDly(). Calling this function causes a context switch and forces µC/OS-II to execute the next highest priority task that is ready to run. The task calling OSTimeDly() is made ready to run as soon as the time specified expires or if another task cancels the delay by calling OSTimeDlyResume(). Note that this task will run only when it’s the highest priority task.

Listing 5.1 shows the code for OSTimeDly(). Your application calls this function by supplying the number of ticks to delay — a value between 1 and 65535. A value of 0 specifies no delay.It is important to realize that the resolution of a delay is between zero and one tick. In other words, if you try to delay for only one tick, you could end up with an intermediate delay between 0 and 1 tick. This is assuming, however, that your processor is not heavily loaded. Figure 5.1 illustrates what happens.

Delaying a Task, OSTimeDlyHMSM()

OSTimeDly() is a very useful function, but your application needs to know time in terms of ticks. You can use the global #define constant OS_TICKS_PER_SEC (see OS_CFG.H) to convert time to ticks by declaring some #defines as follows:

#define  OS_TIME_100mS  (INT16U)((INT32U)OS_TICKS_PER_SEC * 100L / 1000L)
#define  OS_TIME_500mS  (INT16U)((INT32U)OS_TICKS_PER_SEC * 500L / 1000L)
#define  OS_TIME_2S     (INT16U)(OS_TICKS_PER_SEC * 2)

However, this is somewhat awkward. I added the function OSTimeDlyHMSM() so that you can specify time in hours (H), minutes (M), seconds (S), and milliseconds (m), which is more natural. Like OSTimeDly(), calling this function causes a context switch and forces µC/OS-II to execute the next highest priority task that is ready to run. The task calling OSTimeDlyHMSM() is made ready to run as soon as the time specified expires or if another task cancels the delay by calling OSTimeDlyResume() [see section 5.02, Resuming a Delayed Task, OSTimeDlyResume()]. Again, this task runs only when it again becomes the highest priority task. Listing 5.2 shows the code for OSTimeDlyHMSM(). As you can see, your application calls this function by supplying the delay in hours, minutes, seconds, and milliseconds. In practice, you should avoid delaying a task for long periods of time because it’s always a good idea to get some feedback activity from a task (increment a counter, blink an LED, etc.). However, if you do need long delays, µC/OS-II can delay a task for 256 hours (close to 11 days).

Resuming a Delayed Task, OSTimeDlyResume()

Instead of waiting for time to expire, a delayed task can be made ready to run by another task that cancels the delay. This is done by calling OSTimeDlyResume() and specifying the priority of the task to resume. In fact, OSTimeDlyResume() also can resume a task that is waiting for an event (see Chapters 7 through 11), although this is not recommended. In this case, the task pending on the event thinks it timed out waiting for the event.

The code for OSTimeDlyResume() is shown in Listing 5.3.Note that you could also have a task delay itself by waiting on a semaphore, mutex, event flag, mailbox, or queue with a timeout (see Chapters 7 through 11). You would resume such a task by simply posting to the semaphore, mutex, event flag, mailbox, or queue, respectively. The only problem with this scenario is that it requires you to allocate an event control block (see section 6.00), so your application would consume a little bit more RAM.

System Time, OSTimeGet() and OSTimeSet()

Whenever a clock tick occurs, µC/OS-II increments a 32-bit counter. This counter starts at zero when you initiate multitasking by calling OSStart() and rolls over after 4,294,967,295 ticks. At a tick rate of 100Hz, this 32-bit counter rolls over every 497 days. You can obtain the current value of this counter by calling OSTimeGet(). You can also change the value of the counter by calling OSTimeSet(). The code for both functions is shown in Listing 5.4. Note that interrupts are disabled when accessing OSTime. This is because incrementing and copying a 32-bit value on most 8-bit processors requires multiple instructions that must be treated indivisibly.

  • No labels