os: structured timestamp in Rtc session

Instead of returning an uint64_t value, return a structured time stamp.
This change is only visible to components using Rtc_session directly.

Fixes #1381.
This commit is contained in:
Josef Söntgen 2015-01-27 13:56:16 +01:00 committed by Christian Helmuth
parent 6d2c697da1
commit 0a835e4ce9
12 changed files with 94 additions and 76 deletions

View File

@ -6,7 +6,7 @@
/*
* Copyright (C) 2012 Intel Corporation
* Copyright (C) 2013 Genode Labs GmbH
* Copyright (C) 2013-14 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
@ -25,7 +25,7 @@ namespace Rtc {
Session_client(Genode::Capability<Session> cap)
: Genode::Rpc_client<Session>(cap) {}
Genode::uint64_t current_time()
Timestamp current_time()
{
return call<Rpc_current_time>();
}

View File

@ -1,12 +1,13 @@
/*
* \brief Rtc session interface
* \author Markus Partheymueller
* \author Josef Soentgen
* \date 2012-11-15
*/
/*
* Copyright (C) 2012 Intel Corporation
* Copyright (C) 2013 Genode Labs GmbH
* Copyright (C) 2013-2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
@ -21,16 +22,25 @@
namespace Rtc {
struct Timestamp
{
unsigned microsecond;
unsigned second;
unsigned minute;
unsigned hour;
unsigned day;
unsigned month;
unsigned year;
};
struct Session : Genode::Session
{
static const char *service_name() { return "Rtc"; }
/**
* Get microseconds elapsed since 1.1.1970 UTC.
*/
virtual Genode::uint64_t current_time() = 0;
virtual Timestamp current_time() = 0;
GENODE_RPC(Rpc_current_time, Genode::uint64_t, current_time);
GENODE_RPC(Rpc_current_time, Timestamp, current_time);
GENODE_RPC_INTERFACE(Rpc_current_time);
};
}

View File

@ -18,8 +18,6 @@
#include <rtc_session/connection.h>
#include <vfs/file_system.h>
/* libc includes */
#include <time.h>
namespace Vfs { class Rtc_file_system; }
@ -40,6 +38,19 @@ class Vfs::Rtc_file_system : public Single_file_system
static char const *name() { return "rtc"; }
/*********************************
** Directory-service interface **
*********************************/
Stat_result stat(char const *path, Stat &out) override
{
Stat_result result = Single_file_system::stat(path, out);
out.mode |= 0444;
return result;
}
/********************************
** File I/O service interface **
********************************/
@ -51,7 +62,7 @@ class Vfs::Rtc_file_system : public Single_file_system
}
/**
* Read the current time from the RTC
* Read the current time from the Rtc session
*
* On each read the current time is queried and afterwards formated
* as '%Y-%m-%d %H:%M\n'.
@ -59,19 +70,26 @@ class Vfs::Rtc_file_system : public Single_file_system
Read_result read(Vfs_handle *vfs_handle, char *dst, file_size count,
file_size &out_count) override
{
time_t t = _rtc.current_time() / 1000000ULL;
enum { TIMESTAMP_LEN = 17 };
struct tm *tm = localtime(&t);
file_size seek = vfs_handle->seek();
char buf[16 + 1 + 1];
Genode::snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d\n",
1900 + tm->tm_year, /* years since 1900 */
1 + tm->tm_mon, /* months since January [0-11] */
tm->tm_mday, tm->tm_hour, tm->tm_min);
if (seek >= TIMESTAMP_LEN) {
out_count = 0;
return READ_OK;
}
file_size len = count > sizeof(buf) ? sizeof(buf) : count;
Genode::memcpy(dst, buf, len);
Rtc::Timestamp ts = _rtc.current_time();
char buf[TIMESTAMP_LEN+1];
char *b = buf;
unsigned n = Genode::snprintf(buf, sizeof(buf), "%04u-%02u-%02u %02u:%02u\n",
ts.year, ts.month, ts.day, ts.hour, ts.minute);
n -= seek;
b += seek;
file_size len = count > n ? n : count;
Genode::memcpy(dst, b, len);
out_count = len;
return READ_OK;

View File

@ -40,5 +40,3 @@ build_boot_image { core init timer rtc_drv test-rtc }
append qemu_args " -nographic -m 128 "
run_genode_until ".*--- RTC test finished ---.*\n" 20
puts "Test succeeded"

View File

@ -12,16 +12,25 @@
*/
/* Linux includes */
#include <sys/time.h>
#include <time.h>
#include "rtc.h"
Genode::uint64_t Rtc::get_time(void)
Rtc::Timestamp Rtc::get_time(void)
{
struct timeval now { };
Timestamp ts { 0 };
gettimeofday(&now, nullptr);
time_t t = time(NULL);
struct tm *utc = gmtime(&t);
if (utc) {
ts.second = utc->tm_sec;
ts.minute = utc->tm_min;
ts.hour = utc->tm_hour;
ts.day = utc->tm_mday;
ts.month = utc->tm_mon + 1;
ts.year = utc->tm_year + 1900;
}
return now.tv_sec * 1000000ULL + now.tv_usec;
return ts;
}

View File

@ -31,9 +31,9 @@ namespace Rtc {
struct Rtc::Session_component : public Genode::Rpc_object<Session>
{
uint64_t current_time() override
Timestamp current_time() override
{
uint64_t ret = Rtc::get_time();
Timestamp ret = Rtc::get_time();
return ret;
}

View File

@ -28,42 +28,6 @@
using namespace Genode;
/**
* Time helper
*/
static bool is_leap_year(int year)
{
if (((year & 3) || !((year % 100) != 0)) && (year % 400 != 0)) return false;
return true;
}
/**
* Return UNIX time from given date and time.
*/
static uint64_t mktime(int day, int mon, int year, int hour, int minutes, int seconds)
{
bool jan_mar = mon < 3;
uint64_t ret = 0;
ret += (367*(10+mon))/12;
ret += jan_mar*2;
ret -= 719866;
ret += day;
ret += jan_mar * is_leap_year(year);
ret += 365*year;
ret += year/4;
ret -= year/100;
ret += year/400;
ret *= 24;
ret += hour;
ret *= 60;
ret += minutes;
ret *= 60;
ret += seconds;
return ret;
}
enum RTC
{
RTC_SECONDS = 0,
@ -136,7 +100,7 @@ static inline unsigned cmos_read(unsigned char addr)
#define BIN_TO_BCD(val) ((val) = (((val)/10) << 4) + (val) % 10)
uint64_t Rtc::get_time(void)
Rtc::Timestamp Rtc::get_time(void)
{
unsigned year, mon, day, hour, min, sec;
int i;
@ -174,5 +138,5 @@ uint64_t Rtc::get_time(void)
if ((year += 1900) < 1970) year += 100;
return mktime(day, mon, year, hour, min, sec) * 1000000ULL;
return Timestamp { 0, sec, min, hour, day, mon, year };
}

View File

@ -15,11 +15,11 @@
#define _RTC_H_
#include <base/stdint.h>
#include <rtc_session/rtc_session.h>
namespace Rtc {
/* Get real time in microseconds since 1970 */
Genode::uint64_t get_time();
Timestamp get_time();
}
#endif /* _RTC_H_ */

View File

@ -26,11 +26,11 @@ int main(int argc, char **argv)
static Timer::Connection timer;
for (unsigned i = 0; i < 4; ++i) {
Genode::uint64_t now = rtc.current_time();
Rtc::Timestamp now = rtc.current_time();
Genode::printf("RTC: %llu.%06llu seconds since 1970\n",
now / 1000000ULL,
now % 1000000ULL);
Genode::printf("RTC: %u-%02u-%02u %02u:%02u:%02u\n",
now.year, now.month, now.day,
now.hour, now.minute, now.second);
timer.msleep(1000);
}

View File

@ -14,6 +14,8 @@ set build_components {
drivers/framebuffer drivers/pci drivers/input
server/terminal server/ram_fs
test/libports/ncurses
drivers/rtc
}
lappend_if [use_usb_input] build_components drivers/usb
@ -68,7 +70,11 @@ append config {
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides><service name="Timer"/></provides>
</start> }
</start>
<start name="rtc_drv">
<resource name="RAM" quantum="1M"/>
<provides><service name="Rtc"/></provides>
</start>}
append_if [have_spec sdl] config {
<start name="fb_sdl">
@ -162,6 +168,8 @@ append config {
<dir name="ram"> <fs label="root" /> </dir>
<dir name="tmp"> <fs label="tmp" /> </dir>
<dir name="dev"> <rtc/> <zero/> </dir>
</fstab>
<start name="/bin/bash">
<env name="TERM" value="linux" />
@ -183,6 +191,7 @@ set boot_modules {
core init timer ld.lib.so noux terminal ram_fs
libc.lib.so libm.lib.so libc_noux.lib.so ncurses.lib.so
bash.tar coreutils.tar vim.tar
rtc_drv
}
# platform-specific modules

View File

@ -61,6 +61,9 @@
#include <nul/motherboard.h>
#include <sys/hip.h>
/* utilities includes */
#include <service/time.h>
/* local includes */
#include "synced_motherboard.h"
#include "device_model_registry.h"
@ -1133,8 +1136,12 @@ class Machine : public StaticReceiver<Machine>
return true;
}
}
/* current_time() returns microseconds */
msg.wallclocktime = _rtc->current_time() / 1000000U * MessageTime::FREQUENCY;
Rtc::Timestamp rtc_ts = _rtc->current_time();
tm_simple tms(rtc_ts.year, rtc_ts.month, rtc_ts.day, rtc_ts.hour,
rtc_ts.minute, rtc_ts.second);
msg.wallclocktime = mktime(&tms) * MessageTime::FREQUENCY;
Logging::printf("Got time %llx\n", msg.wallclocktime);
msg.timestamp = _unsynchronized_motherboard.clock()->clock(MessageTime::FREQUENCY);

View File

@ -38,6 +38,7 @@
#include <vfs/null_file_system.h>
#include <vfs/zero_file_system.h>
#include <vfs/block_file_system.h>
#include <vfs/rtc_file_system.h>
#include <random_file_system.h>
#include <stdio_file_system.h>
@ -1113,6 +1114,8 @@ int main(int argc, char **argv)
fs_factory.add_fs_type<Vfs::Null_file_system>();
fs_factory.add_fs_type<Vfs::Zero_file_system>();
fs_factory.add_fs_type<Vfs::Block_file_system>();
fs_factory.add_fs_type<Vfs::Block_file_system>();
fs_factory.add_fs_type<Vfs::Rtc_file_system>();
fs_factory.add_fs_type<Stdio_file_system>();
fs_factory.add_fs_type<Random_file_system>();