address thread safety in lower half driver with a driver mutex acquired/released in public api

This commit is contained in:
ziggurat29
2016-05-05 11:22:09 -05:00
parent 273680a6e9
commit 67b1f89159
+46 -5
View File
@@ -34,8 +34,6 @@
* *
****************************************************************************/ ****************************************************************************/
/* REVISIT: This driver is *not* thread-safe! */
/**************************************************************************** /****************************************************************************
* Included Files * Included Files
****************************************************************************/ ****************************************************************************/
@@ -90,6 +88,8 @@ struct stm32l4_lowerhalf_s
* this file. * this file.
*/ */
sem_t devsem; /* Threads can only exclusively access the RTC */
#ifdef CONFIG_RTC_ALARM #ifdef CONFIG_RTC_ALARM
/* Alarm callback information */ /* Alarm callback information */
@@ -218,12 +218,25 @@ static void stm32l4_alarm_callback(FAR void *arg, unsigned int alarmid)
static int stm32l4_rdtime(FAR struct rtc_lowerhalf_s *lower, static int stm32l4_rdtime(FAR struct rtc_lowerhalf_s *lower,
FAR struct rtc_time *rtctime) FAR struct rtc_time *rtctime)
{ {
FAR struct stm32l4_lowerhalf_s *priv;
int ret;
priv = (FAR struct stm32l4_lowerhalf_s *)lower;
if (sem_wait(&priv->devsem) != OK)
{
return -errno;
}
/* This operation depends on the fact that struct rtc_time is cast /* This operation depends on the fact that struct rtc_time is cast
* compatible with struct tm. * compatible with struct tm.
*/ */
return up_rtc_getdatetime((FAR struct tm *)rtctime); ret = up_rtc_getdatetime((FAR struct tm *)rtctime);
sem_post(&priv->devsem);
return ret;
} }
/**************************************************************************** /****************************************************************************
@@ -245,11 +258,25 @@ static int stm32l4_rdtime(FAR struct rtc_lowerhalf_s *lower,
static int stm32l4_settime(FAR struct rtc_lowerhalf_s *lower, static int stm32l4_settime(FAR struct rtc_lowerhalf_s *lower,
FAR const struct rtc_time *rtctime) FAR const struct rtc_time *rtctime)
{ {
FAR struct stm32l4_lowerhalf_s *priv;
int ret;
priv = (FAR struct stm32l4_lowerhalf_s *)lower;
if (sem_wait(&priv->devsem) != OK)
{
return -errno;
}
/* This operation depends on the fact that struct rtc_time is cast /* This operation depends on the fact that struct rtc_time is cast
* compatible with struct tm. * compatible with struct tm.
*/ */
return stm32l4_rtc_setdatetime((FAR const struct tm *)rtctime); ret = stm32l4_rtc_setdatetime((FAR const struct tm *)rtctime);
sem_post(&priv->devsem);
return ret;
} }
/**************************************************************************** /****************************************************************************
@@ -284,6 +311,11 @@ static int stm32l4_setalarm(FAR struct rtc_lowerhalf_s *lower,
DEBUGASSERT(alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB); DEBUGASSERT(alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB);
priv = (FAR struct stm32l4_lowerhalf_s *)lower; priv = (FAR struct stm32l4_lowerhalf_s *)lower;
if (sem_wait(&priv->devsem) != OK)
{
return -errno;
}
if (alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB) if (alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB)
{ {
/* Remember the callback information */ /* Remember the callback information */
@@ -310,7 +342,7 @@ static int stm32l4_setalarm(FAR struct rtc_lowerhalf_s *lower,
} }
} }
sem_post(&priv->devsem);
return ret; return ret;
} }
@@ -417,6 +449,11 @@ static int stm32l4_cancelalarm(FAR struct rtc_lowerhalf_s *lower, int alarmid)
DEBUGASSERT(alarmid == RTC_ALARMA || alarmid == RTC_ALARMB); DEBUGASSERT(alarmid == RTC_ALARMA || alarmid == RTC_ALARMB);
priv = (FAR struct stm32l4_lowerhalf_s *)lower; priv = (FAR struct stm32l4_lowerhalf_s *)lower;
if (sem_wait(&priv->devsem) != OK)
{
return -errno;
}
/* ID0-> Alarm A; ID1 -> Alarm B */ /* ID0-> Alarm A; ID1 -> Alarm B */
if (alarmid == RTC_ALARMA || alarmid == RTC_ALARMB) if (alarmid == RTC_ALARMA || alarmid == RTC_ALARMB)
@@ -432,6 +469,8 @@ static int stm32l4_cancelalarm(FAR struct rtc_lowerhalf_s *lower, int alarmid)
ret = stm32l4_rtc_cancelalarm((enum alm_id_e)alarmid); ret = stm32l4_rtc_cancelalarm((enum alm_id_e)alarmid);
} }
sem_post(&priv->devsem);
return ret; return ret;
} }
#endif #endif
@@ -464,6 +503,8 @@ static int stm32l4_cancelalarm(FAR struct rtc_lowerhalf_s *lower, int alarmid)
FAR struct rtc_lowerhalf_s *stm32l4_rtc_lowerhalf(void) FAR struct rtc_lowerhalf_s *stm32l4_rtc_lowerhalf(void)
{ {
sem_init(&g_rtc_lowerhalf.devsem, 0, 1);
return (FAR struct rtc_lowerhalf_s *)&g_rtc_lowerhalf; return (FAR struct rtc_lowerhalf_s *)&g_rtc_lowerhalf;
} }