Where is the kernel time stored in memory in Linux? - c

For an assignment I have to use a video driver and system timer handler to display the current running time of the Linux system to the corner of the screen.
However, I have not found anywhere that points me into the direction of obtaining the system time from the kernel when my program runs. I am guessing it is in kernel memory at some address and I can just do something like:
hour = get_word(MEM_LOCATION_OF_HOUR);
sec = get_word(MEM_LOCATION_OF_SEC);
ect...
But I cannot find out if this is possible. My guess is that we are not allowed to use library calls like clock() but if that is the only possible way then maybe we are.
Thanks

Can't use library calls? - that's just craziness. Anyway:
getnstimeofday(struct timespec *ts); is one of many methods from here

In kernel, ktime can be used.
a simple example(for calculating time diff) for your reference.
#include <linux/ktime.h>
int fun()
{
ktime_t entry_stamp, now;
s64 delta;
/* Get the current time .*/
entry_stamp = ktime_get();
/* Do your Stuff... */
now = ktime_get();
delta = ktime_to_ns(ktime_sub(now, entry_stamp));
printk(KERN_INFO "Time Taken:%lld ns to execute\n",(long long)delta);
return 0;
}

I have found that the Real-time clock holds the correct values on boot. The CMOS contains all the needed info.
Here is a link to what I found. http://wiki.osdev.org/CMOS#The_Real-Time_Clock

Related

Measuring time lapses in kernel 2.4.37

My purpose is quite simple: to measure the time elapsed:
unsigned long start, end;
int init_module (void) {
start = jiffies;
printk("Hello Modules\n");
end = jiffies;
printk("Measuring time lapses: %lu\n", (end - start) * 1000 /HZ);
return 0;
}
But this method does not work because printk is too short, can any one give me some suggestions? Any other options? Both C and assembly are ok. And I'm required to work under kernel 2.4.37.
Check out printk times. This shall enable you to see the time between the calls or show time relative to a particular message. This is one of the instrumentation tool for kernel.
Provided below the related links and link for patch:
http://elinux.org/Printk_Times
http://elinux.org/images/d/d0/Instrumented_printk.patch

an efficient way to detect when the system's hour changed from xx:59 to xy:00

I have an application on Linux that needs to change some parameters each hour, e.g. at 11:00, 12:00, etc. and the system's date can be changed by the user anytime.
Is there any signal, posix function that would provides me when a hour changes from xx:59 to xx+1:00?
Normally, I use localtime(3) to fetch the current time each seconds then compare if the minute part is equal to 0. however, it does not look a good way to do it, in order to detect a change, I need to call the same function each second for an hour. Especially I run the code on an embedded board that would be good to use less resources.
Here is an example code how I do it:
static char *fetch_time() { // I use this fcn for some other purpose to fetch the time info
char *p;
time_t rawtime;
struct tm * timeinfo;
char buffer[13];
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime (buffer,13,"%04Y%02m%02d%02k%02M",timeinfo);
p = (char *)malloc(sizeof(buffer));
strcpy(p, buffer);
return p;
}
static int hour_change_check(){
char *p;
p = fetch_time();
char current_minute[3] = {'\0'};
current_minute[0] = p[10];
current_minute[1] = p[11];
int current_minute_as_int = atoi(current_minute);
if (current_minute_as_int == 0){
printf("current_min: %d\n",current_minute_as_int);
free(p);
return 1;
}
free(p);
return 0;
}
int main(void){
while(1){
int x = hour_change_check();
printf("x:%d\n",x);
sleep(1);
}
return 0;
}
There is no such signal, but traditionally the method of waiting until some target time is to compute how long it is between "now" and "then", and then call sleep():
now = time(NULL);
when = (some calculation);
if (when > now)
sleep(when - now);
If you need to be very precise about the transition from, e.g., 3:59:59 to 4:00:00, you may want to sleep for a slightly shorter time in case of time adjustments due to leap seconds. (If you are running in a portable device in which time zones can change, you also need to worry about picking up the new location, and if it runs on a half-hour offset, redo all computations. There's even Solar Time in Saudi Arabia....)
Edit: per the suggestion from R.., if clock_nanosleep() is available, calculate a timespec value for the absolute wakeup time and call it with the TIMER_ABSTIME flag. See http://pubs.opengroup.org/onlinepubs/009695399/functions/clock_nanosleep.html for the definition for clock_nanosleep(). However, if time is allowed to step backwards (e.g., localtime with zone shifts), you may still have to do some maintenance checking.
Have you actually measured the overhead used in your solution of polling the time once per second (or even two given some of your other comments)?
The number of instructions that are invoked is minimal AND you do not have any looping. So at worse maybe the cpu uses 100 micro-seconds (0.1 ms, or 0.0001 s) time. This estimate is very dependent on the processor used in your embedded system and its clock speed, but the idea is that maybe the polling logic uses 1/1000 of the total time available.
Also, you could optimize your hour_change_check code to do all of the time calcs and not call another function that issues malloc which has to be immediately freed! Also, if this is an embedded *nix system, can you still run this polling logic in its own thread so that when it issues sleep() it will not interfere or delay other units of work.
Hence, measure the problem and see if it is a significant problem. The polling's performance must be balanced against the requirement that when a user changes the time then the hour change MUST be detected. That is, I think polling every second will catch the hour rollover even if the user changes the time, but is the overhead worth it. Well, how much, exactly, overhead is there?

Delay using timer on raspberry pi

I need to create a accurate delay (around 100us) inside a thread function. I tried using the nanosleep function but it was no accurate enough. I read some post about how to read the hardware 1MHz timer, so on my function in order to create a 100us delay y tried something like this:
prev = *timer;
do {
t = *timer;
} while ((t - prev) < 100);
However, the program seems to stay inside the loop. But if I insert a small nano sleep inside the loop it works (but loosing precision):
sleeper.tv_sec = 0;
sleeper.tv_nsec = (long)(1);
prev = *timer;
do {
nanosleep (&sleeper, &dummy);
t = *timer;
} while ((t - prev) < 500);
I tried the first version in a stand along program and it works, but in my main program, where this is inside a thread it does not.
Does anyone know what the first version (without a small nanosleep) does not work?
I'm sorry to say but Raspberry Pi's OS is not a "real-time OS". In another words, you won't get consistent 100us precision in a user space program due to inherent OS scheduling limitations. If you need that kind of precision, you should use an embedded controller like an Arduino.

Windows Driver Timestamp function

I am modifying an existing Windows Kernel device driver and in there I need to capture a timestamp. I was intending to use time.h library and call the clock() function to get that, however under windows visual studio, the linking is failing. So I took it as a means that I need to work within the driver's libraries.
I found the following function, KeInitializeTimer, and KeSetTimerEx but these are used if I plan to set up a timer and wake up on it. What I really need is something that will give me a timestamp.
Any ideas?
I am updating my question with an answer for others to benefit from my findings.
To get a timestamp, you can use KeQueryTickCount(). This routine will give you the count of interval interrupts that occurred since the system was booted. However, if you need to find out since the last timestamp you captured, an X amount of time has passed you need to also query your system to determine the time it takes for each interval clock interrupt.
ULONG KeQueryTimeIncrement() give you the number of 100-nanosecond units.
Example:
PLARGE_INTEGER timeStamp;
KeQueryTickCount(&timeStamp);
Please note that PLARGE_INTEGER is defined as such:
#if defined(MIDL_PASS)
typedef struct _LARGE_INTEGER {
#else // MIDL_PASS
typedef union _LARGE_INTEGER {
struct {
ULONG LowPart;
LONG HighPart;
} DUMMYSTRUCTNAME;
struct {
ULONG LowPart;
LONG HighPart;
} u;
#endif //MIDL_PASS
LONGLONG QuadPart;
} LARGE_INTEGER;
So lets say, you want to see if 30 seconds passed since you last took a timestamp, you can do the following:
ULONG tickIncrement, ticks;
LARGE_INTEGER waitTillTimeStamp;
tickIncrement = KeQueryTimeIncrement();
// 1sec is 1,000,000,000 nano sec, however, since KeQueryTimeIncrement is in
// 100ns increments, divide that and your constant is 10,000,000
ticks = ((30 * 10,000,000) / tickIncrement);
KeQueryTickCount(&waitTillTimeStamp);
waitTillTimeStamp.QuadPart += ticks;
<.....Some code and time passage....>
KeQueryTickCount(&currTimeStamp);
if (waitTillTimeStamp.QuadPart < currTimeStamp.QuadPart) {
<...Do whatever...>
}
Another example to help you understand this, what if you want to translate the timestamp you got into a time value such as milliseconds.
LARGE_INTEGER mSec, currTimeStamp;
ULONG timeIncrement;
timeIncrement = KeQueryTimeIncrement();
KeQueryTickCount(&currTimeStamp);
// 1 millisecond is 1,000,000 nano seconds, but remember divide by 100 to account for
// KeQueryTickCount granularity.
mSec.QuadPart = (currTimeStamp.QuadPart * timeIncrement) / 10000;
Remember this example is for demonstration purposes, mSec is not the current time in milliseconds. Based on the APIs used above, it is merely the number of milliseconds that have elapsed since the system was started.
You can also use GetTickCount(), but this returns a DWORD and thus will only be able to give you the number of milliseonds since the system was started for up to 49.7 days.
I know this is a 10 years old question but... better later than never. I disagree with the OP's answer.
Proper solution:
// The KeQuerySystemTime routine obtains the current system time.
LARGE_INTEGER SystemTime;
KeQuerySystemTime(&SystemTime);
// The ExSystemTimeToLocalTime routine converts a GMT system time value to the local system time for the current time zone.
LARGE_INTEGER LocalTime;
ExSystemTimeToLocalTime(&SystemTime, &LocalTime);
// The RtlTimeToTimeFields routine converts system time into a TIME_FIELDS structure.
TIME_FIELDS TimeFields;
RtlTimeToTimeFields(&LocalTime, &TimeFields);

unable to link to gettimeofday on embedded system, elapsed time suggestions?

I am trying to use gettimeofday on an embedded ARM device, however it seems as though I am unable to use it:
gnychis#ubuntu:~/Documents/coexisyst/econotag_firmware$ make
Building for board: redbee-econotag
CC obj_redbee-econotag/econotag_coexisyst_firmware.o
LINK (romvars) econotag_coexisyst_firmware_redbee-econotag.elf
/home/gnychis/Documents/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/arm-none- eabi/4.3.2/../../../../arm-none-eabi/lib/libc.a(lib_a-gettimeofdayr.o): In function `_gettimeofday_r':
gettimeofdayr.c:(.text+0x1c): undefined reference to `_gettimeofday'
/home/gnychis/Documents/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/arm-none-eabi/4.3.2/../../../../arm-none-eabi/lib/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text+0x18): undefined reference to `_sbrk'
collect2: ld returned 1 exit status
make[1]: *** [econotag_coexisyst_firmware_redbee-econotag.elf] Error 1
make: *** [mc1322x-default] Error 2
I am assuming I cannot use gettimeofday() ? Does anyone have any suggestions for being able to tell elapsed time? (e.g., 100ms)
What you need to do is create your own _gettimeofday() function to get it to link properly. This function could use the appropriate code to get the time for your processor, assuming you have a free-running system timer available.
#include <sys/time.h>
int _gettimeofday( struct timeval *tv, void *tzvp )
{
uint64_t t = __your_system_time_function_here__(); // get uptime in nanoseconds
tv->tv_sec = t / 1000000000; // convert to seconds
tv->tv_usec = ( t % 1000000000 ) / 1000; // get remaining microseconds
return 0; // return non-zero for error
} // end _gettimeofday()
What I usually do, is to have a timer running at 1khz, so it will generate an interrupt every millisecond, in the interrupt handler I increment a global var by one, say ms_ticks then do something like:
volatile unsigned int ms_ticks = 0;
void timer_isr() { //every ms
ms_ticks++;
}
void delay(int ms) {
ms += ms_ticks;
while (ms > ms_ticks)
;
}
It is also possible to use this as a timestamp, so let's say I want to do something every 500ms:
last_action = ms_ticks;
while (1) { //app super loop
if (ms_ticks - last_action >= 500) {
last_action = ms_ticks;
//action code here
}
//rest of the code
}
Another alternative, since ARMs are 32bits and your timer will probably be a 32bits one, is to instead of generating a 1khz interrupt, you leave it free running and simply use the counter as your ms_ticks.
Use one of the timers in the chip...
It looks like you are using the Econotag which is based on the MC13224v from Freescale.
The MACA_CLK register provides a very good timebase (assuming the radio is running). You can also use the the RTC with CRM->RTC_COUNT. The RTC may or may not be very good depending on if you have an external 32kHz crystal or not (the econotag does NOT).
e.g. with MACA_CLK:
uint32_t t;
t = *MACA_CLK;
while (*MACA_CLK - t > SOMETIME);
See also the timer examples in libmc1322x:
http://git.devl.org/?p=malvira/libmc1322x.git;a=blob;f=tests/tmr.c
Alternate methods are to use etimers or rtimers in Contiki (which has good support for the Econotag). (see http://www.sics.se/contiki/wiki/index.php/Timers )
I've done this before in one of my applications. Just use :
while(1)
{
...
}

Resources