116 #include "sysconfig.h" 127 #define DEF_SYSTIME_INC_COUNT (1000 * GSC_KERNEL_TIMER_INTERVAL_MSEC) 135 #ifdef GSC_DEV_ENABLE_RTC 137 #ifndef GSC_RTC_RESOLUTION_IS_NOT_SEC // $gsc RTCの解像度は秒より精細 149 static volatile enum tsync_status tsync_status;
153 #ifdef GSC_DEV_ENABLE_RTC // $gsc リアルタイムクロックを有効にする 164 SYSERR_PRINT(
"NO RTC Device.\n");
169 SYSERR_PRINT(
"Cannot read time from RTC.\n");
178 static void disp_systime(
struct st_datetime *rtcdatetime)
180 char str[DATEMTIME_STR_LEN+1];
184 DKPRINTF(0x01,
"RTC : %s\n", str);
188 DKPRINTF(0x01,
"SYS : %s\n", str);
191 DKPRINTF(0x01,
"Increment : %d\n", systime_inc_count);
195 #ifdef GSC_DEV_ENABLE_RTC 196 #ifdef GSC_RTC_DATETIME_SYNC_CYCLE 197 #define SYSTIME_ADJUST_MARGIN (1000 * 100) // システム時間補正しない誤差(100ms) 199 #define ABS(x) ((x) < 0 ? -(x) : (x)) 201 static void calc_systime_inc_count(
struct st_systime *rtcsystime)
203 unsigned long long system_time_count;
204 unsigned long long rtc_time_count;
205 int rtc_sys_diff_count;
206 int error_correction = 0;
209 rtc_time_count = ((
unsigned long long)(rtcsystime->
sec) * 1000000) + rtcsystime->
usec;
211 rtc_sys_diff_count = (int)(rtc_time_count - system_time_count);
213 DKPRINTF(0x01,
"RTC_COUNT : %lld\n", rtc_time_count);
214 DKPRINTF(0x01,
"SYS_COUNT : %lld\n", system_time_count);
215 DKPRINTF(0x01,
"RTC DIFF : %d\n", rtc_sys_diff_count);
217 error_correction = rtc_sys_diff_count / GSC_RTC_DATETIME_SYNC_CYCLE;
218 DKPRINTF(0x01,
"Error correction : %d\n", error_correction);
221 if(ABS(rtc_sys_diff_count) <= SYSTIME_ADJUST_MARGIN) {
225 DKPRINTF(0x01,
"difference > %d\n", SYSTIME_ADJUST_MARGIN);
228 DKPRINTF(0x01,
"systime_inc_count : %d\n", systime_inc_count);
242 #ifdef GSC_DEV_ENABLE_RTC 243 int flg_just_sec = 0;
246 UNUSED_VARIABLE(ktime);
252 #ifdef GSC_DEV_ENABLE_RTC 259 #ifdef GSC_DEV_ENABLE_RTC 260 switch(tsync_status) {
266 DKPRINTF(0x01,
"RTC device not found\n");
267 tsync_status = TSYNC_NONE;
275 DKPRINTF(0x02,
"kernel time = %d\n", (
int)ktime);
276 if(read_rtc_time(&rtcdatetime) != 0) {
277 SYSERR_PRINT(
"RTC access fail\n");
278 tsync_status = TSYNC_NONE;
281 char str[DATEMTIME_STR_LEN+1];
283 DKPRINTF(0x02,
"RTC time : %s\n", str);
286 #ifdef GSC_RTC_RESOLUTION_IS_NOT_SEC // 288 tsync_status = TSYNC_NONE;
289 #else // GSC_RTC_RESOLUTION_IS_NOT_SEC 290 if(last_rtcsystime.sec == 0) {
292 DKPRINTF(0x02,
"RTC resolution is sec\n");
293 last_rtcsystime.sec = rtcsystime.
sec;
294 last_rtcsystime.usec = rtcsystime.
usec;
297 if(last_rtcsystime.sec != rtcsystime.
sec) {
299 tsync_status = TSYNC_NONE;
302 #endif // GSC_RTC_RESOLUTION_IS_NOT_SEC 304 if(tsync_status == TSYNC_NONE) {
305 disp_systime(&rtcdatetime);
306 DKPRINTF(0x01,
"Time sync done.\n");
313 #ifdef GSC_RTC_DATETIME_SYNC_CYCLE 316 DKPRINTF(0x01,
"RTC device not found\n");
317 tsync_status = TSYNC_NONE;
325 DKPRINTF(0x02,
"kernel time = %d\n", (
int)ktime);
326 if(read_rtc_time(&rtcdatetime) != 0) {
327 SYSERR_PRINT(
"RTC access fail\n");
328 tsync_status = TSYNC_NONE;
331 char str[DATEMTIME_STR_LEN+1];
333 DKPRINTF(0x02,
"RTC time : %s\n", str);
336 #ifdef GSC_RTC_RESOLUTION_IS_NOT_SEC // 337 calc_systime_inc_count(&rtcsystime);
338 tsync_status = TSYNC_NONE;
339 #else // GSC_RTC_RESOLUTION_IS_NOT_SEC 340 if(last_rtcsystime.sec == 0) {
342 DKPRINTF(0x02,
"RTC resolution is sec\n");
343 last_rtcsystime.sec = rtcsystime.
sec;
344 last_rtcsystime.usec = rtcsystime.
usec;
347 if(last_rtcsystime.sec != rtcsystime.
sec) {
348 calc_systime_inc_count(&rtcsystime);
349 tsync_status = TSYNC_NONE;
352 #endif // GSC_RTC_RESOLUTION_IS_NOT_SEC 354 if(tsync_status == TSYNC_NONE) {
355 disp_systime(&rtcdatetime);
356 DKPRINTF(0x01,
"Time adjust done.\n");
365 SYSERR_PRINT(
"Invalid status %d\n", tsync_status);
368 #endif // GSC_RTC_DATETIME_SYNC_CYCLE 370 #ifdef GSC_DEV_ENABLE_RTC 371 if(flg_just_sec != 0) {
380 "Sunday",
"Monday",
"Tuesday",
"Wednesday",
381 "Thursday",
"Friday",
"Saturday" 392 (void)
tsnprintf(str, DATE_STR_LEN,
"%4d/%02d/%02d %3s",
407 (void)
tsnprintf(str, TIME_STR_LEN,
"%02d:%02d:%02d",
422 (void)
tsnprintf(&str[TIME_STR_LEN-1], MSEC_STR_LEN,
".%03d", time->
msec);
434 str[DATE_STR_LEN-1] =
' ';
447 str[DATE_STR_LEN-1] =
' ';
451 #ifdef GSC_DEV_ENABLE_RTC 457 static int sync_time(
void)
459 DKPRINTF(0x01,
"Time synchronization...\n");
462 SYSERR_PRINT(
"NO RTC Device.\n");
466 #ifndef GSC_RTC_RESOLUTION_IS_NOT_SEC 467 last_rtcsystime.sec = 0;
468 last_rtcsystime.usec = 0;
470 tsync_status = TSYNC_SYNC;
472 while(tsync_status != TSYNC_NONE) {
473 #ifdef GSC_TARGET_SYSTEM_EMU 478 DKPRINTF(0x01,
"Time sync done.\n");
493 SYSERR_PRINT(
"NO RTC Device\n");
498 SYSERR_PRINT(
"Cannot set time to RTC.\n");
519 tsync_status = TSYNC_NONE;
520 l_system_time.
sec = 0;
521 l_system_time.
usec = 0;
526 SYSERR_PRINT(
"Cannot register time func.\n");
530 #ifdef GSC_DEV_ENABLE_RTC 538 SYSERR_PRINT(
"Cannot open RTC device.\n");
563 static void jd2greg(
int jd,
short *year,
char *month,
char *day)
569 century = (4 * jd - 1)/ 146097L;
570 jd -= 146097L * century / 4;
571 y = (4 * jd - 1) / 1461;
574 m = (5 * jd - 3) / 153 + 3;
575 jd -= (153 * m - 457) / 5;
597 return (year + year/4 - year/100 + year/400
598 + (13 * month + 8)/5 + day) % 7;
600 static const int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
602 return (year + year/4 - year/100 + year/400 + t[month-1] + day) % 7;
617 }
else if(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) {
636 const static int mofd[12] = {
637 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
640 if((month > 12) || (month < 1)) {
644 rt = mofd[month - 1];
660 t_time
sec = unixtime->
sec;
661 t_time jday = (sec/((int)24*60*60)) + 2440588;
663 DKPRINTF(0x02,
"jday = %d\n", jday);
665 jd2greg(jday, &(datetime->
year), &(datetime->
month),
672 datetime->
hour = ((sec % (24L*60*60)) / (60*60));
673 datetime->
min = ((sec % (60*60)) / 60);
674 datetime->
sec = (sec % 60);
675 datetime->
msec = unixtime->
usec / 1000;
706 int year = datetime->
year;
707 int month = datetime->
month;
710 if((month -= 2) < 1) {
715 utc = (year/4 - year/100 + year/400
716 + 367L*month/12 + datetime->
day) + year*365 - 719499L;
718 DKPRINTF(0x02,
"day = %d\n", utc);
720 utc *= ((int)24*60*60);
721 utc += ((int)(datetime->
hour)*(60*60) + datetime->
min*60 + datetime->
sec);
739 systime->
usec = datetime->
msec * 1000;
753 #ifdef GSC_DEV_ENABLE_RTC 754 sync_rtc_from_systime();
757 (void)
eprintf(
"Set RTC Time = %d.%03d\n", (
int)systime->
sec, (int)systime->
usec/1000);
783 if(time.
year < 1980) {
787 return ((
unsigned int)(time.
year-1980) << 25) +
788 ((
unsigned int)(time.
month) << 21) +
789 ((
unsigned int)(time.
day) << 16) +
790 ((
unsigned int)(time.
hour) << 11) +
791 ((
unsigned int)(time.
min) << 5) +
792 ((
unsigned int)(time.
sec) / 2);
825 #ifdef GSC_DEV_ENABLE_RTC 829 void sync_systime_from_rtc(
void)
834 #ifdef GSC_RTC_DATETIME_SYNC_CYCLE 838 void adjust_systime(
void)
840 #ifndef GSC_RTC_RESOLUTION_IS_NOT_SEC 841 last_rtcsystime.sec = 0;
842 last_rtcsystime.usec = 0;
844 tsync_status = TSYNC_ADJUST;
851 void sync_rtc_from_systime(
void)
858 (void)set_rtc(&datetime);
int init_time(char *devname)
時計を初期する
void datetime_to_str(char *str, struct st_datetime *time)
時間を日付時間文字列に変換する
static void time_count_proc(void *sp, unsigned long long ktime)
システムタイマ定期処理タイマ関数
void register_sec_timer_func(timer_func func)
時刻秒更新に同期した1秒周期処理を登録する
struct st_device * open_device(char *name)
デバイスをオープンする
void datemtime_to_str(char *str, struct st_datetime *time)
時間を日付ミリ秒時間文字列に変換する
void datetime_to_systime(struct st_systime *systime, struct st_datetime *datetime)
ローカル西暦年月日、時間よりシステム時間を求める
#define IOCMD_RTC_GET
時刻を取得する
int is_leap_year(int year)
うるう年か調べる
char date_to_dayofweek(short year, char month, char day)
西暦年、月、日より曜日を求める
int register_timer_func(timer_func func, unsigned long interval)
周期処理を追加する
void time_to_str(char *str, struct st_datetime *time)
時間を時間文字列に変換する
#define GSC_KERNEL_TIMER_INTERVAL_MSEC
$gsc カーネルタイマ割り込み間隔(ms)
t_time get_systime_sec(void)
システム時間(秒)を取得する
void mtime_to_str(char *str, struct st_datetime *time)
時間をミリ秒時間文字列に変換する
void unixtime_to_datetime(struct st_datetime *datetime, struct st_systime *unixtime)
UNIX時間より時刻を求める
#define IOCMD_RTC_SET
時刻を設定する
void date_to_str(char *str, struct st_datetime *time)
時間を日付文字列に変換する
unsigned long long kernel_time_count
カーネル時間(ms)
unsigned int fattime(void)
FAT 現在実時間を取得する
int eprintf(const char *fmt,...)
エラー出力用簡易printf
void set_systime(struct st_systime *systime)
UTC時刻からシステム時間を設定する
void get_systime(struct st_systime *systime)
システム時間を取得する
static const char weekname[7][10]
曜日文字列
void systime_to_datetime(struct st_datetime *datetime, struct st_systime *stime)
システム時間よりローカル時刻を求める
char dayofweek
曜日 0:日曜日〜6:土曜日
#define GSC_DIFF_FROM_LOCAL_TIME_SEC
$gsc UTCと日本時間(+9時間)との時差(秒)
void(* timer_func)(void *sp, unsigned long long systime)
カーネルタイマ周期処理関数の型
struct st_systime system_time
t_time datetime_to_utc(struct st_datetime *datetime)
ローカル西暦年月日、時間よりUTCを求める
int ioctl_device(struct st_device *dev, unsigned int com, unsigned int arg, void *param)
デバイスを制御する
timer_func sec_timer_func
1秒間隔処理関数
#define DEF_SYSTIME_INC_COUNT
システム時間カーネルタイマ間隔増加分
int tsnprintf(char *str, unsigned int size, const char *fmt,...)
簡易snprintf
int num_of_day_in_month(int year, int month)
うるう月か調べる