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:
parent
6d2c697da1
commit
0a835e4ce9
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2012 Intel Corporation
|
* 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
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
@ -25,7 +25,7 @@ namespace Rtc {
|
||||||
Session_client(Genode::Capability<Session> cap)
|
Session_client(Genode::Capability<Session> cap)
|
||||||
: Genode::Rpc_client<Session>(cap) {}
|
: Genode::Rpc_client<Session>(cap) {}
|
||||||
|
|
||||||
Genode::uint64_t current_time()
|
Timestamp current_time()
|
||||||
{
|
{
|
||||||
return call<Rpc_current_time>();
|
return call<Rpc_current_time>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
/*
|
/*
|
||||||
* \brief Rtc session interface
|
* \brief Rtc session interface
|
||||||
* \author Markus Partheymueller
|
* \author Markus Partheymueller
|
||||||
|
* \author Josef Soentgen
|
||||||
* \date 2012-11-15
|
* \date 2012-11-15
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2012 Intel Corporation
|
* 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
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
@ -21,16 +22,25 @@
|
||||||
|
|
||||||
namespace Rtc {
|
namespace Rtc {
|
||||||
|
|
||||||
|
struct Timestamp
|
||||||
|
{
|
||||||
|
unsigned microsecond;
|
||||||
|
unsigned second;
|
||||||
|
unsigned minute;
|
||||||
|
unsigned hour;
|
||||||
|
unsigned day;
|
||||||
|
unsigned month;
|
||||||
|
unsigned year;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Session : Genode::Session
|
struct Session : Genode::Session
|
||||||
{
|
{
|
||||||
static const char *service_name() { return "Rtc"; }
|
static const char *service_name() { return "Rtc"; }
|
||||||
|
|
||||||
/**
|
virtual Timestamp current_time() = 0;
|
||||||
* Get microseconds elapsed since 1.1.1970 UTC.
|
|
||||||
*/
|
|
||||||
virtual Genode::uint64_t 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);
|
GENODE_RPC_INTERFACE(Rpc_current_time);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
#include <rtc_session/connection.h>
|
#include <rtc_session/connection.h>
|
||||||
#include <vfs/file_system.h>
|
#include <vfs/file_system.h>
|
||||||
|
|
||||||
/* libc includes */
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
namespace Vfs { class Rtc_file_system; }
|
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"; }
|
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 **
|
** 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
|
* On each read the current time is queried and afterwards formated
|
||||||
* as '%Y-%m-%d %H:%M\n'.
|
* 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,
|
Read_result read(Vfs_handle *vfs_handle, char *dst, file_size count,
|
||||||
file_size &out_count) override
|
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];
|
if (seek >= TIMESTAMP_LEN) {
|
||||||
Genode::snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d\n",
|
out_count = 0;
|
||||||
1900 + tm->tm_year, /* years since 1900 */
|
return READ_OK;
|
||||||
1 + tm->tm_mon, /* months since January [0-11] */
|
}
|
||||||
tm->tm_mday, tm->tm_hour, tm->tm_min);
|
|
||||||
|
|
||||||
file_size len = count > sizeof(buf) ? sizeof(buf) : count;
|
Rtc::Timestamp ts = _rtc.current_time();
|
||||||
Genode::memcpy(dst, buf, len);
|
|
||||||
|
|
||||||
|
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;
|
out_count = len;
|
||||||
|
|
||||||
return READ_OK;
|
return READ_OK;
|
||||||
|
|
|
@ -40,5 +40,3 @@ build_boot_image { core init timer rtc_drv test-rtc }
|
||||||
append qemu_args " -nographic -m 128 "
|
append qemu_args " -nographic -m 128 "
|
||||||
|
|
||||||
run_genode_until ".*--- RTC test finished ---.*\n" 20
|
run_genode_until ".*--- RTC test finished ---.*\n" 20
|
||||||
|
|
||||||
puts "Test succeeded"
|
|
||||||
|
|
|
@ -12,16 +12,25 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Linux includes */
|
/* Linux includes */
|
||||||
#include <sys/time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "rtc.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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,9 @@ namespace Rtc {
|
||||||
|
|
||||||
struct Rtc::Session_component : public Genode::Rpc_object<Session>
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,42 +28,6 @@
|
||||||
using namespace Genode;
|
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
|
enum RTC
|
||||||
{
|
{
|
||||||
RTC_SECONDS = 0,
|
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)
|
#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;
|
unsigned year, mon, day, hour, min, sec;
|
||||||
int i;
|
int i;
|
||||||
|
@ -174,5 +138,5 @@ uint64_t Rtc::get_time(void)
|
||||||
|
|
||||||
if ((year += 1900) < 1970) year += 100;
|
if ((year += 1900) < 1970) year += 100;
|
||||||
|
|
||||||
return mktime(day, mon, year, hour, min, sec) * 1000000ULL;
|
return Timestamp { 0, sec, min, hour, day, mon, year };
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
#define _RTC_H_
|
#define _RTC_H_
|
||||||
|
|
||||||
#include <base/stdint.h>
|
#include <base/stdint.h>
|
||||||
|
#include <rtc_session/rtc_session.h>
|
||||||
|
|
||||||
namespace Rtc {
|
namespace Rtc {
|
||||||
|
|
||||||
/* Get real time in microseconds since 1970 */
|
Timestamp get_time();
|
||||||
Genode::uint64_t get_time();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _RTC_H_ */
|
#endif /* _RTC_H_ */
|
||||||
|
|
|
@ -26,11 +26,11 @@ int main(int argc, char **argv)
|
||||||
static Timer::Connection timer;
|
static Timer::Connection timer;
|
||||||
|
|
||||||
for (unsigned i = 0; i < 4; ++i) {
|
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",
|
Genode::printf("RTC: %u-%02u-%02u %02u:%02u:%02u\n",
|
||||||
now / 1000000ULL,
|
now.year, now.month, now.day,
|
||||||
now % 1000000ULL);
|
now.hour, now.minute, now.second);
|
||||||
|
|
||||||
timer.msleep(1000);
|
timer.msleep(1000);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@ set build_components {
|
||||||
drivers/framebuffer drivers/pci drivers/input
|
drivers/framebuffer drivers/pci drivers/input
|
||||||
server/terminal server/ram_fs
|
server/terminal server/ram_fs
|
||||||
test/libports/ncurses
|
test/libports/ncurses
|
||||||
|
|
||||||
|
drivers/rtc
|
||||||
}
|
}
|
||||||
|
|
||||||
lappend_if [use_usb_input] build_components drivers/usb
|
lappend_if [use_usb_input] build_components drivers/usb
|
||||||
|
@ -68,7 +70,11 @@ append config {
|
||||||
<start name="timer">
|
<start name="timer">
|
||||||
<resource name="RAM" quantum="1M"/>
|
<resource name="RAM" quantum="1M"/>
|
||||||
<provides><service name="Timer"/></provides>
|
<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 {
|
append_if [have_spec sdl] config {
|
||||||
<start name="fb_sdl">
|
<start name="fb_sdl">
|
||||||
|
@ -162,6 +168,8 @@ append config {
|
||||||
<dir name="ram"> <fs label="root" /> </dir>
|
<dir name="ram"> <fs label="root" /> </dir>
|
||||||
<dir name="tmp"> <fs label="tmp" /> </dir>
|
<dir name="tmp"> <fs label="tmp" /> </dir>
|
||||||
|
|
||||||
|
<dir name="dev"> <rtc/> <zero/> </dir>
|
||||||
|
|
||||||
</fstab>
|
</fstab>
|
||||||
<start name="/bin/bash">
|
<start name="/bin/bash">
|
||||||
<env name="TERM" value="linux" />
|
<env name="TERM" value="linux" />
|
||||||
|
@ -183,6 +191,7 @@ set boot_modules {
|
||||||
core init timer ld.lib.so noux terminal ram_fs
|
core init timer ld.lib.so noux terminal ram_fs
|
||||||
libc.lib.so libm.lib.so libc_noux.lib.so ncurses.lib.so
|
libc.lib.so libm.lib.so libc_noux.lib.so ncurses.lib.so
|
||||||
bash.tar coreutils.tar vim.tar
|
bash.tar coreutils.tar vim.tar
|
||||||
|
rtc_drv
|
||||||
}
|
}
|
||||||
|
|
||||||
# platform-specific modules
|
# platform-specific modules
|
||||||
|
|
|
@ -61,6 +61,9 @@
|
||||||
#include <nul/motherboard.h>
|
#include <nul/motherboard.h>
|
||||||
#include <sys/hip.h>
|
#include <sys/hip.h>
|
||||||
|
|
||||||
|
/* utilities includes */
|
||||||
|
#include <service/time.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include "synced_motherboard.h"
|
#include "synced_motherboard.h"
|
||||||
#include "device_model_registry.h"
|
#include "device_model_registry.h"
|
||||||
|
@ -1133,8 +1136,12 @@ class Machine : public StaticReceiver<Machine>
|
||||||
return true;
|
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);
|
Logging::printf("Got time %llx\n", msg.wallclocktime);
|
||||||
msg.timestamp = _unsynchronized_motherboard.clock()->clock(MessageTime::FREQUENCY);
|
msg.timestamp = _unsynchronized_motherboard.clock()->clock(MessageTime::FREQUENCY);
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <vfs/null_file_system.h>
|
#include <vfs/null_file_system.h>
|
||||||
#include <vfs/zero_file_system.h>
|
#include <vfs/zero_file_system.h>
|
||||||
#include <vfs/block_file_system.h>
|
#include <vfs/block_file_system.h>
|
||||||
|
#include <vfs/rtc_file_system.h>
|
||||||
#include <random_file_system.h>
|
#include <random_file_system.h>
|
||||||
#include <stdio_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::Null_file_system>();
|
||||||
fs_factory.add_fs_type<Vfs::Zero_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::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<Stdio_file_system>();
|
||||||
fs_factory.add_fs_type<Random_file_system>();
|
fs_factory.add_fs_type<Random_file_system>();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue