From 0ece4d02b00237e85db4f0403f714026abc7955c Mon Sep 17 00:00:00 2001 From: ccli8 Date: Mon, 4 Sep 2017 11:08:09 +0800 Subject: [PATCH] Replace mktime/localtime with interrupt-safe version in rtc The use of mktime was causing a fault when called in interrupt handler because on GCC it lock the mutex protecting the environment, To overcome this issue, this patch add dedicated routine to convert a time_t into a tm and vice versa. In the process mktime has been optimized and is now an order of magnitude faster than the routines present in the C library. --- targets/TARGET_NUVOTON/TARGET_M480/rtc_api.c | 22 ++++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M480/rtc_api.c b/targets/TARGET_NUVOTON/TARGET_M480/rtc_api.c index 5047ccad03..186fffd684 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/rtc_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/rtc_api.c @@ -22,6 +22,7 @@ #include "mbed_error.h" #include "nu_modutil.h" #include "nu_miscutil.h" +#include "mbed_mktime.h" #define YEAR0 1900 //#define EPOCH_YR 1970 @@ -92,7 +93,7 @@ time_t rtc_read(void) timeinfo.tm_sec = rtc_datetime.u32Second; // Convert to timestamp - time_t t = mktime(&timeinfo); + time_t t = _rtc_mktime(&timeinfo); return t; } @@ -104,18 +105,21 @@ void rtc_write(time_t t) } // Convert timestamp to struct tm - struct tm *timeinfo = localtime(&t); + struct tm timeinfo; + if (_rtc_localtime(t, &timeinfo) == false) { + return; + } S_RTC_TIME_DATA_T rtc_datetime; // Convert S_RTC_TIME_DATA_T to struct tm - rtc_datetime.u32Year = timeinfo->tm_year + YEAR0; - rtc_datetime.u32Month = timeinfo->tm_mon + 1; - rtc_datetime.u32Day = timeinfo->tm_mday; - rtc_datetime.u32DayOfWeek = timeinfo->tm_wday; - rtc_datetime.u32Hour = timeinfo->tm_hour; - rtc_datetime.u32Minute = timeinfo->tm_min; - rtc_datetime.u32Second = timeinfo->tm_sec; + rtc_datetime.u32Year = timeinfo.tm_year + YEAR0; + rtc_datetime.u32Month = timeinfo.tm_mon + 1; + rtc_datetime.u32Day = timeinfo.tm_mday; + rtc_datetime.u32DayOfWeek = timeinfo.tm_wday; + rtc_datetime.u32Hour = timeinfo.tm_hour; + rtc_datetime.u32Minute = timeinfo.tm_min; + rtc_datetime.u32Second = timeinfo.tm_sec; rtc_datetime.u32TimeScale = RTC_CLOCK_24; // NOTE: Timing issue with write to RTC registers. This delay is empirical, not rational.