Using C standard library time and clock functions

In the C standard, there is a defined library on time and date declared in "time.h". The library is not limited to embedded applications, and widely used in order to obtain information about time and date. This library is supported by IAR Embedded Workbench, and in this article we will take a look at how to use it in the toolchain.

Features that are supported by time.h

The time and date library of the C language is defined in time.h. This header includes data types with respect to time, constants and functions:

Data types and constants

clock_t Data type for representing time
time_t Data type for representing time
struct tm

Structure that holds the following data:
int tm_sec;// Sec.
int tm_min;// Min
int tm_hour;// Time
int tm_mday; // Day
int tm_mon;// Month
int tm_year;// Year
int tm_wday;// Day of the week
int tm_yday; // Elapsed date Among from the start of the year
int tm_isdst;// Season flag, such as daylight saving time

CLOCKS_PER_SEC The number of times an internal timing event occurs per second

Functions that operate on time

clock Returns the time elapsed since the program was started
time Returns the current time, as the elapsed time in seconds since 00:00:00, January 1, 1970.
difftime Returns the elapsed time between two times, as the difference in seconds.

Conversion functions

asctime Converts a tm object to a string representation
ctime Converts a time_t  object to a string representation
gmtime Converts from a time_t object to tm object
localtime Converts  from  current time to  local time
strftime Converts a tm object into a specified format
mktime Converts from a tm object to a time_t object 

How to use time.h in IAR Embedded Workbench

In embedded systems, you need to write code that calculates the date and time in order to use the time.h functions. We introduce two cases for how to use and implement the time library in IAR Embedded Workbench.

The first case is applicable when using the debugger. Time information is provided from the debugger. The information is not available when the debugger is detached from the target board. The second example shows how to manage the time without using the debugger.

Example 1: Managing time information during debugging

If the debugger is available, the application can use the data/time library, and you do not need to implement anything else in order to manage time information. Below are two code examples: one using clock() and the other using time().

You can get the elapsed time from the system start by using a clock in the following way:

clock_t clk_time;

clk_time = clock ();
printf ("clock time:% dsec \ n", clk_time / CLOCKS_PER_SEC);

 You can also use string display conversion to get the date and time:

time_t now;
struct tm * ts;
char buf [80];

now = time (NULL);
ts = localtime (& now);
strftime (buf, sizeof (buf), "% a% Y-% m-% d% H:% M:% S% Z", ts);
printf ("% s \ n", buf);

This is the result of the above code examples:

clock time: 234sec
Sat 2015-07-11 00:11:40
...

Example 2: Implementation without the debugger

Without the debugger, the application must implement the low-level implementation of the date and time library. If you are using an RTOS, similar functions might be provided and you can use those.

The below example is for an ARM Cortex-M device, which has a Systick timer. The timer makes it easy to implement data and time functions. In this example, SysTick generates an interrupt every 1 msec.

We define two variables for time and clock and define CLOCKS_PER_SEC as ticks in one second:

#define CLOCKS_PER_SEC (1000)
clock_t clk_count = 0;
time_t time_dat;

We create an interrupt handler for the SysTick. 64bit variable is recommended for clk_count to avoid overflow. When an interrupt is generated, clk_count is incremented and time_dat is incremented if one second passes:

void SysTick_Handler (void) {
clk_count ++;
if ((clk_count% 1000) == 0) {
time_dat ++;
}
}

Two functions are implemented using variables:

clock_t clock (void) {
return (clk_count);
}

time_t __time32 (time_t * p) {
return time_dat;
}

The variable "clk_count" is initialized to 0 since clock() returns the elapsed time. The variable, "time_dat" should be initialized to the current time. We can use a conversion function to initialize it. This example uses mktime for the conversion:

struct tm orig;
orig.tm_sec = 10;
orig.tm_min = 46;
orig.tm_hour = 9;
orig.tm_mday = 10;
orig.tm_mon = 6;
orig.tm_year = 115;
orig.tm_wday = 5;
orig.tm_yday = 19;
orig.tm_isdst = -1;
time_dat = mktime (& org);

This gives the date: Fri Jul 10 09:46:10 2015

As a result, every call of the SysTick handler updates the variables. By applying these low level implementations, you can use the clock and time functions on your application.

Conclusion

Standard C library date and time operations implemented in time.h can be used in IAR Embedded Workbench. You can use these functions without writing a low-level implementation by using information provided by the debugger. If you want to use the library without using the debugger, you can implement low-level code as described in this article in order to use the date and time functions.

This article is written by Hiroki Akaboshi, Field Applications Engineer at IAR Systems Japan.

© IAR Systems 1995-2016 - All rights reserved.