arch_alarm: adjust oneshot/arch_alarm to support tick
This commit is contained in:
parent
750007ded9
commit
fc9b5e1980
@ -96,6 +96,7 @@ config ALARM_ARCH
|
||||
select ARCH_HAVE_TIMEKEEPING
|
||||
select SCHED_TICKLESS_ALARM if SCHED_TICKLESS
|
||||
select SCHED_TICKLESS_LIMIT_MAX_SLEEP if SCHED_TICKLESS
|
||||
select SCHED_TICKLESS_TICK_ARGUMENT if SCHED_TICKLESS
|
||||
---help---
|
||||
Implement alarm arch API on top of oneshot driver interface.
|
||||
|
||||
|
@ -123,27 +123,27 @@ static void udelay_coarse(useconds_t microseconds)
|
||||
static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR void *arg)
|
||||
{
|
||||
struct timespec now;
|
||||
clock_t now = 0;
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS
|
||||
ONESHOT_CURRENT(g_oneshot_lower, &now);
|
||||
nxsched_alarm_expiration(&now);
|
||||
ONESHOT_TICK_CURRENT(g_oneshot_lower, &now);
|
||||
nxsched_alarm_tick_expiration(now);
|
||||
#else
|
||||
struct timespec delta;
|
||||
clock_t delta;
|
||||
|
||||
do
|
||||
{
|
||||
static uint64_t tick = 1;
|
||||
struct timespec next;
|
||||
static clock_t tick = 1;
|
||||
clock_t next;
|
||||
|
||||
nxsched_process_timer();
|
||||
timespec_from_usec(&next, ++tick * USEC_PER_TICK);
|
||||
ONESHOT_CURRENT(g_oneshot_lower, &now);
|
||||
clock_timespec_subtract(&next, &now, &delta);
|
||||
next = ++tick;
|
||||
ONESHOT_TICK_CURRENT(g_oneshot_lower, &now);
|
||||
delta = next - now;
|
||||
}
|
||||
while (delta.tv_sec == 0 && delta.tv_nsec == 0);
|
||||
while ((sclock_t)delta <= 0);
|
||||
|
||||
ONESHOT_START(g_oneshot_lower, oneshot_callback, NULL, &delta);
|
||||
ONESHOT_TICK_START(g_oneshot_lower, oneshot_callback, NULL, delta);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -154,19 +154,16 @@ static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower,
|
||||
void up_alarm_set_lowerhalf(FAR struct oneshot_lowerhalf_s *lower)
|
||||
{
|
||||
#ifdef CONFIG_SCHED_TICKLESS
|
||||
struct timespec maxts;
|
||||
uint64_t maxticks;
|
||||
clock_t ticks;
|
||||
#endif
|
||||
|
||||
g_oneshot_lower = lower;
|
||||
ONESHOT_MAX_DELAY(g_oneshot_lower, &maxts);
|
||||
maxticks = timespec_to_usec(&maxts) / USEC_PER_TICK;
|
||||
g_oneshot_maxticks = maxticks < UINT32_MAX ? maxticks : UINT32_MAX;
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS
|
||||
ONESHOT_TICK_MAX_DELAY(g_oneshot_lower, &ticks);
|
||||
g_oneshot_maxticks = ticks < UINT32_MAX ? ticks : UINT32_MAX;
|
||||
#else
|
||||
struct timespec ts;
|
||||
|
||||
g_oneshot_lower = lower;
|
||||
timespec_from_usec(&ts, USEC_PER_TICK);
|
||||
ONESHOT_START(g_oneshot_lower, oneshot_callback, NULL, &ts);
|
||||
ONESHOT_TICK_START(g_oneshot_lower, oneshot_callback, NULL, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -210,11 +207,9 @@ void weak_function up_timer_getmask(FAR clock_t *mask)
|
||||
|
||||
if (g_oneshot_lower != NULL)
|
||||
{
|
||||
struct timespec maxts;
|
||||
clock_t maxticks;
|
||||
|
||||
ONESHOT_MAX_DELAY(g_oneshot_lower, &maxts);
|
||||
maxticks = timespec_to_usec(&maxts) / USEC_PER_TICK;
|
||||
ONESHOT_TICK_MAX_DELAY(g_oneshot_lower, &maxticks);
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
@ -230,34 +225,14 @@ void weak_function up_timer_getmask(FAR clock_t *mask)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SCHED_TICKLESS) && !defined(CONFIG_SCHED_TICKLESS_TICK_ARGUMENT)
|
||||
int weak_function up_timer_gettime(FAR struct timespec *ts)
|
||||
{
|
||||
int ret = -EAGAIN;
|
||||
|
||||
if (g_oneshot_lower != NULL)
|
||||
{
|
||||
ret = ONESHOT_CURRENT(g_oneshot_lower, ts);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SCHED_TICKLESS_TICK_ARGUMENT) || defined(CONFIG_CLOCK_TIMEKEEPING)
|
||||
#if defined(CONFIG_SCHED_TICKLESS) || defined(CONFIG_CLOCK_TIMEKEEPING)
|
||||
int weak_function up_timer_gettick(FAR clock_t *ticks)
|
||||
{
|
||||
int ret = -EAGAIN;
|
||||
|
||||
if (g_oneshot_lower != NULL)
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
ret = ONESHOT_CURRENT(g_oneshot_lower, &now);
|
||||
if (ret == 0)
|
||||
{
|
||||
*ticks = timespec_to_usec(&now) / USEC_PER_TICK;
|
||||
}
|
||||
ret = ONESHOT_TICK_CURRENT(g_oneshot_lower, ticks);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -299,14 +274,14 @@ int weak_function up_timer_gettick(FAR clock_t *ticks)
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS
|
||||
int weak_function up_alarm_cancel(FAR struct timespec *ts)
|
||||
int weak_function up_alarm_tick_cancel(FAR clock_t *ticks)
|
||||
{
|
||||
int ret = -EAGAIN;
|
||||
|
||||
if (g_oneshot_lower != NULL)
|
||||
{
|
||||
ret = ONESHOT_CANCEL(g_oneshot_lower, ts);
|
||||
ONESHOT_CURRENT(g_oneshot_lower, ts);
|
||||
ret = ONESHOT_TICK_CANCEL(g_oneshot_lower, ticks);
|
||||
ONESHOT_TICK_CURRENT(g_oneshot_lower, ticks);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -338,18 +313,24 @@ int weak_function up_alarm_cancel(FAR struct timespec *ts)
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS
|
||||
int weak_function up_alarm_start(FAR const struct timespec *ts)
|
||||
int weak_function up_alarm_tick_start(clock_t ticks)
|
||||
{
|
||||
int ret = -EAGAIN;
|
||||
|
||||
if (g_oneshot_lower != NULL)
|
||||
{
|
||||
struct timespec now;
|
||||
struct timespec delta;
|
||||
clock_t now = 0;
|
||||
clock_t delta;
|
||||
|
||||
ONESHOT_CURRENT(g_oneshot_lower, &now);
|
||||
clock_timespec_subtract(ts, &now, &delta);
|
||||
ret = ONESHOT_START(g_oneshot_lower, oneshot_callback, NULL, &delta);
|
||||
ONESHOT_TICK_CURRENT(g_oneshot_lower, &now);
|
||||
delta = ticks - now;
|
||||
if ((sclock_t)delta < 0)
|
||||
{
|
||||
delta = 0;
|
||||
}
|
||||
|
||||
ret = ONESHOT_TICK_START(g_oneshot_lower, oneshot_callback,
|
||||
NULL, delta);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -91,7 +91,10 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define ONESHOT_MAX_DELAY(l,t) ((l)->ops->max_delay(l,t))
|
||||
#define ONESHOT_MAX_DELAY(l,t) \
|
||||
((l)->ops->max_delay ? (l)->ops->max_delay(l,t) : oneshot_max_delay(l,t))
|
||||
#define ONESHOT_TICK_MAX_DELAY(l,t) \
|
||||
((l)->ops->tick_max_delay ? (l)->ops->tick_max_delay(l,t) : oneshot_tick_max_delay(l,t))
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ONESHOT_START
|
||||
@ -113,7 +116,10 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define ONESHOT_START(l,h,a,t) ((l)->ops->start(l,h,a,t))
|
||||
#define ONESHOT_START(l,h,a,t) \
|
||||
((l)->ops->start ? (l)->ops->start(l,h,a,t) : oneshot_start(l,h,a,t))
|
||||
#define ONESHOT_TICK_START(l,h,a,t) \
|
||||
((l)->ops->tick_start ? (l)->ops->tick_start(l,h,a,t) : oneshot_tick_start(l,h,a,t))
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ONESHOT_CANCEL
|
||||
@ -139,7 +145,10 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define ONESHOT_CANCEL(l,t) ((l)->ops->cancel(l,t))
|
||||
#define ONESHOT_CANCEL(l,t) \
|
||||
((l)->ops->cancel ? (l)->ops->cancel(l,t) : oneshot_cancel(l,t))
|
||||
#define ONESHOT_TICK_CANCEL(l,t) \
|
||||
((l)->ops->tick_cancel ? (l)->ops->tick_cancel(l,t) : oneshot_tick_cancel(l,t))
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ONESHOT_CURRENT
|
||||
@ -160,7 +169,10 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define ONESHOT_CURRENT(l,t) ((l)->ops->current ? (l)->ops->current(l,t) : -ENOSYS)
|
||||
#define ONESHOT_CURRENT(l,t) \
|
||||
((l)->ops->current ? (l)->ops->current(l,t) : oneshot_current(l,t))
|
||||
#define ONESHOT_TICK_CURRENT(l,t) \
|
||||
((l)->ops->tick_current ? (l)->ops->tick_current(l,t) : oneshot_tick_current(l,t))
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
@ -188,10 +200,19 @@ struct oneshot_operations_s
|
||||
CODE int (*start)(FAR struct oneshot_lowerhalf_s *lower,
|
||||
oneshot_callback_t callback, FAR void *arg,
|
||||
FAR const struct timespec *ts);
|
||||
CODE int (*cancel)(struct oneshot_lowerhalf_s *lower,
|
||||
CODE int (*cancel)(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR struct timespec *ts);
|
||||
CODE int (*current)(struct oneshot_lowerhalf_s *lower,
|
||||
CODE int (*current)(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR struct timespec *ts);
|
||||
CODE int (*tick_max_delay)(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR clock_t *ticks);
|
||||
CODE int (*tick_start)(FAR struct oneshot_lowerhalf_s *lower,
|
||||
oneshot_callback_t callback, FAR void *arg,
|
||||
clock_t ticks);
|
||||
CODE int (*tick_cancel)(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR clock_t *ticks);
|
||||
CODE int (*tick_current)(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR clock_t *ticks);
|
||||
};
|
||||
|
||||
/* This structure describes the state of the oneshot timer lower-half
|
||||
@ -237,6 +258,120 @@ extern "C"
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static inline
|
||||
int oneshot_max_delay(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR struct timespec *ts)
|
||||
{
|
||||
clock_t tick;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(lower->ops->tick_max_delay);
|
||||
|
||||
ret = lower->ops->tick_max_delay(lower, &tick);
|
||||
timespec_from_tick(ts, tick);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline
|
||||
int oneshot_start(FAR struct oneshot_lowerhalf_s *lower,
|
||||
oneshot_callback_t callback, FAR void *arg,
|
||||
FAR const struct timespec *ts)
|
||||
{
|
||||
clock_t tick;
|
||||
|
||||
DEBUGASSERT(lower->ops->tick_start);
|
||||
|
||||
tick = timespec_to_tick(ts);
|
||||
return lower->ops->tick_start(lower, callback, arg, tick);
|
||||
}
|
||||
|
||||
static inline
|
||||
int oneshot_cancel(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR struct timespec *ts)
|
||||
{
|
||||
clock_t tick;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(lower->ops->tick_cancel);
|
||||
|
||||
ret = lower->ops->tick_cancel(lower, &tick);
|
||||
timespec_from_tick(ts, tick);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline
|
||||
int oneshot_current(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR struct timespec *ts)
|
||||
{
|
||||
clock_t tick;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(lower->ops->tick_current);
|
||||
|
||||
ret = lower->ops->tick_current(lower, &tick);
|
||||
timespec_from_tick(ts, tick);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline
|
||||
int oneshot_tick_max_delay(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR clock_t *ticks)
|
||||
{
|
||||
struct timespec ts;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(lower->ops->max_delay);
|
||||
|
||||
ret = lower->ops->max_delay(lower, &ts);
|
||||
*ticks = timespec_to_tick(&ts);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline
|
||||
int oneshot_tick_start(FAR struct oneshot_lowerhalf_s *lower,
|
||||
oneshot_callback_t callback, FAR void *arg,
|
||||
clock_t ticks)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
DEBUGASSERT(lower->ops->start);
|
||||
|
||||
timespec_from_tick(&ts, ticks);
|
||||
return lower->ops->start(lower, callback, arg, &ts);
|
||||
}
|
||||
|
||||
static inline
|
||||
int oneshot_tick_cancel(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR clock_t *ticks)
|
||||
{
|
||||
struct timespec ts;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(lower->ops->cancel);
|
||||
|
||||
ret = lower->ops->cancel(lower, &ts);
|
||||
*ticks = timespec_to_tick(&ts);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline
|
||||
int oneshot_tick_current(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR clock_t *ticks)
|
||||
{
|
||||
struct timespec ts;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(lower->ops->current);
|
||||
|
||||
ret = lower->ops->current(lower, &ts);
|
||||
*ticks = timespec_to_tick(&ts);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: oneshot_initialize
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user