📄 clock.c
字号:
/* *---------------------------------------------------------------------- * T-Kernel / Standard Extension * * Copyright (C) 2006 by Ken Sakamura. All rights reserved. * T-Kernel / Standard Extension is distributed * under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * * Version: 1.00.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* * clock.c (clock) * * Time management */#include "clkmgr.h"#include <longlong.h>LOCAL STIME getSysTime( void );LOCAL void setSysTime( STIME time );LOCAL void NotifyClockUpdate( void );LOCAL ER getRealTime( STIME *time );LOCAL ER setRealTime( STIME time );LOCAL ER SetSystemTime( STIME time, TIMEZONE *tz );LOCAL ER InitSystemTime( void );LOCAL ER checkDATE_TIM( DATE_TIM *date );LOCAL ER checkTIMEZONE( TIMEZONE *tz );LOCAL ER _tkse_get_tim2( STIME *time, TIMEZONE *tz );LOCAL ER _tkse_set_tim2( STIME time, TIMEZONE *tz );LOCAL ER _tkse_get_tod( DATE_TIM *date_tim, STIME time, BOOL local );LOCAL ER _tkse_set_tod( DATE_TIM *date_tim, STIME *time, BOOL local );LOCAL ER _tkse_set_tim( SYSTIM *pk_tim );LOCAL ER _tkse_get_tim( SYSTIM *pk_tim );LOCAL ER _tkse_get_otm( SYSTIM *pk_tim );LOCAL WER SyscallEntry( VP para, W fn );LOCAL ER initialize( void );LOCAL ER finish( void );#define TSD_CDT_YMN_85 85#define TSD_CDT_YMX_153 153#define TSD_CDT_OMN_0 0#define TSD_CDT_OMX_12 12#define TSD_CDT_HMN_0 0#define TSD_CDT_HMX_23 23#define TSD_CDT_IMN_0 0#define TSD_CDT_IMX_59 59#define TSD_CDT_SMN_0 0#define TSD_CDT_SMX_59 59#define TSD_CDT_DMN_1 1#define TSD_CDT_DMX_31 31#define TSD_CDT_YDN_1 1#define TSD_CDT_YDX_366 366#define TSD_CLO_HUR_12 12#define TSD_CLO_HUR_9 9#define TSD_CLO_HUR_60 60#define TSD_CLO_SEC_60 60#define TSD_SNC_MIN_1000 1000#define TSD_TT2_VAL_M1 (-1)#define TSD_GYT_VAL_1000 1000#define TSD_SYT_VAL_1000 1000/* * Time management information */LOCAL ClkInfo clkInfo;/* * Clock device name */LOCAL /*const*/ UB clock[] = "CLOCK";/* * Obtain the T-Kernel system time. */LOCAL STIME getSysTime( void ){ SYSTIM tm; longlong systime; tk_get_tim(&tm); hilo_ll(systime, tm.hi, tm.lo); return lltol(li_div(systime, (long)TSD_GYT_VAL_1000));}/* * Set the T-Kernel system time. */LOCAL void setSysTime( STIME time ){ SYSTIM tm; longlong systime; systime = li_mul(ltoll(time), (long)TSD_SYT_VAL_1000); ll_hilo(tm.hi, tm.lo, systime); tk_set_tim(&tm);}/* ------------------------------------------------------------------------ */#ifndef TKERNEL_ONLYLOCAL ER startNotifyClockUpdate( void );/* * Timer handler for time update notification */LOCAL void NotifyClockUpdate( void ){ /* Time update notification */ tkse_brk_msg();}/* * Start the time update notification. * Perform the time update notification every minute at 0 seconds. */LOCAL ER startNotifyClockUpdate( void ){ STIME time; T_CCYC ccyc; ER err; if ( clkInfo.clkupd == 0 ) { return E_OK; } /* Stop the cyclic start handler in active. */ if ( clkInfo.cycid > 0 ) { tk_del_cyc(clkInfo.cycid); clkInfo.cycid = 0; } /* Disable the dispatch to minimize time lag. */ tk_dis_dsp(); time = getSysTime(); /* Start the cyclic start handler. */ SetOBJNAME(ccyc.exinf, "Clk"); ccyc.cycatr = TA_HLNG | TA_STA | TA_PHS; ccyc.cychdr = NotifyClockUpdate; ccyc.cyctim = TSD_CLO_SEC_60 * TSD_SNC_MIN_1000; /* One minute interval */ ccyc.cycphs = (UINT)((TSD_CLO_SEC_60 - (time % TSD_CLO_SEC_60)) * TSD_SNC_MIN_1000); /* Remaining time until 0 seconds */ err = tk_cre_cyc(&ccyc); tk_ena_dsp(); if ( err < E_OK ) { err = ERtoERR(err); goto err_ret; } clkInfo.cycid = (ID)err; return E_OK;err_ret: DEBUG_PRINT(("startNotifyClockUpdate err = %d\n", err)); return err;}#else /* TKERNEL_ONLY */#define startNotifyClockUpdate() ( E_OK )#endif /* TKERNEL_ONLY *//* ------------------------------------------------------------------------ *//* * Obtain the clock device time. */LOCAL ER getRealTime( STIME *time ){ W dd; DATE_TIM date; W s; ER err; /* Obtain the calendar day/time from the clock device. */ dd = tk_opn_dev(clock, TD_READ); if ( dd < E_OK ) { err = dd; goto err_ret1; } err = tk_srea_dev(dd, DN_CKDATETIME, &date, sizeof(date), &s); if ( err < E_OK ) { goto err_ret2; } err = tk_cls_dev(dd, 0); if ( err < E_OK ) { goto err_ret1; } /* Convert the calendar day/time into the total number of seconds. */ DATEtoTIME(time, &date); return E_OK;err_ret2: (void)tk_cls_dev(dd, 0);err_ret1: DEBUG_PRINT(("getRealTime err = %d\n", err)); return ERtoERR(err);}/* * Set the clock device time. * In the case of the system without clock device, return E_OK * without doing anything. */LOCAL ER setRealTime( STIME time ){ W dd; DATE_TIM date; W s; ER err; /* Convert into the calendar day/time. */ TIMEtoDATE(&date, time); /* Set the calendar day/time to the clock device. */ dd = tk_opn_dev(clock, TD_WRITE); if ( dd < E_OK ) { err = dd; goto err_ret1; } err = tk_swri_dev(dd, DN_CKDATETIME, &date, sizeof(date), &s); if ( err < E_OK ) { goto err_ret2; } err = tk_cls_dev(dd, 0); if ( err < E_OK ) { goto err_ret1; } return E_OK;err_ret2: (void)tk_cls_dev(dd, 0);err_ret1: DEBUG_PRINT(("setRealTime err = %d\n", err)); return ( err == E_NOEXS )? E_OK: ERtoERR(err);}/* * Set the system time. * Set the system time to the T-Kernel and clock device. * When time <= 0, do not set the T-Kernel time. * When tz == NULL, do not set the time correction data. * * (*) Set the T-Kernel time, clock device time and time correction data compatibly. * If an error occurs, do not set all of them. * Be sure to avoid the inconsistent condition where any of them are not set. */LOCAL ER SetSystemTime( STIME time, TIMEZONE *tz ){ STIME ltime; ER err; /* Because the local time is set to the clock device, the clock device time is required to be updated even if only the time correction data is changed. */ ltime = ( time > 0 )? time: getSysTime(); if ( tz == NULL ) { LOCK_CM( ltime = GMTtoLT(ltime, &clkInfo.tz) ); } else { ltime = GMTtoLT(ltime, tz); } err = setRealTime(ltime); if ( err < E_OK ) { goto err_ret; } if ( time > 0 ) { /* Set the T-Kernel time. */ setSysTime(time); } if ( tz != NULL ) { /* Set the time correction data. */ LOCK_CM( clkInfo.tz = *tz ); } /* Start the time update notification. */ err = startNotifyClockUpdate(); if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("SetSystemTime err = %d\n", err)); return err;}/* * Initialize the system time. * Set the time obtained from the clock device to T-Kernel. */LOCAL ER InitSystemTime( void ){ STIME gtime, ltime; ER err; /* Obtain the time from the clock device. */ err = getRealTime(<ime); if ( err < E_OK ) { goto err_ret; } /* Reverse correction of the local time */ LOCK_CM( gtime = LTtoGMT(ltime, &clkInfo.tz) ); if ( gtime < 0 ) { err = E_SYS; goto err_ret; } /* Set the T-Kernel time. */ setSysTime(gtime); /* Start the time update notification. */ err = startNotifyClockUpdate(); if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("InitSystemTime err = %d\n", err)); return err;}/* ------------------------------------------------------------------------ */#define chkRange(val, min, max) ( ((val) >= (min)) && ((val) <= (max)) )/* * DATE_TIM parameter check */LOCAL ER checkDATE_TIM( DATE_TIM *date ){ return ( chkRange(date->d_year, TSD_CDT_YMN_85, TSD_CDT_YMX_153) && chkRange(date->d_month, TSD_CDT_OMN_0, TSD_CDT_OMX_12) && chkRange(date->d_hour, TSD_CDT_HMN_0, TSD_CDT_HMX_23) && chkRange(date->d_min, TSD_CDT_IMN_0, TSD_CDT_IMX_59) && chkRange(date->d_sec, TSD_CDT_SMN_0, TSD_CDT_SMX_59) && (( date->d_month != TSD_CDT_OMN_0 )? chkRange(date->d_day, TSD_CDT_DMN_1, TSD_CDT_DMX_31): chkRange(date->d_days, TSD_CDT_YDN_1, TSD_CDT_YDX_366)) )? E_OK: E_PAR;}/* * TIMEZONE parameter check */LOCAL ER checkTIMEZONE( TIMEZONE *tz ){ return ( (chkRange(tz->adjust, -(TSD_CLO_HUR_12 * TSD_CLO_HUR_60 * TSD_CLO_SEC_60), +(TSD_CLO_HUR_12 * TSD_CLO_HUR_60 * TSD_CLO_SEC_60))) && (chkRange(tz->dst_adj, -(TSD_CLO_HUR_12 * TSD_CLO_HUR_60), +(TSD_CLO_HUR_12 * TSD_CLO_HUR_60))) )? E_OK: E_PAR;}/* ------------------------------------------------------------------------ *//* * Obtain the system time. */LOCAL ER _tkse_get_tim2( STIME *time, TIMEZONE *tz ){ ER err; if ( time != NULL ) { err = CheckSpaceRW(time, sizeof(*time)); if ( err < E_OK ) { goto err_ret;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -