mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 03:05:40 +08:00
sched/wdog: Simplify timer expiration for hrtimer.
This commit simplified the timer expiration for hrtimer. Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
This commit is contained in:
committed by
Donny(董九柱)
parent
5bab9fcc7f
commit
3eedf5f22b
@@ -126,7 +126,7 @@ static void ndelay_accurate(unsigned long nanoseconds)
|
|||||||
static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower,
|
static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower,
|
||||||
FAR void *arg)
|
FAR void *arg)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_SCHED_TICKLESS) || defined(CONFIG_HRTIMER)
|
#if defined(CONFIG_SCHED_TICKLESS)
|
||||||
nxsched_process_timer();
|
nxsched_process_timer();
|
||||||
#else
|
#else
|
||||||
clock_t now;
|
clock_t now;
|
||||||
|
|||||||
+10
-3
@@ -145,21 +145,28 @@ void hrtimer_process(uint64_t now);
|
|||||||
|
|
||||||
static inline_function void hrtimer_reprogram(uint64_t next_expired)
|
static inline_function void hrtimer_reprogram(uint64_t next_expired)
|
||||||
{
|
{
|
||||||
|
/* `hrtimer_reprogram` relies on the underlying timer being a non-periodic
|
||||||
|
* timer. If the underlying timer hardware is a periodic timer like
|
||||||
|
* systick, we cannot set the next expiration time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_TICKLESS
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
|
||||||
clock_nsec2time(&ts, next_expired);
|
clock_nsec2time(&ts, next_expired);
|
||||||
|
|
||||||
#ifdef CONFIG_ALARM_ARCH
|
# ifdef CONFIG_ALARM_ARCH
|
||||||
ret = up_alarm_start(&ts);
|
ret = up_alarm_start(&ts);
|
||||||
#else
|
# else
|
||||||
struct timespec current;
|
struct timespec current;
|
||||||
up_timer_gettime(¤t);
|
up_timer_gettime(¤t);
|
||||||
clock_timespec_subtract(&ts, ¤t, &ts);
|
clock_timespec_subtract(&ts, ¤t, &ts);
|
||||||
ret = up_timer_start(&ts);
|
ret = up_timer_start(&ts);
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
DEBUGASSERT(ret == 0);
|
DEBUGASSERT(ret == 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ set(SRCS
|
|||||||
sched_sysinfo.c
|
sched_sysinfo.c
|
||||||
sched_get_stateinfo.c
|
sched_get_stateinfo.c
|
||||||
sched_switchcontext.c
|
sched_switchcontext.c
|
||||||
sched_sleep.c
|
sched_sleep.c)
|
||||||
sched_timer.c)
|
|
||||||
|
|
||||||
if(DEFINED CONFIG_STACKCHECK_MARGIN)
|
if(DEFINED CONFIG_STACKCHECK_MARGIN)
|
||||||
if(NOT CONFIG_STACKCHECK_MARGIN EQUAL -1)
|
if(NOT CONFIG_STACKCHECK_MARGIN EQUAL -1)
|
||||||
@@ -98,7 +97,7 @@ if(NOT CONFIG_SCHED_CPULOAD_NONE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_SCHED_TICKLESS)
|
if(CONFIG_SCHED_TICKLESS)
|
||||||
list(APPEND SRCS sched_tickexpiration.c)
|
list(APPEND SRCS sched_processtickless.c)
|
||||||
else()
|
else()
|
||||||
list(APPEND SRCS sched_processtick.c)
|
list(APPEND SRCS sched_processtick.c)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ CSRCS += sched_yield.c sched_rrgetinterval.c sched_foreach.c
|
|||||||
CSRCS += sched_lock.c sched_unlock.c sched_lockcount.c
|
CSRCS += sched_lock.c sched_unlock.c sched_lockcount.c
|
||||||
CSRCS += sched_idletask.c sched_self.c sched_get_stackinfo.c sched_get_tls.c
|
CSRCS += sched_idletask.c sched_self.c sched_get_stackinfo.c sched_get_tls.c
|
||||||
CSRCS += sched_sysinfo.c sched_get_stateinfo.c sched_getcpu.c
|
CSRCS += sched_sysinfo.c sched_get_stateinfo.c sched_getcpu.c
|
||||||
CSRCS += sched_switchcontext.c sched_sleep.c sched_timer.c
|
CSRCS += sched_switchcontext.c sched_sleep.c
|
||||||
|
|
||||||
ifneq ($(CONFIG_STACKCHECK_MARGIN),)
|
ifneq ($(CONFIG_STACKCHECK_MARGIN),)
|
||||||
ifneq ($(CONFIG_STACKCHECK_MARGIN),-1)
|
ifneq ($(CONFIG_STACKCHECK_MARGIN),-1)
|
||||||
@@ -79,7 +79,7 @@ endif
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_SCHED_TICKLESS),y)
|
ifeq ($(CONFIG_SCHED_TICKLESS),y)
|
||||||
CSRCS += sched_tickexpiration.c
|
CSRCS += sched_processtickless.c
|
||||||
else
|
else
|
||||||
CSRCS += sched_processtick.c
|
CSRCS += sched_processtick.c
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "wdog/wdog.h"
|
#include "wdog/wdog.h"
|
||||||
|
#include "hrtimer/hrtimer.h"
|
||||||
#include "clock/clock.h"
|
#include "clock/clock.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -146,7 +147,7 @@ static inline void nxsched_process_scheduler(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nxsched_process_tick
|
* Name: nxsched_process_timer
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function handles system timer events.
|
* This function handles system timer events.
|
||||||
@@ -165,7 +166,7 @@ static inline void nxsched_process_scheduler(void)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void nxsched_process_tick(void)
|
void nxsched_process_timer(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||||
/* Process wall time */
|
/* Process wall time */
|
||||||
@@ -185,7 +186,11 @@ void nxsched_process_tick(void)
|
|||||||
|
|
||||||
/* Process watchdogs */
|
/* Process watchdogs */
|
||||||
|
|
||||||
|
#ifdef CONFIG_HRTIMER
|
||||||
|
hrtimer_process(clock_systime_nsec());
|
||||||
|
#else
|
||||||
wd_timer(clock_systime_ticks());
|
wd_timer(clock_systime_ticks());
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SYSTEMTICK_HOOK
|
#ifdef CONFIG_SYSTEMTICK_HOOK
|
||||||
/* Call out to a user-provided function in order to perform board-specific,
|
/* Call out to a user-provided function in order to perform board-specific,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/sched/sched_tickexpiration.c
|
* sched/sched/sched_processtickless.c
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "wdog/wdog.h"
|
#include "wdog/wdog.h"
|
||||||
|
#include "hrtimer/hrtimer.h"
|
||||||
#include "clock/clock.h"
|
#include "clock/clock.h"
|
||||||
|
|
||||||
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
#ifdef CONFIG_CLOCK_TIMEKEEPING
|
||||||
@@ -362,8 +363,11 @@ static void nxsched_timer_start(clock_t ticks, clock_t interval)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void nxsched_process_tick(void)
|
void nxsched_process_timer(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_HRTIMER
|
||||||
|
hrtimer_process(clock_systime_nsec());
|
||||||
|
#else
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
clock_t ticks;
|
clock_t ticks;
|
||||||
|
|
||||||
@@ -389,6 +393,7 @@ void nxsched_process_tick(void)
|
|||||||
wd_timer(ticks);
|
wd_timer(ticks);
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* sched/sched/sched_timer.c
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership. The
|
|
||||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Included Files
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
|
||||||
#include <nuttx/arch.h>
|
|
||||||
#include <nuttx/clock.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "sched/sched.h"
|
|
||||||
#include "hrtimer/hrtimer.h"
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Data
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/* High-resolution timer used to drive the scheduler tick.
|
|
||||||
*
|
|
||||||
* In non-tickless mode, this timer periodically generates a scheduler
|
|
||||||
* tick with interval NSEC_PER_TICK.
|
|
||||||
*
|
|
||||||
* In tickless mode, the timer is still used, but the callback does not
|
|
||||||
* request automatic re-arming.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef CONFIG_HRTIMER
|
|
||||||
static hrtimer_t g_sched_hrtimer;
|
|
||||||
static bool g_sched_hrtimer_started = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: nxsched_hrtimer_callback
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* High-resolution timer callback used to drive the scheduler.
|
|
||||||
*
|
|
||||||
* This callback is invoked when the scheduler hrtimer expires.
|
|
||||||
* It advances the scheduler time base by calling
|
|
||||||
* nxsched_process_tick().
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* hrtimer - Pointer to the expired hrtimer instance
|
|
||||||
* expired - Expiration time in nanoseconds
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* In non-tickless mode:
|
|
||||||
* Returns the next expiration interval (NSEC_PER_TICK),
|
|
||||||
* causing the hrtimer to be re-armed periodically.
|
|
||||||
*
|
|
||||||
* In tickless mode:
|
|
||||||
* Returns 0 to indicate that the timer should not be
|
|
||||||
* automatically restarted.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#ifdef CONFIG_HRTIMER
|
|
||||||
static uint64_t
|
|
||||||
nxsched_hrtimer_callback(FAR const struct hrtimer_s *hrtimer,
|
|
||||||
uint64_t expired)
|
|
||||||
{
|
|
||||||
UNUSED(hrtimer);
|
|
||||||
UNUSED(expired);
|
|
||||||
|
|
||||||
/* Advance scheduler time and process time slice expiration */
|
|
||||||
|
|
||||||
nxsched_process_tick();
|
|
||||||
|
|
||||||
#ifndef CONFIG_SCHED_TICKLESS
|
|
||||||
/* Periodic tick mode: re-arm timer with fixed tick interval */
|
|
||||||
|
|
||||||
return NSEC_PER_TICK;
|
|
||||||
#else
|
|
||||||
/* Tickless mode controls the next wakeup explicitly */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#if defined(CONFIG_HRTIMER) && defined(CONFIG_SCHED_TICKLESS)
|
|
||||||
int nxsched_hrtimer_tick_start(clock_t tick)
|
|
||||||
{
|
|
||||||
return hrtimer_start(&g_sched_hrtimer,
|
|
||||||
nxsched_hrtimer_callback,
|
|
||||||
tick * NSEC_PER_TICK,
|
|
||||||
HRTIMER_MODE_ABS);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: nxsched_process_timer
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Process scheduler timing events.
|
|
||||||
*
|
|
||||||
* If high-resolution timers are enabled, this function dispatches
|
|
||||||
* expired hrtimers based on the current hrtimer time.
|
|
||||||
*
|
|
||||||
* Otherwise, it falls back to directly processing a scheduler tick.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
void nxsched_process_timer(void)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_HRTIMER
|
|
||||||
/* Process all expired high-resolution timers */
|
|
||||||
|
|
||||||
if (g_sched_hrtimer_started == false)
|
|
||||||
{
|
|
||||||
g_sched_hrtimer_started = true;
|
|
||||||
hrtimer_start(&g_sched_hrtimer,
|
|
||||||
nxsched_hrtimer_callback,
|
|
||||||
NSEC_PER_TICK,
|
|
||||||
HRTIMER_MODE_REL);
|
|
||||||
}
|
|
||||||
|
|
||||||
hrtimer_process(clock_systime_nsec());
|
|
||||||
#else
|
|
||||||
/* Fallback: process one scheduler tick */
|
|
||||||
|
|
||||||
nxsched_process_tick();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@@ -95,7 +95,7 @@ int wd_cancel(FAR struct wdog_s *wdog)
|
|||||||
|
|
||||||
if (!list_is_empty(&g_wdactivelist))
|
if (!list_is_empty(&g_wdactivelist))
|
||||||
{
|
{
|
||||||
wd_timer_start(wd_next_expire());
|
wd_timer_start(wd_next_expire(), false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,7 +41,11 @@
|
|||||||
|
|
||||||
struct list_node g_wdactivelist = LIST_INITIAL_VALUE(g_wdactivelist);
|
struct list_node g_wdactivelist = LIST_INITIAL_VALUE(g_wdactivelist);
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_TICKLESS
|
#ifdef CONFIG_HRTIMER
|
||||||
|
struct hrtimer_s g_wdtimer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_SCHED_TICKLESS) || defined(CONFIG_HRTIMER)
|
||||||
bool g_wdtimernested;
|
bool g_wdtimernested;
|
||||||
clock_t g_wdexpired;
|
clock_t g_wdexpired;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+18
-4
@@ -104,7 +104,7 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static inline_function void wd_expiration(clock_t ticks)
|
static inline_function clock_t wd_expiration(clock_t ticks)
|
||||||
{
|
{
|
||||||
FAR struct wdog_s *wdog;
|
FAR struct wdog_s *wdog;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
@@ -156,10 +156,12 @@ static inline_function void wd_expiration(clock_t ticks)
|
|||||||
|
|
||||||
if (next_ticks != ticks)
|
if (next_ticks != ticks)
|
||||||
{
|
{
|
||||||
wd_timer_start(next_ticks);
|
wd_timer_start(next_ticks, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
|
|
||||||
|
return next_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -283,7 +285,7 @@ int wd_start_abstick(FAR struct wdog_s *wdog, clock_t ticks,
|
|||||||
|
|
||||||
/* If the wdog is canceling, restarting the wdog is not allowed. */
|
/* If the wdog is canceling, restarting the wdog is not allowed. */
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_TICKLESS
|
#if defined(CONFIG_SCHED_TICKLESS) || defined(CONFIG_HRTIMER)
|
||||||
/* We need to reassess timer if the watchdog
|
/* We need to reassess timer if the watchdog
|
||||||
* list head has changed.
|
* list head has changed.
|
||||||
*/
|
*/
|
||||||
@@ -304,7 +306,7 @@ int wd_start_abstick(FAR struct wdog_s *wdog, clock_t ticks,
|
|||||||
* changed, then this will pick that new delay.
|
* changed, then this will pick that new delay.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
wd_timer_start(wd_next_expire());
|
wd_timer_start(wd_next_expire(), false);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
UNUSED(reassess);
|
UNUSED(reassess);
|
||||||
@@ -352,9 +354,21 @@ int wd_start_abstick(FAR struct wdog_s *wdog, clock_t ticks,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CONFIG_HRTIMER
|
||||||
void wd_timer(clock_t ticks)
|
void wd_timer(clock_t ticks)
|
||||||
{
|
{
|
||||||
/* Check if there are any active watchdogs to process */
|
/* Check if there are any active watchdogs to process */
|
||||||
|
|
||||||
wd_expiration(ticks);
|
wd_expiration(ticks);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
uint64_t wd_timer(const hrtimer_t *timer, uint64_t expired)
|
||||||
|
{
|
||||||
|
/* Check if there are any active watchdogs to process */
|
||||||
|
|
||||||
|
clock_t tick = div_const(expired, NSEC_PER_TICK);
|
||||||
|
clock_t delay = wd_expiration(tick) - tick;
|
||||||
|
uint64_t nsec = TICK2NSEC((uint64_t)delay);
|
||||||
|
return nsec <= HRTIMER_MAX_DELAY ? nsec : HRTIMER_MAX_DELAY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
+65
-37
@@ -38,6 +38,10 @@
|
|||||||
#include <nuttx/wdog.h>
|
#include <nuttx/wdog.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_HRTIMER
|
||||||
|
# include <nuttx/hrtimer.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -61,16 +65,56 @@ extern "C"
|
|||||||
|
|
||||||
extern struct list_node g_wdactivelist;
|
extern struct list_node g_wdactivelist;
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_TICKLESS
|
#ifdef CONFIG_HRTIMER
|
||||||
|
extern struct hrtimer_s g_wdtimer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_SCHED_TICKLESS) || defined(CONFIG_HRTIMER)
|
||||||
extern bool g_wdtimernested;
|
extern bool g_wdtimernested;
|
||||||
extern clock_t g_wdexpired;
|
extern clock_t g_wdexpired;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: wd_timer
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function is called from the timer interrupt handler to determine
|
||||||
|
* if it is time to execute a watchdog function. If so, the watchdog
|
||||||
|
* function will be executed in the context of the timer interrupt
|
||||||
|
* handler.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* ticks - If CONFIG_SCHED_TICKLESS is defined then the number of ticks
|
||||||
|
* in the interval that just expired is provided. Otherwise,
|
||||||
|
* this function is called on each timer interrupt and a value of one
|
||||||
|
* is implicit.
|
||||||
|
* noswitches - True: Can't do context switches now.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* If CONFIG_SCHED_TICKLESS is defined then the number of ticks for the
|
||||||
|
* next delay is provided (zero if no delay). Otherwise, this function
|
||||||
|
* has no returned value.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Called from interrupt handler logic with interrupts disabled.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CONFIG_HRTIMER
|
||||||
|
void wd_timer(clock_t ticks);
|
||||||
|
#else
|
||||||
|
uint64_t wd_timer(const hrtimer_t *timer, uint64_t expired);
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Inline functions
|
* Inline functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_TICKLESS
|
#if defined(CONFIG_SCHED_TICKLESS) || defined(CONFIG_HRTIMER)
|
||||||
# define wd_in_callback() (g_wdtimernested)
|
# define wd_in_callback() (g_wdtimernested)
|
||||||
# define wd_set_nested(f) (g_wdtimernested = (f))
|
# define wd_set_nested(f) (g_wdtimernested = (f))
|
||||||
# define wd_update_expire(expired) (g_wdexpired = (expired))
|
# define wd_update_expire(expired) (g_wdexpired = (expired))
|
||||||
@@ -80,7 +124,22 @@ extern clock_t g_wdexpired;
|
|||||||
# define wd_update_expire(expired)
|
# define wd_update_expire(expired)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_TICKLESS
|
#ifdef CONFIG_HRTIMER
|
||||||
|
static inline_function void wd_timer_start(clock_t tick, bool in_expiration)
|
||||||
|
{
|
||||||
|
DEBUGASSERT((uint64_t)tick <= UINT64_MAX / NSEC_PER_TICK);
|
||||||
|
if (!in_expiration)
|
||||||
|
{
|
||||||
|
hrtimer_start(&g_wdtimer, wd_timer,
|
||||||
|
TICK2NSEC((uint64_t)tick), HRTIMER_MODE_ABS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline_function void wd_timer_cancel(void)
|
||||||
|
{
|
||||||
|
hrtimer_cancel(&g_wdtimer);
|
||||||
|
}
|
||||||
|
#elif defined(CONFIG_SCHED_TICKLESS)
|
||||||
static inline_function clock_t wd_adjust_next_tick(clock_t tick)
|
static inline_function clock_t wd_adjust_next_tick(clock_t tick)
|
||||||
{
|
{
|
||||||
clock_t next_tick = tick;
|
clock_t next_tick = tick;
|
||||||
@@ -111,13 +170,10 @@ static inline_function clock_t wd_adjust_next_tick(clock_t tick)
|
|||||||
return next_tick;
|
return next_tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline_function void wd_timer_start(clock_t tick)
|
static inline_function void wd_timer_start(clock_t tick, bool in_expiration)
|
||||||
{
|
{
|
||||||
clock_t next_tick = wd_adjust_next_tick(tick);
|
clock_t next_tick = wd_adjust_next_tick(tick);
|
||||||
|
#ifdef CONFIG_SCHED_TICKLESS_ALARM
|
||||||
#ifdef CONFIG_HRTIMER
|
|
||||||
nxsched_hrtimer_tick_start(tick);
|
|
||||||
#elif defined(CONFIG_SCHED_TICKLESS_ALARM)
|
|
||||||
up_alarm_tick_start(next_tick);
|
up_alarm_tick_start(next_tick);
|
||||||
#else
|
#else
|
||||||
up_timer_tick_start(next_tick - clock_systime_ticks());
|
up_timer_tick_start(next_tick - clock_systime_ticks());
|
||||||
@@ -134,7 +190,7 @@ static inline_function void wd_timer_cancel(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define wd_timer_start(next_tick)
|
# define wd_timer_start(next_tick, in_expiration)
|
||||||
# define wd_timer_cancel()
|
# define wd_timer_cancel()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -161,34 +217,6 @@ static inline_function clock_t wd_get_next_expire(clock_t curr)
|
|||||||
return (sclock_t)(next - curr) <= 0 ? 0u : next;
|
return (sclock_t)(next - curr) <= 0 ? 0u : next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: wd_timer
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This function is called from the timer interrupt handler to determine
|
|
||||||
* if it is time to execute a watchdog function. If so, the watchdog
|
|
||||||
* function will be executed in the context of the timer interrupt
|
|
||||||
* handler.
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* ticks - If CONFIG_SCHED_TICKLESS is defined then the number of ticks
|
|
||||||
* in the interval that just expired is provided. Otherwise,
|
|
||||||
* this function is called on each timer interrupt and a value of one
|
|
||||||
* is implicit.
|
|
||||||
* noswitches - True: Can't do context switches now.
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* If CONFIG_SCHED_TICKLESS is defined then the number of ticks for the
|
|
||||||
* next delay is provided (zero if no delay). Otherwise, this function
|
|
||||||
* has no returned value.
|
|
||||||
*
|
|
||||||
* Assumptions:
|
|
||||||
* Called from interrupt handler logic with interrupts disabled.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
void wd_timer(clock_t ticks);
|
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user