diff --git a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_rtc.c b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_rtc.c index 41097fe1fb0..7d4e37b5c8c 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drivers/drv_rtc.c +++ b/bsp/stm32/libraries/HAL_Drivers/drivers/drv_rtc.c @@ -9,6 +9,7 @@ * 2020-10-14 Dozingfiretruck Porting for stm32wbxx * 2021-02-05 Meco Man fix the problem of mixing local time and UTC time * 2021-07-05 iysheng implement RTC framework V2.0 + * 2025-06-05 RCSN add local time conversion for get timeval and set stamp */ #include "board.h" @@ -71,8 +72,11 @@ static rt_err_t stm32_rtc_get_timeval(struct timeval *tv) tm_new.tm_mon = RTC_DateStruct.Month - 1; tm_new.tm_year = RTC_DateStruct.Year + 100; +#ifdef RT_ALARM_USING_LOCAL_TIME + tv->tv_sec = mktime(&tm_new); +#else tv->tv_sec = timegm(&tm_new); - +#endif #if defined(SOC_SERIES_STM32H7) tv->tv_usec = (255.0 - RTC_TimeStruct.SubSeconds * 1.0) / 256.0 * 1000.0 * 1000.0; #endif @@ -85,8 +89,11 @@ static rt_err_t set_rtc_time_stamp(time_t time_stamp) RTC_TimeTypeDef RTC_TimeStruct = {0}; RTC_DateTypeDef RTC_DateStruct = {0}; struct tm tm = {0}; - +#ifdef RT_ALARM_USING_LOCAL_TIME + localtime_r(&time_stamp,&tm); +#else gmtime_r(&time_stamp, &tm); +#endif if (tm.tm_year < 100) { return -RT_ERROR; @@ -318,6 +325,11 @@ static rt_err_t stm32_rtc_set_alarm(struct rt_rtc_wkalarm *alarm) rtc_device.wkalarm.tm_hour = alarm->tm_hour; rtc_device.wkalarm.tm_min = alarm->tm_min; rtc_device.wkalarm.tm_sec = alarm->tm_sec; + /* must include the year, month, and day */ + /* as the alarm in RT_ALARM_ONESHOT mode compares the current timestamp with the alarm timestamp */ + rtc_device.wkalarm.tm_year = alarm->tm_year; + rtc_device.wkalarm.tm_mon = alarm->tm_mon; + rtc_device.wkalarm.tm_mday = alarm->tm_mday; rtc_alarm_time_set(&rtc_device); } else diff --git a/components/drivers/rtc/Kconfig b/components/drivers/rtc/Kconfig index a8b33662a51..9dcf7cf529b 100644 --- a/components/drivers/rtc/Kconfig +++ b/components/drivers/rtc/Kconfig @@ -19,6 +19,11 @@ config RT_USING_RTC config RT_ALARM_PRIORITY int "priority for alarm thread" default 10 + + config RT_ALARM_USING_LOCAL_TIME + bool "Using local time for the alarm calculation" + default n + depends on RT_USING_ALARM endif config RT_USING_SOFT_RTC diff --git a/components/drivers/rtc/dev_alarm.c b/components/drivers/rtc/dev_alarm.c index aabc415838a..48a03ea9a36 100644 --- a/components/drivers/rtc/dev_alarm.c +++ b/components/drivers/rtc/dev_alarm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2025 RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -10,6 +10,7 @@ * 2020-10-15 zhangsz add alarm flags hour minute second. * 2020-11-09 zhangsz fix alarm set when modify rtc time. * 2024-09-29 milo make internal thread's attributes configurable. + * 2025-6-4 RCSN support the alarm using local time for calculation */ #include @@ -108,8 +109,13 @@ static void alarm_wakeup(struct rt_alarm *alarm, struct tm *now) { case RT_ALARM_ONESHOT: { +#ifdef RT_ALARM_USING_LOCAL_TIME + sec_alarm = mktime(&alarm->wktime); + sec_now = mktime(now); +#else sec_alarm = timegm(&alarm->wktime); sec_now = timegm(now); +#endif if (((sec_now - sec_alarm) <= RT_ALARM_DELAY) && (sec_now >= sec_alarm)) { /* stop alarm */ @@ -239,7 +245,11 @@ static void alarm_update(rt_uint32_t event) { /* get time of now */ get_timestamp(×tamp); +#ifdef RT_ALARM_USING_LOCAL_TIME + localtime_r(×tamp, &now); +#else gmtime_r(×tamp, &now); +#endif for (next = _container.head.next; next != &_container.head; next = next->next) { @@ -250,7 +260,11 @@ static void alarm_update(rt_uint32_t event) /* get time of now */ get_timestamp(×tamp); +#ifdef RT_ALARM_USING_LOCAL_TIME + localtime_r(×tamp, &now); +#else gmtime_r(×tamp, &now); +#endif sec_now = alarm_mkdaysec(&now); for (next = _container.head.next; next != &_container.head; next = next->next) @@ -359,7 +373,11 @@ static rt_err_t alarm_setup(rt_alarm_t alarm, struct tm *wktime) *setup = *wktime; /* get time of now */ get_timestamp(×tamp); +#ifdef RT_ALARM_USING_LOCAL_TIME + localtime_r(×tamp, &now); +#else gmtime_r(×tamp, &now); +#endif /* if these are a "don't care" value,we set them to now*/ if ((setup->tm_sec > 59) || (setup->tm_sec < 0)) @@ -574,7 +592,11 @@ rt_err_t rt_alarm_start(rt_alarm_t alarm) /* get time of now */ get_timestamp(×tamp); +#ifdef RT_ALARM_USING_LOCAL_TIME + localtime_r(×tamp, &now); +#else gmtime_r(×tamp, &now); +#endif alarm->flag |= RT_ALARM_STATE_START; @@ -768,18 +790,26 @@ void rt_alarm_dump(void) { rt_list_t *next; rt_alarm_t alarm; - - rt_kprintf("| hh:mm:ss | week | flag | en |\n"); - rt_kprintf("+----------+------+------+----+\n"); + int32_t tz_offset_sec = 0; + uint32_t abs_tz_offset_sec = 0U; +#ifdef RT_ALARM_USING_LOCAL_TIME +#if defined(RT_LIBC_USING_LIGHT_TZ_DST) + tz_offset_sec = rt_tz_get(); +#endif /* RT_LIBC_USING_LIGHT_TZ_DST */ + abs_tz_offset_sec = tz_offset_sec > 0 ? tz_offset_sec : -tz_offset_sec; +#endif + rt_kprintf("| hh:mm:ss | week | flag | en | timezone |\n"); + rt_kprintf("+----------+------+------+----+--------------+\n"); for (next = _container.head.next; next != &_container.head; next = next->next) { alarm = rt_list_entry(next, struct rt_alarm, list); rt_uint8_t flag_index = get_alarm_flag_index(alarm->flag); - rt_kprintf("| %02d:%02d:%02d | %2d | %2s | %2d |\n", + rt_kprintf("| %02d:%02d:%02d | %2d | %2s | %2d | UTC%c%02d:%02d:%02d |\n", alarm->wktime.tm_hour, alarm->wktime.tm_min, alarm->wktime.tm_sec, - alarm->wktime.tm_wday, _alarm_flag_tbl[flag_index].name, alarm->flag & RT_ALARM_STATE_START); + alarm->wktime.tm_wday, _alarm_flag_tbl[flag_index].name, alarm->flag & RT_ALARM_STATE_START, + tz_offset_sec > 0 ? '+' : '-', abs_tz_offset_sec / 3600U, abs_tz_offset_sec % 3600U / 60U, abs_tz_offset_sec % 3600U % 60U); } - rt_kprintf("+----------+------+------+----+\n"); + rt_kprintf("+----------+------+------+----+--------------+\n"); } MSH_CMD_EXPORT_ALIAS(rt_alarm_dump, list_alarm, list alarm info);