native/rtc: improve implementation

* add error checking / warnings
* implement parts of alarm functionality
* clean up
This commit is contained in:
Ludwig Ortmann 2014-11-22 11:06:23 +01:00
parent 37a1a105bc
commit f35981a6d7

View File

@ -12,7 +12,7 @@
* The implementation uses POSIX system calls to emulate a real-time * The implementation uses POSIX system calls to emulate a real-time
* clock based on the system clock. * clock based on the system clock.
* *
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de> * @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
* *
* @ingroup native_cpu * @ingroup native_cpu
* @defgroup native_rtc * @defgroup native_rtc
@ -21,6 +21,7 @@
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <err.h> #include <err.h>
#include "debug.h" #include "debug.h"
@ -30,40 +31,68 @@
#include "native_internal.h" #include "native_internal.h"
static int native_rtc_powered; static int native_rtc_initialized = 0;
static int native_rtc_initialized; static int native_rtc_powered = 0;
static struct tm native_rtc_alarm;
static rtc_alarm_cb_t native_rtc_alarm_callback;
static void *native_rtc_alarm_argument;
void rtc_init(void) void rtc_init(void)
{ {
native_rtc_powered = 0; DEBUG("rtc_init\n");
memset(&native_rtc_alarm, 0, sizeof(native_rtc_alarm));
native_rtc_alarm_callback = NULL;
native_rtc_alarm_argument = NULL;
native_rtc_initialized = 1; native_rtc_initialized = 1;
printf("Native RTC initialized.\n"); printf("Native RTC initialized.\n");
rtc_poweron(); rtc_poweron();
} }
void rtc_poweron(void) void rtc_poweron(void)
{ {
DEBUG("rtc_poweron\n"); DEBUG("rtc_poweron\n");
if (native_rtc_initialized == 1) {
native_rtc_powered = 1; if (!native_rtc_initialized) {
} warnx("rtc_poweron: not initialized");
else { return;
DEBUG("rtc not initialized, not powering on\n");
} }
native_rtc_powered = 1;
} }
void rtc_poweroff(void) void rtc_poweroff(void)
{ {
DEBUG("rtc_poweroff()\n"); DEBUG("rtc_poweroff()\n");
if (!native_rtc_initialized) {
warnx("rtc_poweroff: not initialized");
}
if (!native_rtc_powered) {
warnx("rtc_poweroff: not powered on");
}
native_rtc_powered = 0; native_rtc_powered = 0;
} }
/* TODO: implement time setting using a delta */
int rtc_set_time(struct tm *ttime) int rtc_set_time(struct tm *ttime)
{ {
/* TODO: implemented setting using a delta */ (void) ttime;
DEBUG("rtc_set_time()\n"); DEBUG("rtc_set_time()\n");
(void)ttime; /* not implemented atm */ if (!native_rtc_initialized) {
warnx("rtc_set_time: not initialized");
return -1;
}
if (!native_rtc_powered) {
warnx("rtc_set_time: not powered on");
return -1;
}
warnx("rtc_set_time: not implemented"); warnx("rtc_set_time: not implemented");
return -1; return -1;
@ -73,25 +102,44 @@ int rtc_get_time(struct tm *ttime)
{ {
time_t t; time_t t;
if (native_rtc_powered == 1) { if (!native_rtc_initialized) {
_native_syscall_enter(); warnx("rtc_get_time: not initialized");
t = time(NULL); return -1;
if (localtime_r(&t, ttime) == NULL) {
err(EXIT_FAILURE, "rtc_get_time: localtime_r");
}
_native_syscall_leave();
} }
if (!native_rtc_powered) {
warnx("rtc_get_time: not powered on");
return -1;
}
_native_syscall_enter();
t = time(NULL);
if (localtime_r(&t, ttime) == NULL) {
err(EXIT_FAILURE, "rtc_get_time: localtime_r");
}
_native_syscall_leave();
return 0; return 0;
} }
/* TODO: implement alarm scheduling */
int rtc_set_alarm(struct tm *time, rtc_alarm_cb_t cb, void *arg) int rtc_set_alarm(struct tm *time, rtc_alarm_cb_t cb, void *arg)
{ {
(void) time; (void) time;
(void) cb; (void) cb;
(void) arg; (void) arg;
if (!native_rtc_initialized) {
warnx("rtc_set_alarm: not initialized");
return -1;
}
if (!native_rtc_powered) {
warnx("rtc_set_alarm: not powered on");
return -1;
}
memcpy(&native_rtc_alarm, time, sizeof(native_rtc_alarm));
warnx("rtc_set_alarm: not implemented"); warnx("rtc_set_alarm: not implemented");
return -1; return -1;
@ -101,12 +149,32 @@ int rtc_get_alarm(struct tm *time)
{ {
(void) time; (void) time;
warnx("rtc_get_alarm: not implemented"); if (!native_rtc_initialized) {
warnx("rtc_get_alarm: not initialized");
return -1;
}
if (!native_rtc_powered) {
warnx("rtc_get_alarm: not powered on");
return -1;
}
return -1; memcpy(time, &native_rtc_alarm, sizeof(native_rtc_alarm));
return 0;
} }
/* TODO: implement alarm unscheduling once rtc_set_alarm is
* implemented */
void rtc_clear_alarm(void) void rtc_clear_alarm(void)
{ {
warnx("rtc_clear_alarm: not implemented"); DEBUG("rtc_clear_alarm()\n");
if (!native_rtc_initialized) {
warnx("rtc_clear_alarm: not initialized");
}
if (!native_rtc_powered) {
warnx("rtc_clear_alarm: not powered on");
}
memset(&native_rtc_alarm, 0, sizeof(native_rtc_alarm));
} }