I tried wkalrm by Werner Almesberger and it works without problems. I
don't know where i found it so i attached it to this mail.
Ciao,
Rainer
Nikita V. Youshchenko wrote:
> Hi
>
> I see, rtcwake does not work on freerunner:
>
> freerunner:~# rtcwake -s 30
> rtcwake: /dev/rtc0 not enabled for wakeup events
>
> Is there any working methond to make freerunner suspend sleep and later
> wakeup not later than at a given moment?
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Openmoko community mailing list
> [email protected]
> http://lists.openmoko.org/mailman/listinfo/community
/*
* wkalrm.c - Use the RTC alarm to wake us up
*
* Copyright (C) 2008 by OpenMoko, Inc.
* Written by Werner Almesberger <[email protected]>
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/rtc.h>
#define DEFAULT_RTC "/dev/rtc0"
static const char *device = DEFAULT_RTC;
static int fd;
/* ----- Low-level wrappers ------------------------------------------------ */
static void read_alarm(struct rtc_wkalrm *alarm)
{
int res;
res = ioctl(fd, RTC_WKALM_RD, alarm);
if (res < 0) {
perror("ioctl(RTC_WKALM_RD)");
exit(1);
}
}
static void read_time(struct rtc_time *tm)
{
int res;
res = ioctl(fd, RTC_RD_TIME, tm);
if (res < 0) {
perror("ioctl(RTC_RD_TIME)");
exit(1);
}
}
static void write_alarm(const struct rtc_wkalrm *alarm)
{
int res;
res = ioctl(fd, RTC_WKALM_SET, alarm);
if (res < 0) {
perror("ioctl(RTC_WKALM_SET)");
exit(1);
}
}
/* ----- Date conversions -------------------------------------------------- */
static void show_alarm(void)
{
struct rtc_wkalrm alarm;
read_alarm(&alarm);
if (!alarm.enabled)
printf("alarm disabled%s\n",
alarm.pending ? " (pending)" : "");
else
printf("%02d:%02d:%02d %04d-%02d-%02d%s\n",
alarm.time.tm_hour, alarm.time.tm_min, alarm.time.tm_sec,
alarm.time.tm_year+1900, alarm.time.tm_mon+1,
alarm.time.tm_mday,
alarm.pending ? " (pending)" : "");
}
static void set_alarm_abs(const char *t, const char *day)
{
fprintf(stderr, "not yet implemented :-)\n");
exit(1);
}
static void set_alarm_delta(time_t delta)
{
struct rtc_wkalrm alarm;
struct tm tm, *tmp;
time_t t;
read_time(&alarm.time);
memset(&tm, 0, sizeof(tm));
tm.tm_sec = alarm.time.tm_sec;
tm.tm_min = alarm.time.tm_min;
tm.tm_hour = alarm.time.tm_hour;
tm.tm_mday = alarm.time.tm_mday;
tm.tm_mon = alarm.time.tm_mon;
tm.tm_year = alarm.time.tm_year;
t = mktime(&tm);
if (t == (time_t) -1) {
fprintf(stderr, "mktime: error\n");
exit(1);
}
t += delta;
tmp = localtime(&t);
if (!tmp) {
fprintf(stderr, "localtime_r: error\n");
exit(1);
}
alarm.time.tm_sec = tmp->tm_sec;
alarm.time.tm_min = tmp->tm_min;
alarm.time.tm_hour = tmp->tm_hour;
alarm.time.tm_mday = tmp->tm_mday;
alarm.time.tm_mon = tmp->tm_mon;
alarm.time.tm_year = tmp->tm_year;
alarm.enabled = 1;
write_alarm(&alarm);
}
static void set_alarm_rel(const char *delta)
{
unsigned long n;
char *end;
n = strtoul(delta, &end, 10);
if (!strcmp(end, "d") || !strcmp(end, "day") || !strcmp(end, "days"))
n *= 24*3600;
else if (!strcmp(end, "h") || !strcmp(end, "hour") ||
!strcmp(end, "hours"))
n *= 3600;
else if (!strcmp(end, "m") || !strcmp(end, "min") ||
!strcmp(end, "mins"))
n *= 60;
else if (strcmp(end, "s") && strcmp(end, "sec") &&
strcmp(end, "secs")) {
fprintf(stderr, "invalid delta time \"%s\"\n", delta);
exit(1);
}
set_alarm_delta(n);
}
static void disable_alarm(void)
{
struct rtc_wkalrm alarm;
read_alarm(&alarm);
alarm.enabled = 0;
write_alarm(&alarm);
}
static void set_alarm_24h(const char *t)
{
fprintf(stderr, "not yet implemented :-)\n");
exit(1);
}
static void set_alarm(const char *when)
{
if (*when == '+')
set_alarm_rel(when+1);
else
set_alarm_24h(when);
}
/* ----- Command line parsing ---------------------------------------------- */
static void usage(const char *name)
{
fprintf(stderr,
"usage: %s [-d device]\n"
" %s [-d device] hh:mm[:ss] [[yyyy-]mm-dd]\n"
" %s [-d device] +Nunit\n\n"
" unit is d[ay[s]], h[our[s]] m[in[s]], or s[ec[s]]\n\n"
" -d device open the specified RTC device (default: %s)\n"
, name, name, name, DEFAULT_RTC);
exit(1);
}
int main(int argc, char **argv)
{
int c;
while ((c = getopt(argc, argv, "d:")) != EOF)
switch (c) {
case 'd':
device = optarg;
break;
default:
usage(*argv);
}
fd = open(device, O_RDWR);
if (fd < 0) {
perror(device);
exit(1);
}
switch (argc-optind) {
case 0:
show_alarm();
break;
case 1:
if (!strcmp(argv[optind], "off"))
disable_alarm();
else
set_alarm(argv[optind]);
break;
case 2:
set_alarm_abs(argv[optind], argv[optind+1]);
break;
default:
usage(*argv);
}
return 0;
}
_______________________________________________
Openmoko community mailing list
[email protected]
http://lists.openmoko.org/mailman/listinfo/community