From b4873b06e8015ad0ba3c9b70326889fca6eb38a7 Mon Sep 17 00:00:00 2001 From: zhangdengyu Date: Mon, 15 May 2023 22:18:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BF=AE=E5=A4=8Dtime=E4=B8=ADTIMEZONE?= =?UTF-8?q?=E4=BC=98=E5=85=88=E4=BD=BF=E7=94=A8RTC=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 方案描述: 1、time中timezone全局变量修改为优先从RTC获取 2、settimeofday接口,linux和posix标准有差异,m核中对齐posix标准,具体如下: int settimeofday(const struct timeval *tv, const struct timezone *tz) 2.1、linux中: tz参数已弃用,一般设置为NULL; tv参数,为NULL时返回0,不设置错误码,表示不修改当前时间; 2.2、posix中: tv或tz全部为NULL时,返回-1,设置错误码EFAULT; tv或tz有一个不为NULL时,不设置相应的参数,返回0;不设置错误码; 3、新增settimeofday接口设置timezone相关测试用例 BREAKING CHANGE: 修复time中TIMEZONE优先使用RTC模块的问题对外变更描述: 修改int settimeofday(const struct timeval *tv, const struct timezone *tz)接口 settimeofday接口对入参的判断逻辑修改: 1、tv或tz全部为NULL时,返回-1,设置错误码EFAULT; 2、tv或tz有一个不为NULL时,不设置相应的参数,返回0;不设置错误码; Close: #I73G40 Signed-off-by: zhangdengyu Change-Id: Id536fc27d8bf0697765ac1543776e8105e6f62f4 --- kal/posix/src/time.c | 63 +++++++++++++------ .../posix/src/time/time_func_test_01.c | 37 +++++++++++ 2 files changed, 82 insertions(+), 18 deletions(-) diff --git a/kal/posix/src/time.c b/kal/posix/src/time.c index b3787723..f5dc1dc6 100644 --- a/kal/posix/src/time.c +++ b/kal/posix/src/time.c @@ -613,11 +613,22 @@ struct tm *gmtime(const time_t *timer) struct tm *localtime_r(const time_t *timep, struct tm *result) { + INT32 ret; + if ((timep == NULL) || (result == NULL)) { errno = EFAULT; return NULL; } - if (!ConvertSecs2Utc(*timep, -TIMEZONE, result)) { + + if (g_rtcTimeFunc.RtcGetTimezoneHook != NULL) { + INT32 tempTimezone = 0; + g_rtcTimeFunc.RtcGetTimezoneHook(&tempTimezone); + ret = ConvertSecs2Utc(*timep, -tempTimezone, result); + } else { + ret = ConvertSecs2Utc(*timep, -TIMEZONE, result); + } + + if (!ret) { errno = EINVAL; return NULL; } @@ -660,7 +671,14 @@ static time_t ConvertUtc2Secs(struct tm *tm) seconds += (tm->tm_mday - 1) * SECS_PER_DAY; seconds += tm->tm_hour * SECS_PER_HOUR + tm->tm_min * SECS_PER_MIN + tm->tm_sec; - seconds += TIMEZONE; + if (g_rtcTimeFunc.RtcGetTimezoneHook != NULL) { + INT32 tempTimezone = 0; + g_rtcTimeFunc.RtcGetTimezoneHook(&tempTimezone); + seconds += tempTimezone; + } else { + seconds += TIMEZONE; + } + return seconds; } @@ -686,7 +704,14 @@ time_t mktime(struct tm *tmptr) } timeInSeconds = ConvertUtc2Secs(tmptr); /* normalize tm_wday and tm_yday */ - ConvertSecs2Utc(timeInSeconds, -TIMEZONE, tmptr); + if (g_rtcTimeFunc.RtcGetTimezoneHook != NULL) { + INT32 tempTimezone = 0; + g_rtcTimeFunc.RtcGetTimezoneHook(&tempTimezone); + ConvertSecs2Utc(timeInSeconds, -tempTimezone, tmptr); + } else { + ConvertSecs2Utc(timeInSeconds, -TIMEZONE, tmptr); + } + return timeInSeconds; } @@ -718,7 +743,7 @@ int gettimeofday(struct timeval *tv, void *ptz) tv->tv_usec = ts.tv_nsec / OS_SYS_NS_PER_US; } } - + if (tz != NULL) { if (g_rtcTimeFunc.RtcGetTimezoneHook != NULL) { INT32 tempTimezone = 0; @@ -740,12 +765,12 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz) { struct timespec ts; - if (tv == NULL) { + if ((tv == NULL) && (tz == NULL)) { errno = EFAULT; return -1; } - if (tv->tv_usec >= OS_SYS_US_PER_SECOND) { + if ((tv != NULL) && (tv->tv_usec >= OS_SYS_US_PER_SECOND)) { errno = EINVAL; return -1; } @@ -764,18 +789,20 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz) } } - if (g_rtcTimeFunc.RtcSetTimeHook != NULL) { - UINT64 usec; - g_rtcTimeBase = tv->tv_sec * OS_SYS_MS_PER_SECOND + tv->tv_usec / OS_SYS_MS_PER_SECOND; - usec = tv->tv_sec * OS_SYS_US_PER_SECOND + tv->tv_usec; - if (-1 == g_rtcTimeFunc.RtcSetTimeHook(g_rtcTimeBase, &usec)) { - return -1; - } - } else { - ts.tv_sec = tv->tv_sec; - ts.tv_nsec = tv->tv_usec * OS_SYS_NS_PER_US; - if (-1 == clock_settime(CLOCK_REALTIME, &ts)) { - return -1; + if (tv != NULL) { + if (g_rtcTimeFunc.RtcSetTimeHook != NULL) { + UINT64 usec; + g_rtcTimeBase = tv->tv_sec * OS_SYS_MS_PER_SECOND + tv->tv_usec / OS_SYS_MS_PER_SECOND; + usec = tv->tv_sec * OS_SYS_US_PER_SECOND + tv->tv_usec; + if (g_rtcTimeFunc.RtcSetTimeHook(g_rtcTimeBase, &usec) < 0) { + return -1; + } + } else { + ts.tv_sec = tv->tv_sec; + ts.tv_nsec = tv->tv_usec * OS_SYS_NS_PER_US; + if (clock_settime(CLOCK_REALTIME, &ts) < 0) { + return -1; + } } } diff --git a/testsuites/unittest/posix/src/time/time_func_test_01.c b/testsuites/unittest/posix/src/time/time_func_test_01.c index d891bf1d..4ed86769 100644 --- a/testsuites/unittest/posix/src/time/time_func_test_01.c +++ b/testsuites/unittest/posix/src/time/time_func_test_01.c @@ -293,6 +293,42 @@ LITE_TEST_CASE(PosixTimeFuncTestSuite, testTimeLocaltime002, Function | MediumTe return 0; } +/* * + * @tc.number SUB_KERNEL_TIME_LOCALTIME_003 + * @tc.name test settimeofday api + * @tc.desc [C- SOFTWARE -0200] + */ +LITE_TEST_CASE(PosixTimeFuncTestSuite, testTimeLocaltime003, Function | MediumTest | Level1) +{ + char cTime[32]; /* 32, no special meaning */ + time_t tStart; + time_t tEnd; + struct timezone tz; + struct timeval timeSet = { + .tv_sec = 86399, /* 86399, no special meaning */ + .tv_usec = 0 + }; + + int ret = gettimeofday(NULL, &tz); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + ret = settimeofday(&timeSet, &tz); + time(&tStart); + sleep(2); /* 2, sleep time */ + time(&tEnd); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); + + struct tm *tmStart = localtime(&tStart); + strftime(cTime, sizeof(cTime), "%H:%M:%S", tmStart); + ICUNIT_ASSERT_STRING_EQUAL(cTime, "07:59:59", 0); + LOG("\n time_t=%lld, first time:%s", tStart, cTime); + struct tm *tmEnd = localtime(&tEnd); + strftime(cTime, sizeof(cTime), "%H:%M:%S", tmEnd); + ICUNIT_ASSERT_STRING_EQUAL(cTime, "08:00:01", 0); + LOG("\n time_t=%lld, first time:%s", tEnd, cTime); + return 0; +} + /* * * @tc.number SUB_KERNEL_TIME_LOCALTIMER_001 * @tc.name localtime_r api base test @@ -593,6 +629,7 @@ void PosixTimeFuncTest(void) #if (LOSCFG_LIBC_MUSL == 1) RUN_ONE_TESTCASE(testTimeLocaltime001); RUN_ONE_TESTCASE(testTimeLocaltime002); + RUN_ONE_TESTCASE(testTimeLocaltime003); RUN_ONE_TESTCASE(testTimeLocaltimer001); RUN_ONE_TESTCASE(testTimeLocaltimer002); #endif