drivers/timers/arch_alarm.c and arch_timer.c: Implement up_critmon_gettime and up_critmon_convert and remove the critical section from current_usec to infinite recursion.
This commit is contained in:
parent
e57f7cf6ae
commit
15db8a21ae
@ -392,6 +392,47 @@ int up_alarm_start(FAR const struct timespec *ts)
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************************************************
|
||||
* Name: up_critmon_*
|
||||
*
|
||||
* Description:
|
||||
* The first interface simply provides the current time value in unknown
|
||||
* units. NOTE: This function may be called early before the timer has
|
||||
* been initialized. In that event, the function should just return a
|
||||
* start time of zero.
|
||||
*
|
||||
* Nothing is assumed about the units of this time value. The following
|
||||
* are assumed, however: (1) The time is an unsigned integer value, (2)
|
||||
* the time is monotonically increasing, and (3) the elapsed time (also
|
||||
* in unknown units) can be obtained by subtracting a start time from
|
||||
* the current time.
|
||||
*
|
||||
* The second interface simple converts an elapsed time into well known
|
||||
* units.
|
||||
********************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_CRITMONITOR
|
||||
uint32_t up_critmon_gettime(void)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
if (g_oneshot_lower != NULL)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
ONESHOT_CURRENT(g_oneshot_lower, &ts);
|
||||
ret = timespec_to_usec(&ts);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void up_critmon_convert(uint32_t elapsed, FAR struct timespec *ts)
|
||||
{
|
||||
timespec_from_usec(ts, elapsed);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_mdelay
|
||||
*
|
||||
|
@ -91,12 +91,8 @@ static struct arch_timer_s g_timer;
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS
|
||||
static inline uint64_t timespec_to_usec(const FAR struct timespec *ts)
|
||||
{
|
||||
return (uint64_t)ts->tv_sec * USEC_PER_SEC + ts->tv_nsec / NSEC_PER_USEC;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SCHED_TICKLESS) || defined(CONFIG_SCHED_CRITMONITOR) \
|
||||
|| defined(CONFIG_SCHED_IRQMONITOR_GETTIME)
|
||||
static inline void timespec_from_usec(FAR struct timespec *ts,
|
||||
uint64_t microseconds)
|
||||
{
|
||||
@ -104,6 +100,13 @@ static inline void timespec_from_usec(FAR struct timespec *ts,
|
||||
microseconds -= (uint64_t)ts->tv_sec * USEC_PER_SEC;
|
||||
ts->tv_nsec = microseconds * NSEC_PER_USEC;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS
|
||||
static inline uint64_t timespec_to_usec(const FAR struct timespec *ts)
|
||||
{
|
||||
return (uint64_t)ts->tv_sec * USEC_PER_SEC + ts->tv_nsec / NSEC_PER_USEC;
|
||||
}
|
||||
|
||||
static inline bool timeout_diff(uint32_t new, uint32_t old)
|
||||
{
|
||||
@ -143,12 +146,13 @@ static uint64_t current_usec(void)
|
||||
{
|
||||
struct timer_status_s status;
|
||||
uint64_t timebase;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = enter_critical_section();
|
||||
TIMER_GETSTATUS(g_timer.lower, &status);
|
||||
do
|
||||
{
|
||||
timebase = g_timer.timebase;
|
||||
leave_critical_section(flags);
|
||||
TIMER_GETSTATUS(g_timer.lower, &status);
|
||||
}
|
||||
while (timebase != g_timer.timebase);
|
||||
|
||||
return timebase + (status.timeout - status.timeleft);
|
||||
}
|
||||
@ -425,6 +429,44 @@ int up_timer_start(FAR const struct timespec *ts)
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************************************************
|
||||
* Name: up_critmon_*
|
||||
*
|
||||
* Description:
|
||||
* The first interface simply provides the current time value in unknown
|
||||
* units. NOTE: This function may be called early before the timer has
|
||||
* been initialized. In that event, the function should just return a
|
||||
* start time of zero.
|
||||
*
|
||||
* Nothing is assumed about the units of this time value. The following
|
||||
* are assumed, however: (1) The time is an unsigned integer value, (2)
|
||||
* the time is monotonically increasing, and (3) the elapsed time (also
|
||||
* in unknown units) can be obtained by subtracting a start time from
|
||||
* the current time.
|
||||
*
|
||||
* The second interface simple converts an elapsed time into well known
|
||||
* units.
|
||||
********************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_CRITMONITOR
|
||||
uint32_t up_critmon_gettime(void)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
if (g_timer.lower != NULL)
|
||||
{
|
||||
ret = current_usec();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void up_critmon_convert(uint32_t elapsed, FAR struct timespec *ts)
|
||||
{
|
||||
timespec_from_usec(ts, elapsed);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_mdelay
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user