/******************************************************************************* 版权所有: 版本号: 1.00 文件名: sysTime.c 生成日期: 2008.8.16 作者: 功能说明:系统时间维护及GPS对时处理 修改日志: 日志1: 修改者: 修改日期: 修改内容: 修改原因: ****************************************************************************/ #include "head.h" #ifdef CPU_FUXI #include #include #include #include #endif extern unsigned int g_keep_alive_gps; #ifdef CPU_FUXI int g_rtc_ok; #endif void sys_time_get(struct rtc_time_t *pct) { struct timespec ts; clk_time_get(&ts); timespec_to_rtc(ts,pct,1); } #ifdef CPU_FUXI int sys_time_set(struct rtc_time_t *pct) { int ret = 0; char pchDT[30]; struct timespec ts; SHM_TS_T shm_ts; if(rtc_to_timespec(pct,&ts) != 0) { return -1; } shm_ts.ts = ts; // shm_comm_packet_write(SHM_ADDR_D_TIME, (uint8_t *)&shm_ts, sizeof(SHM_TS_T)); mb_notice_time_update(); sprintf(pchDT, "date -s '%04d-%02d-%02d %02d:%02d:%02d'", pct->year + 2000, pct->month, pct->day, pct->hour, pct->min, pct->ms / 1000); system(pchDT); system("hwclock -w"); system("sync"); rt_printf("设置系统时间: %s\n", pchDT); ret = gps_set_time(&ts); return ret; } int sys_time_set_kernal(struct rtc_time_t *pct) { int ret = 0; char pchDT[30]; struct timespec ts; if(rtc_to_timespec(pct,&ts) != 0) { return -1; } sprintf(pchDT, "date -s '%04d-%02d-%02d %02d:%02d:%02d'", pct->year + 2000, pct->month, pct->day, pct->hour, pct->min, pct->ms / 1000); system(pchDT); system("hwclock -w"); system("sync"); printf("设置系统时间: %s\n", pchDT); ret = gps_set_time(&ts); return ret; } void sys_time_check(void) { struct rtc_time_t ct; SHM_TS_T shm_ts; int ret; if(g_rtc_ok < 0) { ret = shm_comm_packet_read(SHM_ADDR_U_TIME, sizeof(SHM_TS_T), (uint8_t *)&shm_ts, sizeof(SHM_TS_T)); if(ret >= 0) { g_rtc_ok = 0; timespec_to_rtc(shm_ts.ts, &ct, 1); if(ct.hour>=24||ct.min>=60||ct.month>12||ct.day>31||ct.day==0||ct.month==0) // 读取时钟错误 { rt_printf("app read rtc data error."); return; } sys_time_set_kernal(&ct); rt_printf("app read rtc succeed."); } } } #else int sys_time_set(struct rtc_time_t *pct) { int ret; struct timespec ts; if(rtc_to_timespec(pct,&ts) != 0) { return -1; } ret = clk_time_set(&ts); return ret; } #endif void sys_time_set_rmt(struct rtc_time_t *pt) { sys_time_set(pt); } void sys_time_init_zero(struct rtc_time_t *p_mt) { p_mt->year=8; p_mt->month=8; p_mt->day=8; p_mt->hour=8; p_mt->min=8; p_mt->ms=8000; } // 系统时钟已在clk_init中初始化,此处重新初始化是为了保存SOE. #ifdef CPU_FUXI void sys_time_init(void) { struct rtc_time_t ct; SHM_TS_T shm_ts; bool err=false; int ret,i; // GPS已ok,不检查实时时钟 if(g_keep_alive_gps) { return; } #if 0 if(rtc_time_read((struct rtc_time_t*)&ct)!=0) { err=true; } #else i = 0; while(1) { ret = shm_comm_packet_read(SHM_ADDR_U_TIME, sizeof(SHM_TS_T), (uint8_t *)&shm_ts, sizeof(SHM_TS_T)); if(ret >= 0) { break; } i++; if(i > 100) { err=true; break; } msleep(100);// 延时100ms } timespec_to_rtc(shm_ts.ts, &ct, 1); #endif if(ct.hour>=24||ct.min>=60||ct.month>12||ct.day>31||ct.day==0||ct.month==0) // 读取时钟错误 { err=true; } if(err) { sys_time_init_zero(&ct); rt_err_set(ERR_CODE_RTC,0); #if 0 sys_time_set(&ct); #endif g_rtc_ok = -1; return; } sys_time_set_kernal(&ct); } #else void sys_time_init(void) { struct rtc_time_t ct; bool err=false; // GPS已ok,不检查实时时钟 if(g_keep_alive_gps) { return; } if(rtc_time_read((struct rtc_time_t*)&ct)!=0) { err=true; } if(ct.hour>=24||ct.min>=60||ct.month>12||ct.day>31||ct.day==0||ct.month==0) // 读取时钟错误 { err=true; } if(err) { extern struct timespec g_sys_time; int ret; sys_time_init_zero(&ct); rtc_to_timespec(&ct,&g_sys_time); ret = rtc_time_write(&ct); if(ret == 0) { rt_err_clr(ERR_CODE_RTC,0); } } } #endif void sys_time_change(struct rtc_time_t *p_ct) { p_ct->min++; if(p_ct->min>=60) { p_ct->min=0; p_ct->hour++; if(p_ct->hour>=24) { bool bdayflag=false; p_ct->hour=0; p_ct->day++; if(p_ct->month==2) // 2月 { if(p_ct->day>28) { WORD year=p_ct->year+2000; if(year%4==0) //闰年 2月29天,其他28天 { if(p_ct->day>29) { bdayflag=true; } } else { bdayflag=true; } } } else { if(p_ct->day>30) { if(p_ct->month==2||p_ct->month==4||p_ct->month==6||p_ct->month==9||p_ct->month==11) { bdayflag=true; } if(p_ct->day>31) { bdayflag=true; } } } if(bdayflag) { p_ct->day=1; p_ct->month++; if(p_ct->month>12) { p_ct->month=1; p_ct->year++; } } } } } #define RTC_WRITE_PERIOD (600UL*USTIMER_SEC) void clk_app(void) { static uint32_t us0 = -(RTC_WRITE_PERIOD -20*USTIMER_SEC); // 启动20S后更新一次 struct timespec ts; struct rtc_time_t rtc; // 旧系统的时间更新策略是有GPS对时,每隔10分钟,更新一次时钟芯片时间 // 没有外部对时1000秒从时钟芯片更新一次系统时间。这种策略将导致没有外部 // 对时的时候,系统时间波动较大,导致时间测量不准。 // 新系统的时间策略是,不管什么情况,每隔10分钟,更新一次时钟芯片时间. // 这样系统时间就不会有较大波动。 // 每隔10分钟,更新一次时钟芯片时间 if(ustimer_delay_origin2(&us0,RTC_WRITE_PERIOD) != 1) { return; } gps_get_time(&ts); if(timespec_to_rtc(ts,&rtc,1) != 0) { rt_printf("clk_app:timespec_to_rtc err.\r\n"); return; } if(rtc_time_write(&rtc) != 0) { rt_printf("clk_app:rtc_time_write err.\r\n"); return; } rt_err_clr(ERR_CODE_RTC,0); }