mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 10:46:25 +00:00
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) 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>();
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 };
|
||||
}
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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>();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user