commands: add hwclock
The hwclock command allows to query or set the hardware clock (RTC). Barebox' 'hwclock' command uses busybox' 'date' compatible time format ccyymmddHHMM[.SS]: # /bin/busybox date -s 201407292005.41 ; /bin/date Tue Jul 29 20:05:41 MSK 2014 Tue Jul 29 20:05:41 MSK 2014 Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
686df208b3
commit
2bcf7f4dc8
|
@ -1691,6 +1691,14 @@ config CMD_GPIO
|
|||
|
||||
Usage: gpio_set_value GPIO VALUE
|
||||
|
||||
config CMD_HWCLOCK
|
||||
bool
|
||||
depends on RTC_CLASS
|
||||
prompt "hwclock command"
|
||||
default y
|
||||
help
|
||||
The hwclock command allows to query or set the hardware clock (RTC).
|
||||
|
||||
config CMD_I2C
|
||||
bool
|
||||
depends on I2C
|
||||
|
|
|
@ -100,3 +100,4 @@ obj-$(CONFIG_CMD_MENUTREE) += menutree.o
|
|||
obj-$(CONFIG_CMD_2048) += 2048.o
|
||||
obj-$(CONFIG_CMD_REGULATOR) += regulator.o
|
||||
obj-$(CONFIG_CMD_LSPCI) += lspci.o
|
||||
obj-$(CONFIG_CMD_HWCLOCK) += hwclock.o
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <getopt.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <rtc.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <string.h>
|
||||
#include <environment.h>
|
||||
|
||||
static char *strchrnul(const char *s, int c)
|
||||
{
|
||||
while (*s != '\0' && *s != c)
|
||||
s++;
|
||||
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
static int sscanf_two_digits(char *s, int *res)
|
||||
{
|
||||
char buf[3];
|
||||
unsigned long t;
|
||||
|
||||
if (!isdigit(s[0]) || !isdigit(s[1])) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf[0] = s[0];
|
||||
buf[1] = s[1];
|
||||
buf[2] = '\0';
|
||||
|
||||
t = simple_strtoul(buf, NULL, 10);
|
||||
*res = t;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_datestr(char *date_str, struct rtc_time *ptm)
|
||||
{
|
||||
char end = '\0';
|
||||
int len = strchrnul(date_str, '.') - date_str;
|
||||
int year;
|
||||
|
||||
/* ccyymmddHHMM[.SS] */
|
||||
if (len != 12) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sscanf_two_digits(date_str, &year) ||
|
||||
sscanf_two_digits(&date_str[2], &ptm->tm_year)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ptm->tm_year = year * 100 + ptm->tm_year;
|
||||
|
||||
/* Adjust years */
|
||||
ptm->tm_year -= 1900;
|
||||
|
||||
if (sscanf_two_digits(&date_str[4], &ptm->tm_mon) ||
|
||||
sscanf_two_digits(&date_str[6], &ptm->tm_mday) ||
|
||||
sscanf_two_digits(&date_str[8], &ptm->tm_hour) ||
|
||||
sscanf_two_digits(&date_str[10], &ptm->tm_min)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Adjust month from 1-12 to 0-11 */
|
||||
ptm->tm_mon -= 1;
|
||||
|
||||
end = date_str[12];
|
||||
|
||||
if (end == '.') {
|
||||
/* xxx.SS */
|
||||
if (!sscanf_two_digits(&date_str[13], &ptm->tm_sec)) {
|
||||
end = '\0';
|
||||
}
|
||||
/* else end != NUL and we error out */
|
||||
}
|
||||
|
||||
if (end != '\0') {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_hwclock(int argc, char *argv[])
|
||||
{
|
||||
struct rtc_device *r;
|
||||
struct rtc_time tm;
|
||||
struct rtc_time stm;
|
||||
char rtc_name[16] = "rtc0";
|
||||
char *env_name = NULL;
|
||||
int opt;
|
||||
int set = 0;
|
||||
|
||||
while ((opt = getopt(argc, argv, "f:s:e:")) > 0) {
|
||||
int ret;
|
||||
|
||||
switch (opt) {
|
||||
case 'f':
|
||||
strncpy(rtc_name, optarg, 16);
|
||||
break;
|
||||
case 's':
|
||||
memset(&stm, 0, sizeof(stm));
|
||||
|
||||
ret = parse_datestr(optarg, &stm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rtc_valid_tm(&stm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
set = 1;
|
||||
break;
|
||||
case 'e':
|
||||
env_name = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r = rtc_lookup(rtc_name);
|
||||
if (IS_ERR(r))
|
||||
return PTR_ERR(r);
|
||||
|
||||
if (set) {
|
||||
rtc_set_time(r, &stm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rtc_read_time(r, &tm);
|
||||
|
||||
if (env_name) {
|
||||
unsigned long time;
|
||||
char t[12];
|
||||
|
||||
rtc_tm_to_time(&tm, &time);
|
||||
snprintf(t, 12, "%lu", time);
|
||||
setenv(env_name, t);
|
||||
} else {
|
||||
printf("%02d:%02d:%02d %02d-%02d-%04d\n",
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec,
|
||||
tm.tm_mday, tm.tm_mon + 1, tm.tm_year + 1900);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BAREBOX_CMD_HELP_START(hwclock)
|
||||
BAREBOX_CMD_HELP_TEXT("Options:")
|
||||
BAREBOX_CMD_HELP_OPT ("-f NAME\t\t\t", "RTC device name (default rtc0)")
|
||||
BAREBOX_CMD_HELP_OPT ("-e VARNAME\t\t", "store RTC readout into variable VARNAME")
|
||||
BAREBOX_CMD_HELP_OPT ("-s ccyymmddHHMM[.SS]\t", "set time")
|
||||
BAREBOX_CMD_HELP_END
|
||||
|
||||
BAREBOX_CMD_START(hwclock)
|
||||
.cmd = do_hwclock,
|
||||
BAREBOX_CMD_DESC("query or set the hardware clock (RTC)")
|
||||
BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP)
|
||||
BAREBOX_CMD_HELP(cmd_hwclock_help)
|
||||
BAREBOX_CMD_END
|
Loading…
Reference in New Issue