System Time

Introduction

The concept of time in the context of a real time operating system was introduced in an earlier article, along with an idea of the facilities associated with time that likely to be available with an RTOS.

Clock Tick

All timing facilities are driven by a hardware clock. This is simply an oscillator that generates an interrupt at regular intervals. For timing numbers to be meaningful to applications programs, the frequency of the oscillator must be known.

Clock Interrupt Service Routine

The interrupts generated by the hardware clock must be handled appropriately by an interrupt service routine (ISR), which implements all the timing facilities of an RTOS. The details of the clock ISR in Nucleus SE will be covered in a future article.

Timing Facilities

Nucleus RTOS and Nucleus SE include a number of timing facilities:

  • A tick clock – This is a simple counter that is incremented by clock ISR. In both Nucleus RTOS and Nucleus SE this counter is 32 bits wide and there are facilities for tasks to set and read its value. In Nucleus SE the tick clock is optional. This topic is discussed in more detail in the remainder of this chapter.

  • Application timers – Both Nucleus RTOS and Nucleus SE support timer objects. Their use and implementation in Nucleus SE will be discussed in detail in the next article.

  • Time slice scheduling – In Nucleus RTOS, tasks of the same priority are scheduled on a round-robin basis, but a time slice may also be applied. In Nucleus SE, a time slice scheduler is an option; this was discussed in detail in an earlier article.

  • Task sleep. A task may elect to suspend itself (go to sleep) for a specified time period. This facility was described in detail in a previous article.

  • API call timeouts – In both Nucleus RTOS and Nucleus SE a number of API calls allow a task to suspend, pending the availability of a resource. This suspension may be indefinite, or, in Nucleus RTOS, an optional timeout period may be specified. API call timeouts are not supported in Nucleus SE.

Accuracy

A brief word about timing accuracy is worthwhile at this point.

The precision of a timing facility is totally dependent on the frequency of the clock oscillator. For example, if a pulse is received every 10 milliseconds and an application task wants to delay for 100 milliseconds, it clearly needs to wait for 10 pulses. However, it is not known when the previous pulse occurred – it may have been just now, or it could have been nearly 10 milliseconds ago. Hence a 100-millisecond delay could be as long as (just under) 110 milliseconds.

An obvious way to solve this problem is to increase the oscillator frequency. If the pulse were to occur at 1 millisecond intervals, the 100-millisecond delay would never be longer than 101 milliseconds. The downside is that 10 times as much CPU time would be spent in the clock ISR, which is an overhead.

The system designer must determine the balance between required timer accuracy and available CPU power.

Configuring System Time

As with most aspects of Nucleus SE, the configuration of system time is primarily controlled by #define statements in nuse_config.h . The key setting is NUSE_SYSTEM_TIME_SUPPORT , which enables the facility. There is no question of specifying the number of objects – system time is simply enabled or not.

Choosing a non-zero value is the “master enable” for system time. This causes a data structure to be defined, of which more later in this article. It also activates the API enabling settings.

API Enables

Every API function (service call) in Nucleus SE has an enabling #define symbol in nuse_config.h . For system time, these are:

NUSE_CLOCK_SET
NUSE_CLOCK_RETRIEVE

By default, both of these are set to FALSE , thus disabling each service call and inhibiting the inclusion of any implementation code. To configure system time for an application, you need to select the API calls that you want to use and set their enabling symbols to TRUE .

Here is an extract from the default nuse_config.h file.

#define NUSE_SYSTEM_TIME_SUPPORT FALSE    /* Enables the system                                             tick clock */#define NUSE_CLOCK_SET        FALSE    /* Service call enabler */#define NUSE_CLOCK_RETRIEVE   FALSE    /* Service call enabler */

A compile time error will result if a system time API function is enabled and the system time facility has not been enabled. If your code uses an API call, which has not been enabled, a link time error will result, as no implementation code will have been included in the application.

System Time Service Calls

Nucleus RTOS supports two service calls that appertain to system time, which provide the following functionality:

  • Set the system time value. Implemented by NUSE_Clock_Set() in Nucleus SE.

  • Obtain the system time value. Implemented by NUSE_Clock_Retrieve() in Nucleus SE.

The implementation of each of these service calls is examined in detail.

System Time Set and Obtain Services

The only operations, which can be performed on the system time value, are to set it to a value and obtain (retrieve) its current value. Nucleus RTOS and Nucleus SE each provide two basic API calls for these operations, which will be discussed here.

The interpretation of the system time value is application dependent, as it is simply a count of how many clock “ticks” there have been since the counter was last reset. To use this information, the frequency of the clock oscillator must be known.

Setting Time

Any task may set system time by making a call to this API function.

Nucleus RTOS API Call for Setting Time

Service call prototype:

VOID NU_Set_Clock(UNSIGNED new_value);

Parameters:

new_value – the value to which the system time is to be set

Returns:

none.

Nucleus SE API Call for Setting Time

This API call supports the key functionality of the Nucleus RTOS API.

Service call prototype:

void NUSE_Clock_Set(U32 new_value);

Parameters:

new_value – the value to which the system time is to be set

Returns:

none.

Nucleus SE Implementation of Setting Time

The code is very simple. The supplied value is just stored into NUSE_Tick_Clock within a critical section.

Retrieving Time

A task may obtain system time by making a call to this API function.

Nucleus RTOS API Call for Retrieving Time

Service call prototype:

UNSIGNED NU_Retrieve_Clock(VOID);

Parameters:

none

Returns:

the current system time value

Nucleus SE API Call for Retrieving Time

This API call supports the key functionality of the Nucleus RTOS API.

Service call prototype:

U32 NUSE_Clock_Retrieve(void);

Parameters:

none

Returns:

the current system time value

Nucleus SE Implementation of Retrieving Time

The code is very simple. The value of NUSE_Tick_Clock is obtained within a critical section and returned.

Data Structures

System time utilizes one data structure – in RAM – which is just a single 32-bit word.

I strongly recommend that application code does not access this data structure directly but uses the provided API functions. This avoids incompatibility with future versions of Nucleus SE and unwanted side-effects and simplifies porting of an application to Nucleus RTOS. The details of data structures are included here to facilitate easier understanding of the working of the service call code and for debugging.

RAM Data

The data structure is:

NUSE_Tick_Clock – This is a variable of type U32 where the system clock tick count is stored.

This data structure is initialized to zero by NUSE_Init_Task() when Nucleus SE starts up. A future article will provide a full description of Nucleus SE start-up procedures.

ROM Data

There are no ROM data structures associated with system time.

System Time Data Footprint

Like all aspects of Nucleus SE, the amount of data memory required for system time is readily predictable.

The ROM data footprint is 0.

The RAM data footprint (in bytes) is always 4.

Unimplemented API Calls

All Nucleus RTOS API calls that appertain to system time have an equivalent in Nucleus SE.

Compatibility with Nucleus PLUS

With all aspects of Nucleus SE, it was my goal to maintain as high a level of applications code compatibility with Nucleus RTOS as possible. System time is no exception, and, from a user’s perspective, it is implemented in much the same way as in Nucleus RTOS. The Nucleus RTOS API calls may be directly mapped onto Nucleus SE calls. A future article will include further information on using Nucleus SE for users of Nucleus RTOS.

The next RTOS Revealed article will look at application timers.


Colin Walls has nearly forty years’ experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles and two books on embedded software, Colin is an embedded software technologist with Mentor, a Siemens business, and is based in the UK. His regular blog is located at: http://blogs.mentor.com/colinwalls. He may be reached by email at colin_walls@mentor.com

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.