sched/wdog: improve accuracy of wd_gettime() in tickless mode

This commit is contained in:
ligd 2018-11-09 09:26:34 -06:00 committed by Gregory Nutt
parent 74c4d4f3d7
commit 441cf6c207
4 changed files with 52 additions and 2 deletions

View File

@ -88,6 +88,7 @@ int wd_gettime(WDOG_ID wdog)
delay += curr->lag;
if (curr == wdog)
{
delay -= wd_elapse();
leave_critical_section(flags);
return delay;
}

View File

@ -67,6 +67,14 @@ sq_queue_t g_wdactivelist;
uint16_t g_wdnfree;
/* This is wdog tickbase, for wd_gettime() may called many times
* between 2 times of wd_timer(), we use it to update wd_gettime().
*/
#ifdef CONFIG_SCHED_TICKLESS
clock_t g_wdtickbase;
#endif
/****************************************************************************
* Private Data
****************************************************************************/

View File

@ -292,6 +292,12 @@ int wd_start(WDOG_ID wdog, int32_t delay, wdentry_t wdentry, int argc, ...)
if (g_wdactivelist.head == NULL)
{
#ifdef CONFIG_SCHED_TICKLESS
/* Update clock tickbase */
g_wdtickbase = clock_systimer();
#endif
/* Add the watchdog to the head == tail of the queue. */
sq_addlast((FAR sq_entry_t *)wdog, &g_wdactivelist);
@ -461,14 +467,19 @@ unsigned int wd_timer(int ticks)
/* There are. Decrement the lag counter */
wdog->lag -= decr;
ticks -= decr;
wdog->lag -= decr;
ticks -= decr;
g_wdtickbase += decr;
/* Check if the watchdog at the head of the list is ready to run */
wd_expiration();
}
/* Update clock tickbase */
g_wdtickbase += ticks;
/* Return the delay for the next watchdog to expire */
ret = g_wdactivelist.head ?

View File

@ -46,8 +46,30 @@
#include <stdbool.h>
#include <nuttx/compiler.h>
#include <nuttx/clock.h>
#include <nuttx/wdog.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Name: wd_elapse
*
* Description:
* This function is used to get time-elapse from last time wd_timer() be
* called. In case of CONFIG_SCHED_TICKLESS configured, wd_timer() may
* take lots of ticks, during this time, wd_start()/wd_cancel() may
* called, so we need wd_elapse() to correct the delay/lag.
*
****************************************************************************/
#ifdef CONFIG_SCHED_TICKLESS
# define wd_elapse() (clock_systimer() - g_wdtickbase)
#else
# define wd_elapse() (0)
#endif
/****************************************************************************
* Public Data
****************************************************************************/
@ -80,6 +102,14 @@ extern sq_queue_t g_wdactivelist;
extern uint16_t g_wdnfree;
/* This is wdog tickbase, for wd_gettime() may called many times
* between 2 times of wd_timer(), we use it to update wd_gettime().
*/
#ifdef CONFIG_SCHED_TICKLESS
extern clock_t g_wdtickbase;
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/