#include <stdio.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <time.h>
|
#include <errno.h>
|
#include <fcntl.h>
|
#include <sys/ioctl.h>
|
#include <sys/time.h>
|
#include <linux/rtc.h>
|
#include <unistd.h>
|
#include <ctype.h>
|
|
#include "common.h"
|
#include "rtc_test.h"
|
#include "script.h"
|
#include "test_case.h"
|
#include "Language/language.h"
|
|
|
#define TAG "[PCBA,RTC]: "
|
#define LOG(x...) printf(TAG x)
|
|
|
int rtc_xopen(int flags)
|
{
|
int rtc;
|
char major_rtc[] = "/dev/rtc";
|
char minor_rtc[] = "/dev/rtc0";
|
|
rtc = open(major_rtc, flags);
|
if (rtc < 0) {
|
rtc = open(minor_rtc, flags);
|
if (rtc < 0) {
|
printf("open %s failed:%s\n", minor_rtc,
|
strerror(errno));
|
}
|
}
|
|
else {
|
printf("open %s\n", major_rtc);
|
}
|
return rtc;
|
}
|
|
int rtc_read_tm(struct tm *ptm, int fd)
|
{
|
int ret;
|
|
memset(ptm, 0, sizeof(*ptm));
|
|
ret = ioctl(fd, RTC_RD_TIME, ptm);
|
if (ret < 0)
|
printf("read rtc failed:%s\n", strerror(errno));
|
else
|
ptm->tm_isdst = -1; /* "not known" */
|
|
return ret;
|
}
|
|
static int read_rtc(time_t *time_p)
|
{
|
int fd;
|
int ret;
|
struct tm tm_time;
|
|
//fd = rtc_xopen(O_RDONLY);
|
fd = open("/dev/rtc0", O_RDONLY);
|
if (fd < 0)
|
return fd;
|
else
|
ret = rtc_read_tm(&tm_time, fd);
|
|
close(fd);
|
|
if (ret < 0)
|
return ret;
|
|
else
|
*time_p = mktime(&tm_time);
|
|
return 0;
|
}
|
|
int get_system_time(char *dt)
|
{
|
int ret;
|
int fd;
|
time_t t;
|
time_t timep;
|
struct tm *p;
|
|
ret = read_rtc(&timep);
|
if (ret < 0)
|
return ret;
|
|
else
|
p = localtime(&timep);
|
|
sprintf(dt, "%04d-%02d-%02d %02d:%02d:%02d", (1900 + p->tm_year),
|
(1 + p->tm_mon), p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
|
|
return 0;
|
}
|
|
int set_system_time(struct timeval *tv)
|
{
|
int ret;
|
int fd;
|
|
fd = open("/dev/rtc0", O_RDWR);
|
if (fd < 0) {
|
printf("open /dev/rtc0 failed:%s\n", strerror(errno));
|
return -1;
|
}
|
ret = ioctl(fd, RTC_SET_TIME, tv);
|
//ret = ioctl(fd, ANDROID_ALARM_SET_RTC, tv);
|
if (ret < 0) {
|
printf("set rtc failed:%s\n", strerror(errno));
|
return -1;
|
}
|
|
close(fd);
|
|
return 0;
|
}
|
|
|
void *rtc_test(void *argc)
|
{
|
struct testcase_info *tc_info = (struct testcase_info *)argc;
|
char dt[32] = { "20120926.132600" };
|
int ret, y;
|
struct tm tm;
|
struct timeval tv;
|
char *s;
|
int day, hour;
|
time_t t;
|
struct tm *p;
|
struct timespec ts;
|
struct rtc_time rtc;
|
|
/* remind ddr test */
|
if (tc_info->y <= 0)
|
tc_info->y = get_cur_print_y();
|
y = tc_info->y;
|
|
ui_print_xy_rgba(0, y, 255, 255, 0, 255, "%s:[%s..]\n", PCBA_RTC,
|
PCBA_TESTING);
|
|
#if 0
|
s = malloc(32);
|
if (script_fetch("rtc", "module_args", (int *)dt, 8) == 0)
|
strncpy(s, dt, 32);
|
day = atoi(s);
|
while (*s && *s != '.')
|
s++;
|
if (*s)
|
s++;
|
hour = atoi(s);
|
|
tm.tm_year = day / 10000 - 1900;
|
tm.tm_mon = (day % 10000) / 100 - 1;
|
tm.tm_mday = (day % 100);
|
tm.tm_hour = hour / 10000;
|
tm.tm_min = (hour % 10000) / 100;
|
tm.tm_sec = (hour % 100);
|
tm.tm_isdst = -1;
|
tv.tv_sec = mktime(&tm);
|
tv.tv_usec = 0;
|
printf("set rtc time :%lu\n", tv.tv_sec);
|
//ret = set_system_time(&tv);
|
ret = set_system_time(&tm);
|
if (ret < 0) {
|
printf("test rtc failed:set_system_time failed\n");
|
ret = -1;
|
}
|
|
else {
|
sleep(1);
|
|
while (1) {
|
t = get_system_time(dt);
|
if (t < 0) {
|
ret = -1;
|
break;
|
}
|
p = localtime(&t);
|
|
ui_display_sync(0, y, 0, 255, 0, 255,
|
"%s:[%s] { %04d/%02d/%02d %02d:%02d:%02d }\n",
|
PCBA_RTC, PCBA_SECCESS,
|
(1900 + p->tm_year),
|
(1 + p->tm_mon), p->tm_mday,
|
p->tm_hour, p->tm_min, p->tm_sec);
|
sleep(1);
|
}
|
}
|
#else
|
{
|
int rst;
|
char result_filename[100] = {0};
|
|
LOG("=======pcba_core :start rtc test========\n");
|
rst = run_test_item_cmd("echo_auto_test echo_rtc_test");
|
|
if(rst == 0) {
|
snprintf(result_filename, sizeof(result_filename),
|
"%s/echo_%s_test_result", "/tmp",tc_info->base_info->name);
|
ret = parse_test_result(result_filename, "rtc_test", NULL);
|
} else {
|
return NULL;
|
}
|
|
#define MINOR_RTC_PATH "/dev/rtc0"
|
|
//show time
|
if (ret == 0) {
|
int fd,ret;
|
struct tm tm_p;
|
|
//LOG("==========rtc_get_system_time_test start===========\n");
|
//fd = rtc_xopen(O_RDONLY|O_NOCTTY|O_NDELAY);
|
fd = open(MINOR_RTC_PATH, O_RDONLY);
|
if (fd < 0) {
|
LOG("open %s failed:%s\n", MINOR_RTC_PATH,strerror(errno));
|
return argc;
|
}
|
|
memset(&tm_p,0,sizeof(tm_p));
|
ret = ioctl(fd, RTC_RD_TIME, &tm_p);
|
if (ret < 0) {
|
LOG("test rtc failed:get_system_time failed: %s\n",strerror(errno));
|
tc_info->result = -1;
|
ui_print_xy_rgba(0, y, 255, 0, 0, 255, "%s:[%s]\n",
|
PCBA_RTC, PCBA_FAILED);
|
return NULL;
|
}
|
else {
|
//LOG("rtc test: rtc_get_system_time success.\n");
|
mktime(&tm_p); //ʹÓÃmktimeº¯ÊýµÃµ½time_t¸ñʽµÄÊä³ö
|
|
//LOG("test time is: %04d-%02d-%02d %02d:%02d:%02d\n", 1900+tm_p.tm_year,
|
// 1 + tm_p.tm_mon, tm_p.tm_mday, tm_p.tm_hour, tm_p.tm_min, tm_p.tm_sec);
|
|
tc_info->result = 0;
|
ui_display_sync(0, y, 0, 255, 0, 255,
|
"%s:[%s] { %04d/%02d/%02d %02d:%02d:%02d }\n",
|
PCBA_RTC, PCBA_SECCESS,
|
1900+tm_p.tm_year, 1 + tm_p.tm_mon, tm_p.tm_mday,
|
tm_p.tm_hour, tm_p.tm_min, tm_p.tm_sec);
|
}
|
|
//LOG("System time is :%s\n",asctime(&tm_p));
|
close(fd);
|
//LOG("==========rtc_get_system_time_test finish.===========\n");
|
return 0;
|
} else {
|
tc_info->result = -1;
|
ui_print_xy_rgba(0, y, 255, 0, 0, 255, "%s:[%s]\n",
|
PCBA_RTC, PCBA_FAILED);
|
return argc;
|
}
|
}
|
#endif
|
if (ret == 0) {
|
tc_info->result = 0;
|
ui_print_xy_rgba(0, y, 0, 255, 0, 255, "%s:[%s]\n",
|
PCBA_RTC, PCBA_SECCESS);
|
} else {
|
tc_info->result = -1;
|
ui_print_xy_rgba(0, y, 255, 0, 0, 255, "%s:[%s]\n",
|
PCBA_RTC,PCBA_FAILED);
|
}
|
return argc;
|
}
|