From ff0b6d241beafd99b41d5ea91e29b4869ecbcfc0 Mon Sep 17 00:00:00 2001 From: armink Date: Wed, 29 Sep 2021 17:12:27 +0800 Subject: [PATCH 1/6] [DeviceDriver][RTC] Remove RT_DEVICE_CTRL_RTC_GET_TIME_US and RT_DEVICE_CTRL_RTC_SET_TIME_US. Add RT_DEVICE_CTRL_RTC_GET_TIMEVAL and RT_DEVICE_CTRL_RTC_SET_TIMEVAL. The RT_DEVICE_CTRL_RTC_GET_TIMEVAL cmd can get second time and microsecond time. --- components/drivers/include/drivers/rtc.h | 12 +- components/libc/compilers/common/time.c | 148 ++++++----------------- 2 files changed, 42 insertions(+), 118 deletions(-) diff --git a/components/drivers/include/drivers/rtc.h b/components/drivers/include/drivers/rtc.h index 0bafbad7ad..f8702a2e99 100644 --- a/components/drivers/include/drivers/rtc.h +++ b/components/drivers/include/drivers/rtc.h @@ -15,12 +15,12 @@ #include -#define RT_DEVICE_CTRL_RTC_GET_TIME 0x10 /**< get second time */ -#define RT_DEVICE_CTRL_RTC_SET_TIME 0x11 /**< set second time */ -#define RT_DEVICE_CTRL_RTC_GET_TIME_US 0x12 /**< get microsecond time */ -#define RT_DEVICE_CTRL_RTC_SET_TIME_US 0x13 /**< set microsecond time */ -#define RT_DEVICE_CTRL_RTC_GET_ALARM 0x14 /**< get alarm */ -#define RT_DEVICE_CTRL_RTC_SET_ALARM 0x15 /**< set alarm */ +#define RT_DEVICE_CTRL_RTC_GET_TIME 0x20 /**< get second time */ +#define RT_DEVICE_CTRL_RTC_SET_TIME 0x21 /**< set second time */ +#define RT_DEVICE_CTRL_RTC_GET_TIMEVAL 0x22 /**< get timeval for gettimeofday */ +#define RT_DEVICE_CTRL_RTC_SET_TIMEVAL 0x23 /**< set timeval for gettimeofday */ +#define RT_DEVICE_CTRL_RTC_GET_ALARM 0x24 /**< get alarm */ +#define RT_DEVICE_CTRL_RTC_SET_ALARM 0x25 /**< set alarm */ struct rt_rtc_ops { diff --git a/components/libc/compilers/common/time.c b/components/libc/compilers/common/time.c index f81844f8e9..6395d789fa 100644 --- a/components/libc/compilers/common/time.c +++ b/components/libc/compilers/common/time.c @@ -18,21 +18,23 @@ * 2021-02-12 Meco Man move all of the functions located in to this file * 2021-03-15 Meco Man fixed a bug of leaking memory in asctime() * 2021-05-01 Meco Man support fixed timezone - * 2021-07-21 Meco Man implement that change/set timezone APIs */ #include "sys/time.h" -#include #include -#include + #ifdef RT_USING_DEVICE #include #endif -#define DBG_TAG "time" +#define DBG_TAG "TIME" #define DBG_LVL DBG_INFO #include +#ifndef RT_LIBC_FIXED_TIMEZONE +#define RT_LIBC_FIXED_TIMEZONE 8 /* UTC+8 */ +#endif + /* seconds per day */ #define SPD 24*60*60 @@ -101,7 +103,7 @@ static rt_err_t get_timeval(struct timeval *tv) if (rt_device_open(device, 0) == RT_EOK) { rst = rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &tv->tv_sec); - rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME_US, &tv->tv_usec); + rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIMEVAL, tv); rt_device_close(device); } } @@ -147,7 +149,7 @@ static int set_timeval(struct timeval *tv) if (rt_device_open(device, 0) == RT_EOK) { rst = rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &tv->tv_sec); - rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME_US, &tv->tv_usec); + rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIMEVAL, tv); rt_device_close(device); } } @@ -199,7 +201,7 @@ struct tm *gmtime_r(const time_t *timep, struct tm *r) r->tm_mon = i; r->tm_mday += work - __spm[i]; - r->tm_isdst = tz_is_dst(); + r->tm_isdst = 0; return r; } RTM_EXPORT(gmtime_r); @@ -215,7 +217,7 @@ struct tm* localtime_r(const time_t* t, struct tm* r) { time_t local_tz; - local_tz = *t + tz_get() * 3600; + local_tz = *t + RT_LIBC_FIXED_TIMEZONE * 3600; return gmtime_r(&local_tz, r); } RTM_EXPORT(localtime_r); @@ -232,36 +234,13 @@ time_t mktime(struct tm * const t) time_t timestamp; timestamp = timegm(t); - timestamp = timestamp - 3600 * tz_get(); + timestamp = timestamp - 3600 * RT_LIBC_FIXED_TIMEZONE; return timestamp; } RTM_EXPORT(mktime); char* asctime_r(const struct tm *t, char *buf) { - /* Checking input validity */ - if (rt_strlen(days) <= (t->tm_wday << 2) || rt_strlen(months) <= (t->tm_mon << 2)) - { - LOG_W("asctime_r: the input parameters exceeded the limit, please check it."); - *(int*) buf = *(int*) days; - *(int*) (buf + 4) = *(int*) months; - num2str(buf + 8, t->tm_mday); - if (buf[8] == '0') - buf[8] = ' '; - buf[10] = ' '; - num2str(buf + 11, t->tm_hour); - buf[13] = ':'; - num2str(buf + 14, t->tm_min); - buf[16] = ':'; - num2str(buf + 17, t->tm_sec); - buf[19] = ' '; - num2str(buf + 20, 2000 / 100); - num2str(buf + 22, 2000 % 100); - buf[24] = '\n'; - buf[25] = '\0'; - return buf; - } - /* "Wed Jun 30 21:49:08 1993\n" */ *(int*) buf = *(int*) (days + (t->tm_wday << 2)); *(int*) (buf + 4) = *(int*) (months + (t->tm_mon << 2)); @@ -446,7 +425,7 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) if(tz != RT_NULL) { tz->tz_dsttime = DST_NONE; - tz->tz_minuteswest = -(tz_get() * 60); + tz->tz_minuteswest = -(RT_LIBC_FIXED_TIMEZONE * 60); } if (tv != RT_NULL && get_timeval(tv) == RT_EOK) @@ -469,6 +448,7 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz) * Thus, the following is purely of historic interest. */ if (tv != RT_NULL + && tv->tv_sec >= 0 && tv->tv_usec >= 0 && set_timeval((struct timeval *)tv) == RT_EOK) { @@ -487,47 +467,33 @@ RTM_EXPORT(difftime); RTM_EXPORT(strftime); #ifdef RT_USING_POSIX - -#ifdef RT_USING_RTC -static volatile struct timeval _timevalue; -static int _rt_clock_time_system_init() +static struct timeval _timevalue; +static int clock_time_system_init() { - register rt_base_t level; - time_t time = 0; + time_t time; rt_tick_t tick; rt_device_t device; + time = 0; device = rt_device_find("rtc"); if (device != RT_NULL) { /* get realtime seconds */ - if(rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time) == RT_EOK) - { - level = rt_hw_interrupt_disable(); - tick = rt_tick_get(); /* get tick */ - _timevalue.tv_usec = (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK; - _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1; - rt_hw_interrupt_enable(level); - return 0; - } + rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); } - level = rt_hw_interrupt_disable(); - _timevalue.tv_usec = 0; - _timevalue.tv_sec = 0; - rt_hw_interrupt_enable(level); + /* get tick */ + tick = rt_tick_get(); - return -1; + _timevalue.tv_usec = (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK; + _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1; + + return 0; } -INIT_COMPONENT_EXPORT(_rt_clock_time_system_init); -#endif /* RT_USING_RTC */ +INIT_COMPONENT_EXPORT(clock_time_system_init); int clock_getres(clockid_t clockid, struct timespec *res) { -#ifndef RT_USING_RTC - LOG_W("Cannot find a RTC device to save time!"); - return -1; -#else int ret = 0; if (res == RT_NULL) @@ -557,16 +523,11 @@ int clock_getres(clockid_t clockid, struct timespec *res) } return ret; -#endif /* RT_USING_RTC */ } RTM_EXPORT(clock_getres); int clock_gettime(clockid_t clockid, struct timespec *tp) { -#ifndef RT_USING_RTC - LOG_W("Cannot find a RTC device to save time!"); - return -1; -#else int ret = 0; if (tp == RT_NULL) @@ -579,14 +540,11 @@ int clock_gettime(clockid_t clockid, struct timespec *tp) { case CLOCK_REALTIME: { - int tick; - register rt_base_t level; + /* get tick */ + int tick = rt_tick_get(); - level = rt_hw_interrupt_disable(); - tick = rt_tick_get(); /* get tick */ tp->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND; tp->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK) * 1000; - rt_hw_interrupt_enable(level); } break; @@ -610,17 +568,11 @@ int clock_gettime(clockid_t clockid, struct timespec *tp) } return ret; -#endif /* RT_USING_RTC */ } RTM_EXPORT(clock_gettime); int clock_settime(clockid_t clockid, const struct timespec *tp) { -#ifndef RT_USING_RTC - LOG_W("Cannot find a RTC device to save time!"); - return -1; -#else - register rt_base_t level; int second; rt_tick_t tick; rt_device_t device; @@ -628,36 +580,34 @@ int clock_settime(clockid_t clockid, const struct timespec *tp) if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL)) { rt_set_errno(EINVAL); + return -1; } /* get second */ second = tp->tv_sec; + /* get tick */ + tick = rt_tick_get(); - level = rt_hw_interrupt_disable(); - tick = rt_tick_get(); /* get tick */ /* update timevalue */ _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK; _timevalue.tv_sec = second - tick/RT_TICK_PER_SECOND - 1; - rt_hw_interrupt_enable(level); /* update for RTC device */ device = rt_device_find("rtc"); if (device != RT_NULL) { /* set realtime seconds */ - if(rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second) == RT_EOK) - { - return 0; - } + rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second); } + else + return -1; - return -1; -#endif /* RT_USING_RTC */ + return 0; } RTM_EXPORT(clock_settime); -int rt_timespec_to_tick(const struct timespec *time) +int clock_time_to_tick(const struct timespec *time) { int tick; int nsecond, second; @@ -688,32 +638,6 @@ int rt_timespec_to_tick(const struct timespec *time) return tick; } -RTM_EXPORT(rt_timespec_to_tick); +RTM_EXPORT(clock_time_to_tick); #endif /* RT_USING_POSIX */ - - -/* timezone */ -#ifndef RT_LIBC_DEFAULT_TIMEZONE -#define RT_LIBC_DEFAULT_TIMEZONE 8 -#endif - -static volatile int8_t _current_timezone = RT_LIBC_DEFAULT_TIMEZONE; - -void tz_set(int8_t tz) -{ - register rt_base_t level; - level = rt_hw_interrupt_disable(); - _current_timezone = tz; - rt_hw_interrupt_enable(level); -} - -int8_t tz_get(void) -{ - return _current_timezone; -} - -int8_t tz_is_dst(void) -{ - return 0; -} From a4619732dfb3789a1ea9107d47629fe5025fd02c Mon Sep 17 00:00:00 2001 From: armink Date: Wed, 29 Sep 2021 17:15:40 +0800 Subject: [PATCH 2/6] [DeviceDriver] Change the special device commands form 0x1X to 0x2X. It will avoid same of general device commands. --- include/rtdef.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/rtdef.h b/include/rtdef.h index 3f5f4c5ef9..a324eea122 100644 --- a/include/rtdef.h +++ b/include/rtdef.h @@ -966,13 +966,13 @@ enum rt_device_class_type /** * special device commands */ -#define RT_DEVICE_CTRL_CHAR_STREAM 0x10 /**< stream mode on char device */ -#define RT_DEVICE_CTRL_BLK_GETGEOME 0x10 /**< get geometry information */ -#define RT_DEVICE_CTRL_BLK_SYNC 0x11 /**< flush data to block device */ -#define RT_DEVICE_CTRL_BLK_ERASE 0x12 /**< erase block on block device */ -#define RT_DEVICE_CTRL_BLK_AUTOREFRESH 0x13 /**< block device : enter/exit auto refresh mode */ -#define RT_DEVICE_CTRL_NETIF_GETMAC 0x10 /**< get mac address */ -#define RT_DEVICE_CTRL_MTD_FORMAT 0x10 /**< format a MTD device */ +#define RT_DEVICE_CTRL_CHAR_STREAM 0x20 /**< stream mode on char device */ +#define RT_DEVICE_CTRL_BLK_GETGEOME 0x20 /**< get geometry information */ +#define RT_DEVICE_CTRL_BLK_SYNC 0x21 /**< flush data to block device */ +#define RT_DEVICE_CTRL_BLK_ERASE 0x22 /**< erase block on block device */ +#define RT_DEVICE_CTRL_BLK_AUTOREFRESH 0x23 /**< block device : enter/exit auto refresh mode */ +#define RT_DEVICE_CTRL_NETIF_GETMAC 0x20 /**< get mac address */ +#define RT_DEVICE_CTRL_MTD_FORMAT 0x20 /**< format a MTD device */ typedef struct rt_device *rt_device_t; From 816a99d88e5f42ceb846f587235281a1a1414750 Mon Sep 17 00:00:00 2001 From: armink Date: Wed, 29 Sep 2021 17:52:10 +0800 Subject: [PATCH 3/6] [DeviceDriver][RTC] Add RT_DEVICE_CTRL_RTC_GET_TIMEVAL and RT_DEVICE_CTRL_RTC_SET_TIMEVAL ops --- components/drivers/include/drivers/rtc.h | 4 ++-- components/drivers/rtc/rtc.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/drivers/include/drivers/rtc.h b/components/drivers/include/drivers/rtc.h index f8702a2e99..5b333161f8 100644 --- a/components/drivers/include/drivers/rtc.h +++ b/components/drivers/include/drivers/rtc.h @@ -29,8 +29,8 @@ struct rt_rtc_ops rt_err_t (*set_secs)(void *arg); rt_err_t (*get_alarm)(void *arg); rt_err_t (*set_alarm)(void *arg); - rt_err_t (*get_usecs)(void *arg); - rt_err_t (*set_usecs)(void *arg); + rt_err_t (*get_timeval)(void *arg); + rt_err_t (*set_timeval)(void *arg); }; typedef struct rt_rtc_device diff --git a/components/drivers/rtc/rtc.c b/components/drivers/rtc/rtc.c index bc75c83e7d..0658d2aaf4 100644 --- a/components/drivers/rtc/rtc.c +++ b/components/drivers/rtc/rtc.c @@ -71,11 +71,11 @@ static rt_err_t rt_rtc_control(struct rt_device *dev, int cmd, void *args) case RT_DEVICE_CTRL_RTC_SET_TIME: ret = TRY_DO_RTC_FUNC(rtc_device, set_secs, args); break; - case RT_DEVICE_CTRL_RTC_GET_TIME_US: - ret = TRY_DO_RTC_FUNC(rtc_device, get_usecs, args); + case RT_DEVICE_CTRL_RTC_GET_TIMEVAL: + ret = TRY_DO_RTC_FUNC(rtc_device, get_timeval, args); break; - case RT_DEVICE_CTRL_RTC_SET_TIME_US: - ret = TRY_DO_RTC_FUNC(rtc_device, set_usecs, args); + case RT_DEVICE_CTRL_RTC_SET_TIMEVAL: + ret = TRY_DO_RTC_FUNC(rtc_device, set_timeval, args); break; case RT_DEVICE_CTRL_RTC_GET_ALARM: ret = TRY_DO_RTC_FUNC(rtc_device, get_alarm, args); From 0beb9b3a07196eee088f04cfa069cbbde9ea1ada Mon Sep 17 00:00:00 2001 From: armink Date: Wed, 29 Sep 2021 17:58:00 +0800 Subject: [PATCH 4/6] [STM32][RTC] Add timeval ops for STM32 platform Sub-second timestamp. --- bsp/stm32/libraries/HAL_Drivers/drv_rtc.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_rtc.c b/bsp/stm32/libraries/HAL_Drivers/drv_rtc.c index 278fce140b..46d09dd16f 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_rtc.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_rtc.c @@ -38,7 +38,7 @@ RT_WEAK void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegiste return; } -static time_t get_rtc_timestamp(void) +static void get_rtc_timeval(struct timeval *tv) { RTC_TimeTypeDef RTC_TimeStruct = {0}; RTC_DateTypeDef RTC_DateStruct = {0}; @@ -54,8 +54,11 @@ static time_t get_rtc_timestamp(void) tm_new.tm_mon = RTC_DateStruct.Month - 1; tm_new.tm_year = RTC_DateStruct.Year + 100; - LOG_D("get rtc time."); - return timegm(&tm_new); + tv->tv_sec = timegm(&tm_new); + +#if defined(SOC_SERIES_STM32H7) + tv->tv_usec = (255.0 - RTC_TimeStruct.SubSeconds * 1.0) / 256.0 * 1000.0 * 1000.0; +#endif } static rt_err_t set_rtc_time_stamp(time_t time_stamp) @@ -243,7 +246,9 @@ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI1; static rt_err_t stm32_rtc_get_secs(void *args) { - *(rt_uint32_t *)args = get_rtc_timestamp(); + struct timeval tv; + get_rtc_timeval(&tv); + *(rt_uint32_t *) args = tv.tv_sec; LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args); return RT_EOK; @@ -262,6 +267,13 @@ static rt_err_t stm32_rtc_set_secs(void *args) return result; } +static rt_err_t stm32_rtc_get_timeval(void *args) +{ + get_rtc_timeval((struct timeval *) args); + + return RT_EOK; +} + static const struct rt_rtc_ops stm32_rtc_ops = { stm32_rtc_init, @@ -269,7 +281,7 @@ static const struct rt_rtc_ops stm32_rtc_ops = stm32_rtc_set_secs, RT_NULL, RT_NULL, - RT_NULL, + stm32_rtc_get_timeval, RT_NULL, }; From 75e0ec124f8b50019b1f80de6b6a4588236e7d76 Mon Sep 17 00:00:00 2001 From: armink Date: Wed, 29 Sep 2021 18:17:41 +0800 Subject: [PATCH 5/6] [components][time] Revert the old code. --- components/libc/compilers/common/time.c | 144 ++++++++++++++++++------ 1 file changed, 110 insertions(+), 34 deletions(-) diff --git a/components/libc/compilers/common/time.c b/components/libc/compilers/common/time.c index 6395d789fa..24289088fb 100644 --- a/components/libc/compilers/common/time.c +++ b/components/libc/compilers/common/time.c @@ -18,23 +18,21 @@ * 2021-02-12 Meco Man move all of the functions located in to this file * 2021-03-15 Meco Man fixed a bug of leaking memory in asctime() * 2021-05-01 Meco Man support fixed timezone + * 2021-07-21 Meco Man implement that change/set timezone APIs */ #include "sys/time.h" +#include #include - +#include #ifdef RT_USING_DEVICE #include #endif -#define DBG_TAG "TIME" +#define DBG_TAG "time" #define DBG_LVL DBG_INFO #include -#ifndef RT_LIBC_FIXED_TIMEZONE -#define RT_LIBC_FIXED_TIMEZONE 8 /* UTC+8 */ -#endif - /* seconds per day */ #define SPD 24*60*60 @@ -201,7 +199,7 @@ struct tm *gmtime_r(const time_t *timep, struct tm *r) r->tm_mon = i; r->tm_mday += work - __spm[i]; - r->tm_isdst = 0; + r->tm_isdst = tz_is_dst(); return r; } RTM_EXPORT(gmtime_r); @@ -217,7 +215,7 @@ struct tm* localtime_r(const time_t* t, struct tm* r) { time_t local_tz; - local_tz = *t + RT_LIBC_FIXED_TIMEZONE * 3600; + local_tz = *t + tz_get() * 3600; return gmtime_r(&local_tz, r); } RTM_EXPORT(localtime_r); @@ -234,13 +232,36 @@ time_t mktime(struct tm * const t) time_t timestamp; timestamp = timegm(t); - timestamp = timestamp - 3600 * RT_LIBC_FIXED_TIMEZONE; + timestamp = timestamp - 3600 * tz_get(); return timestamp; } RTM_EXPORT(mktime); char* asctime_r(const struct tm *t, char *buf) { + /* Checking input validity */ + if (rt_strlen(days) <= (t->tm_wday << 2) || rt_strlen(months) <= (t->tm_mon << 2)) + { + LOG_W("asctime_r: the input parameters exceeded the limit, please check it."); + *(int*) buf = *(int*) days; + *(int*) (buf + 4) = *(int*) months; + num2str(buf + 8, t->tm_mday); + if (buf[8] == '0') + buf[8] = ' '; + buf[10] = ' '; + num2str(buf + 11, t->tm_hour); + buf[13] = ':'; + num2str(buf + 14, t->tm_min); + buf[16] = ':'; + num2str(buf + 17, t->tm_sec); + buf[19] = ' '; + num2str(buf + 20, 2000 / 100); + num2str(buf + 22, 2000 % 100); + buf[24] = '\n'; + buf[25] = '\0'; + return buf; + } + /* "Wed Jun 30 21:49:08 1993\n" */ *(int*) buf = *(int*) (days + (t->tm_wday << 2)); *(int*) (buf + 4) = *(int*) (months + (t->tm_mon << 2)); @@ -425,7 +446,7 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) if(tz != RT_NULL) { tz->tz_dsttime = DST_NONE; - tz->tz_minuteswest = -(RT_LIBC_FIXED_TIMEZONE * 60); + tz->tz_minuteswest = -(tz_get() * 60); } if (tv != RT_NULL && get_timeval(tv) == RT_EOK) @@ -448,7 +469,6 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz) * Thus, the following is purely of historic interest. */ if (tv != RT_NULL - && tv->tv_sec >= 0 && tv->tv_usec >= 0 && set_timeval((struct timeval *)tv) == RT_EOK) { @@ -467,33 +487,47 @@ RTM_EXPORT(difftime); RTM_EXPORT(strftime); #ifdef RT_USING_POSIX -static struct timeval _timevalue; -static int clock_time_system_init() + +#ifdef RT_USING_RTC +static volatile struct timeval _timevalue; +static int _rt_clock_time_system_init() { - time_t time; + register rt_base_t level; + time_t time = 0; rt_tick_t tick; rt_device_t device; - time = 0; device = rt_device_find("rtc"); if (device != RT_NULL) { /* get realtime seconds */ - rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time); + if(rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time) == RT_EOK) + { + level = rt_hw_interrupt_disable(); + tick = rt_tick_get(); /* get tick */ + _timevalue.tv_usec = (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK; + _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1; + rt_hw_interrupt_enable(level); + return 0; + } } - /* get tick */ - tick = rt_tick_get(); + level = rt_hw_interrupt_disable(); + _timevalue.tv_usec = 0; + _timevalue.tv_sec = 0; + rt_hw_interrupt_enable(level); - _timevalue.tv_usec = (tick%RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK; - _timevalue.tv_sec = time - tick/RT_TICK_PER_SECOND - 1; - - return 0; + return -1; } -INIT_COMPONENT_EXPORT(clock_time_system_init); +INIT_COMPONENT_EXPORT(_rt_clock_time_system_init); +#endif /* RT_USING_RTC */ int clock_getres(clockid_t clockid, struct timespec *res) { +#ifndef RT_USING_RTC + LOG_W("Cannot find a RTC device to save time!"); + return -1; +#else int ret = 0; if (res == RT_NULL) @@ -523,11 +557,16 @@ int clock_getres(clockid_t clockid, struct timespec *res) } return ret; +#endif /* RT_USING_RTC */ } RTM_EXPORT(clock_getres); int clock_gettime(clockid_t clockid, struct timespec *tp) { +#ifndef RT_USING_RTC + LOG_W("Cannot find a RTC device to save time!"); + return -1; +#else int ret = 0; if (tp == RT_NULL) @@ -540,11 +579,14 @@ int clock_gettime(clockid_t clockid, struct timespec *tp) { case CLOCK_REALTIME: { - /* get tick */ - int tick = rt_tick_get(); + int tick; + register rt_base_t level; + level = rt_hw_interrupt_disable(); + tick = rt_tick_get(); /* get tick */ tp->tv_sec = _timevalue.tv_sec + tick / RT_TICK_PER_SECOND; tp->tv_nsec = (_timevalue.tv_usec + (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK) * 1000; + rt_hw_interrupt_enable(level); } break; @@ -568,11 +610,17 @@ int clock_gettime(clockid_t clockid, struct timespec *tp) } return ret; +#endif /* RT_USING_RTC */ } RTM_EXPORT(clock_gettime); int clock_settime(clockid_t clockid, const struct timespec *tp) { +#ifndef RT_USING_RTC + LOG_W("Cannot find a RTC device to save time!"); + return -1; +#else + register rt_base_t level; int second; rt_tick_t tick; rt_device_t device; @@ -580,34 +628,36 @@ int clock_settime(clockid_t clockid, const struct timespec *tp) if ((clockid != CLOCK_REALTIME) || (tp == RT_NULL)) { rt_set_errno(EINVAL); - return -1; } /* get second */ second = tp->tv_sec; - /* get tick */ - tick = rt_tick_get(); + level = rt_hw_interrupt_disable(); + tick = rt_tick_get(); /* get tick */ /* update timevalue */ _timevalue.tv_usec = MICROSECOND_PER_SECOND - (tick % RT_TICK_PER_SECOND) * MICROSECOND_PER_TICK; _timevalue.tv_sec = second - tick/RT_TICK_PER_SECOND - 1; + rt_hw_interrupt_enable(level); /* update for RTC device */ device = rt_device_find("rtc"); if (device != RT_NULL) { /* set realtime seconds */ - rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second); + if(rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &second) == RT_EOK) + { + return 0; + } } - else - return -1; - return 0; + return -1; +#endif /* RT_USING_RTC */ } RTM_EXPORT(clock_settime); -int clock_time_to_tick(const struct timespec *time) +int rt_timespec_to_tick(const struct timespec *time) { int tick; int nsecond, second; @@ -638,6 +688,32 @@ int clock_time_to_tick(const struct timespec *time) return tick; } -RTM_EXPORT(clock_time_to_tick); +RTM_EXPORT(rt_timespec_to_tick); #endif /* RT_USING_POSIX */ + + +/* timezone */ +#ifndef RT_LIBC_DEFAULT_TIMEZONE +#define RT_LIBC_DEFAULT_TIMEZONE 8 +#endif + +static volatile int8_t _current_timezone = RT_LIBC_DEFAULT_TIMEZONE; + +void tz_set(int8_t tz) +{ + register rt_base_t level; + level = rt_hw_interrupt_disable(); + _current_timezone = tz; + rt_hw_interrupt_enable(level); +} + +int8_t tz_get(void) +{ + return _current_timezone; +} + +int8_t tz_is_dst(void) +{ + return 0; +} From 3fafe6e8119806e2dc6efd46b946602213b8dc11 Mon Sep 17 00:00:00 2001 From: armink Date: Wed, 29 Sep 2021 19:47:22 +0800 Subject: [PATCH 6/6] [bsp][simulator] Add RT_DEVICE_CTRL_RTC_GET_TIMEVAL support for RTC driver --- bsp/simulator/drivers/drv_rtc.c | 44 +++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/bsp/simulator/drivers/drv_rtc.c b/bsp/simulator/drivers/drv_rtc.c index 7e19714da2..8543b4c926 100644 --- a/bsp/simulator/drivers/drv_rtc.c +++ b/bsp/simulator/drivers/drv_rtc.c @@ -45,6 +45,23 @@ static void soft_rtc_alarm_update(struct rt_rtc_wkalarm *palarm) #endif +static void get_rtc_timeval(struct timeval *tv) +{ + struct tm newtime = { 0 }; + SYSTEMTIME sys_time; + + GetSystemTime(&sys_time); + newtime.tm_year = sys_time.wYear - 1900; + newtime.tm_mon = sys_time.wMonth - 1; + newtime.tm_mday = sys_time.wDay; + newtime.tm_hour = sys_time.wHour; + newtime.tm_min = sys_time.wMinute; + newtime.tm_sec = sys_time.wSecond; + + tv->tv_sec = timegm(&newtime); + tv->tv_usec = sys_time.wMilliseconds * 1000UL; +} + static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args) { __time32_t *t; @@ -56,17 +73,14 @@ static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args) { case RT_DEVICE_CTRL_RTC_GET_TIME: { - t = (__time32_t *)args; - SYSTEMTIME sys_time; - - GetSystemTime(&sys_time); - newtime.tm_year = sys_time.wYear - 1900; - newtime.tm_mon = sys_time.wMonth - 1; - newtime.tm_mday = sys_time.wDay; - newtime.tm_hour = sys_time.wHour; - newtime.tm_min = sys_time.wMinute; - newtime.tm_sec = sys_time.wSecond; - *t = timegm(&newtime); + struct timeval tv; + get_rtc_timeval(&tv); + *(rt_uint32_t *) args = tv.tv_sec; + break; + } + case RT_DEVICE_CTRL_RTC_GET_TIMEVAL: + { + get_rtc_timeval((struct timeval *) args); break; } case RT_DEVICE_CTRL_RTC_SET_TIME: @@ -85,14 +99,6 @@ static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args) soft_rtc_alarm_update(&wkalarm); break; #endif - case RT_DEVICE_CTRL_RTC_GET_TIME_US: - { - long *tv_usec = (long *)args; - SYSTEMTIME sys_time; - GetSystemTime(&sys_time); - *tv_usec = sys_time.wMilliseconds * 1000UL; - break; - } default: return -RT_ERROR; }