RTC: Handle RTC failures. If mktime is called with garbage, it may crash

This commit is contained in:
Gregory Nutt
2015-12-21 14:39:40 -06:00
parent a696b807fb
commit a2e1ece873
2 changed files with 19 additions and 12 deletions
+2 -2
View File
@@ -241,8 +241,8 @@ int pcf85263_rtc_initialize(FAR struct i2c_dev_s *i2c)
{ {
/* Remember the i2c device and claim that the RTC is enabled */ /* Remember the i2c device and claim that the RTC is enabled */
g_pcf85263.i2c = i2c; g_pcf85263.i2c = i2c;
g_rtc_enabled = true; g_rtc_enabled = true;
return OK; return OK;
} }
+17 -10
View File
@@ -110,47 +110,53 @@ struct timespec g_basetime;
#if defined(CONFIG_RTC_DATETIME) #if defined(CONFIG_RTC_DATETIME)
/* Initialize the system time using a broken out date/time structure */ /* Initialize the system time using a broken out date/time structure */
static inline void clock_basetime(FAR struct timespec *tp) static inline int clock_basetime(FAR struct timespec *tp)
{ {
struct tm rtctime; struct tm rtctime;
int ret;
/* Get the broken-out time from the date/time RTC. */ /* Get the broken-out time from the date/time RTC. */
(void)up_rtc_getdatetime(&rtctime); ret = up_rtc_getdatetime(&rtctime);
if (ret >= 0)
{
/* And use the broken-out time to initialize the system time */
/* And use the broken-out time to initialize the system time */ tp->tv_sec = mktime(&rtctime);
tp->tv_nsec = 0;
}
tp->tv_sec = mktime(&rtctime); return ret;
tp->tv_nsec = 0;
} }
#elif defined(CONFIG_RTC_HIRES) #elif defined(CONFIG_RTC_HIRES)
/* Initialize the system time using a high-resolution structure */ /* Initialize the system time using a high-resolution structure */
static inline void clock_basetime(FAR struct timespec *tp) static inline int clock_basetime(FAR struct timespec *tp)
{ {
/* Get the complete time from the hi-res RTC. */ /* Get the complete time from the hi-res RTC. */
(void)up_rtc_gettime(tp); return up_rtc_gettime(tp);
} }
#else #else
/* Initialize the system time using seconds only */ /* Initialize the system time using seconds only */
static inline void clock_basetime(FAR struct timespec *tp) static inline int clock_basetime(FAR struct timespec *tp)
{ {
/* Get the seconds (only) from the lo-resolution RTC */ /* Get the seconds (only) from the lo-resolution RTC */
tp->tv_sec = up_rtc_time(); tp->tv_sec = up_rtc_time();
tp->tv_nsec = 0; tp->tv_nsec = 0;
return OK;
} }
#endif /* CONFIG_RTC_HIRES */ #endif /* CONFIG_RTC_HIRES */
#else /* CONFIG_RTC */ #else /* CONFIG_RTC */
static inline void clock_basetime(FAR struct timespec *tp) static inline int clock_basetime(FAR struct timespec *tp)
{ {
time_t jdn = 0; time_t jdn = 0;
@@ -165,6 +171,7 @@ static inline void clock_basetime(FAR struct timespec *tp)
tp->tv_sec = jdn * SEC_PER_DAY; tp->tv_sec = jdn * SEC_PER_DAY;
tp->tv_nsec = 0; tp->tv_nsec = 0;
return OK;
} }
#endif /* CONFIG_RTC */ #endif /* CONFIG_RTC */
@@ -181,7 +188,7 @@ static void clock_inittime(void)
{ {
/* (Re-)initialize the time value to match the RTC */ /* (Re-)initialize the time value to match the RTC */
clock_basetime(&g_basetime); (void)clock_basetime(&g_basetime);
#ifndef CONFIG_SCHED_TICKLESS #ifndef CONFIG_SCHED_TICKLESS
g_system_timer = 0; g_system_timer = 0;
#endif #endif