mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 11:56:10 +08:00
RTC: Handle RTC failures. If mktime is called with garbage, it may crash
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user