Back-ported the latest VT algorithm and VT_Storm test application.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_20.3.x@14450 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-05-31 07:49:50 +00:00
parent c6b3961857
commit a0135fd1bb
7 changed files with 180 additions and 48 deletions

View File

@ -534,31 +534,35 @@ void chVTDoTickI(void) {
} }
} }
#else /* CH_CFG_ST_TIMEDELTA > 0 */ #else /* CH_CFG_ST_TIMEDELTA > 0 */
delta_list_t *dlp; virtual_timer_t *vtp;
sysinterval_t delta, nowdelta; sysinterval_t delta, nowdelta;
systime_t now; systime_t now;
/* Looping through timers consuming all timers with deltas lower or equal
than the interval between "now" and "lasttime".*/
while (true) {
vtfunc_t fn;
/* First timer in the delta list.*/
vtp = (virtual_timer_t *)vtlp->dlist.next;
/* Delta between current time and last execution time.*/ /* Delta between current time and last execution time.*/
now = chVTGetSystemTimeX(); now = chVTGetSystemTimeX();
nowdelta = chTimeDiffX(vtlp->lasttime, now); nowdelta = chTimeDiffX(vtlp->lasttime, now);
/* Looping through timers consuming all timers with deltas lower or equal /* Loop break condition.
than the interval between "now" and "lasttime".
Note that the list scan is limited by the delta list header having Note that the list scan is limited by the delta list header having
"vtlp->dlist.delta == (sysinterval_t)-1" which is greater than all "vtlp->dlist.delta == (sysinterval_t)-1" which is greater than all
deltas.*/ deltas*/
dlp = vtlp->dlist.next; if (nowdelta < vtp->dlist.delta) {
while (nowdelta >= dlp->delta) { break;
virtual_timer_t *vtp = (virtual_timer_t *)dlp; }
systime_t lasttime;
vtfunc_t fn;
/* Last time deadline is updated to the next timer's time.*/ /* Last time deadline is updated to the next timer's time.*/
lasttime = chTimeAddX(vtlp->lasttime, dlp->delta); vtlp->lasttime = chTimeAddX(vtlp->lasttime, vtp->dlist.delta);
vtlp->lasttime = lasttime;
/* Removing the timer from the list.*/ /* Removing the timer from the list.*/
(void) vt_dequeue(dlp); (void) vt_dequeue(&vtp->dlist);
/* Marking the timer as not armed.*/ /* Marking the timer as not armed.*/
fn = vtp->func; fn = vtp->func;
@ -575,13 +579,6 @@ void chVTDoTickI(void) {
chSysUnlockFromISR(); chSysUnlockFromISR();
fn(vtp->par); fn(vtp->par);
chSysLockFromISR(); chSysLockFromISR();
/* Delta between current time after callback execution time.*/
now = chVTGetSystemTimeX();
nowdelta = chTimeDiffX(lasttime, now);
/* Next element in the list.*/
dlp = vtlp->dlist.next;
} }
/* If the list is empty, nothing else to do.*/ /* If the list is empty, nothing else to do.*/
@ -589,10 +586,10 @@ void chVTDoTickI(void) {
return; return;
} }
/* Calculating the next alarm time.*/ /* Calculating the delta to the next alarm time.*/
delta = dlp->delta - nowdelta; delta = vtp->dlist.delta - nowdelta;
/* For normal timers limit to CH_CFG_ST_TIMEDELTA.*/ /* Limit delta to CH_CFG_ST_TIMEDELTA.*/
if (delta < (sysinterval_t)CH_CFG_ST_TIMEDELTA) { if (delta < (sysinterval_t)CH_CFG_ST_TIMEDELTA) {
delta = (sysinterval_t)CH_CFG_ST_TIMEDELTA; delta = (sysinterval_t)CH_CFG_ST_TIMEDELTA;
} }

View File

@ -52,7 +52,7 @@
* setting also defines the system tick time unit. * setting also defines the system tick time unit.
*/ */
#if !defined(CH_CFG_ST_FREQUENCY) #if !defined(CH_CFG_ST_FREQUENCY)
#define CH_CFG_ST_FREQUENCY 1000000 #define CH_CFG_ST_FREQUENCY 21250000
#endif #endif
/** /**

View File

@ -79,7 +79,7 @@
* @brief Enables the GPT subsystem. * @brief Enables the GPT subsystem.
*/ */
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) #if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
#define HAL_USE_GPT FALSE #define HAL_USE_GPT TRUE
#endif #endif
/** /**

View File

@ -131,8 +131,8 @@
#define STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY 7 #define STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY 7
#define STM32_IRQ_TIM1_CC_PRIORITY 7 #define STM32_IRQ_TIM1_CC_PRIORITY 7
#define STM32_IRQ_TIM2_PRIORITY 7 #define STM32_IRQ_TIM2_PRIORITY 7
#define STM32_IRQ_TIM3_PRIORITY 7 #define STM32_IRQ_TIM3_PRIORITY 3
#define STM32_IRQ_TIM4_PRIORITY 7 #define STM32_IRQ_TIM4_PRIORITY 4
#define STM32_IRQ_TIM5_PRIORITY 7 #define STM32_IRQ_TIM5_PRIORITY 7
#define STM32_IRQ_TIM6_PRIORITY 7 #define STM32_IRQ_TIM6_PRIORITY 7
#define STM32_IRQ_TIM7_PRIORITY 7 #define STM32_IRQ_TIM7_PRIORITY 7
@ -222,8 +222,8 @@
*/ */
#define STM32_GPT_USE_TIM1 FALSE #define STM32_GPT_USE_TIM1 FALSE
#define STM32_GPT_USE_TIM2 FALSE #define STM32_GPT_USE_TIM2 FALSE
#define STM32_GPT_USE_TIM3 FALSE #define STM32_GPT_USE_TIM3 TRUE
#define STM32_GPT_USE_TIM4 FALSE #define STM32_GPT_USE_TIM4 TRUE
#define STM32_GPT_USE_TIM5 FALSE #define STM32_GPT_USE_TIM5 FALSE
#define STM32_GPT_USE_TIM6 FALSE #define STM32_GPT_USE_TIM6 FALSE
#define STM32_GPT_USE_TIM7 FALSE #define STM32_GPT_USE_TIM7 FALSE

View File

@ -35,12 +35,40 @@
/* Module exported variables. */ /* Module exported variables. */
/*===========================================================================*/ /*===========================================================================*/
#if VT_STORM_CFG_HAMMERS || defined(__DOXYGEN__)
/*
* GPT4 configuration.
*/
static const GPTConfig gpt3cfg = {
1000000, /* 1MHz timer clock.*/
vt_storm_gpt1_cb, /* Timer callback.*/
0,
0
};
/*
* GPT3 configuration.
*/
static const GPTConfig gpt4cfg = {
1000000, /* 1MHz timer clock.*/
vt_storm_gpt2_cb, /* Timer callback.*/
0,
0
};
#endif
/* /*
* VT Storm configuration. * VT Storm configuration.
*/ */
const vt_storm_config_t portab_vt_storm_config = { const vt_storm_config_t portab_vt_storm_config = {
(BaseSequentialStream *)&PORTAB_SD1, (BaseSequentialStream *)&PORTAB_SD1,
PORTAB_LINE_LED1, PORTAB_LINE_LED1,
#if VT_STORM_CFG_HAMMERS
&GPTD3,
&GPTD4,
&gpt3cfg,
&gpt4cfg,
#endif
STM32_SYSCLK STM32_SYSCLK
}; };

View File

@ -52,6 +52,7 @@ static const vt_storm_config_t *config;
static virtual_timer_t watchdog; static virtual_timer_t watchdog;
static virtual_timer_t wrapper; static virtual_timer_t wrapper;
static virtual_timer_t sweeper0, sweeperm1, sweeperp1, sweeperm3, sweeperp3; static virtual_timer_t sweeper0, sweeperm1, sweeperp1, sweeperm3, sweeperp3;
static virtual_timer_t guard0, guard1, guard2, guard3;
static volatile sysinterval_t delay; static volatile sysinterval_t delay;
static volatile bool saturated; static volatile bool saturated;
@ -91,10 +92,11 @@ static void sweeper0_cb(void *p) {
static volatile unsigned x = 0; static volatile unsigned x = 0;
unsigned r; unsigned r;
r = rand() & 31; r = rand() & 15;
while (r--) while (r--) {
x++; x++;
} }
}
#endif #endif
chVTSetI(&wrapper, (sysinterval_t)-1, wrapper_cb, NULL); chVTSetI(&wrapper, (sysinterval_t)-1, wrapper_cb, NULL);
chVTSetI(&sweeper0, delay, sweeper0_cb, NULL); chVTSetI(&sweeper0, delay, sweeper0_cb, NULL);
@ -112,10 +114,11 @@ static void sweeperm1_cb(void *p) {
static volatile unsigned x = 0; static volatile unsigned x = 0;
unsigned r; unsigned r;
r = rand() & 31; r = rand() & 15;
while (r--) while (r--) {
x++; x++;
} }
}
#endif #endif
chVTSetI(&sweeperm1, delay - 1, sweeperm1_cb, NULL); chVTSetI(&sweeperm1, delay - 1, sweeperm1_cb, NULL);
chSysUnlockFromISR(); chSysUnlockFromISR();
@ -132,10 +135,11 @@ static void sweeperp1_cb(void *p) {
static volatile unsigned x = 0; static volatile unsigned x = 0;
unsigned r; unsigned r;
r = rand() & 31; r = rand() & 15;
while (r--) while (r--) {
x++; x++;
} }
}
#endif #endif
chVTSetI(&sweeperp1, delay + 1, sweeperp1_cb, NULL); chVTSetI(&sweeperp1, delay + 1, sweeperp1_cb, NULL);
chSysUnlockFromISR(); chSysUnlockFromISR();
@ -152,10 +156,11 @@ static void sweeperm3_cb(void *p) {
static volatile unsigned x = 0; static volatile unsigned x = 0;
unsigned r; unsigned r;
r = rand() & 31; r = rand() & 15;
while (r--) while (r--) {
x++; x++;
} }
}
#endif #endif
chVTSetI(&sweeperm3, delay - 3, sweeperm3_cb, NULL); chVTSetI(&sweeperm3, delay - 3, sweeperm3_cb, NULL);
chSysUnlockFromISR(); chSysUnlockFromISR();
@ -172,15 +177,21 @@ static void sweeperp3_cb(void *p) {
static volatile unsigned x = 0; static volatile unsigned x = 0;
unsigned r; unsigned r;
r = rand() & 31; r = rand() & 15;
while (r--) while (r--) {
x++; x++;
} }
}
#endif #endif
chVTSetI(&sweeperp3, delay + 3, sweeperp3_cb, NULL); chVTSetI(&sweeperp3, delay + 3, sweeperp3_cb, NULL);
chSysUnlockFromISR(); chSysUnlockFromISR();
} }
static void guard_cb(void *p) {
(void)p;
}
/*===========================================================================*/ /*===========================================================================*/
/* Module exported functions. */ /* Module exported functions. */
/*===========================================================================*/ /*===========================================================================*/
@ -221,19 +232,28 @@ void vt_storm_execute(const vt_storm_config_t *cfg) {
#endif #endif
chprintf(cfg->out, "***\r\n"); chprintf(cfg->out, "***\r\n");
chprintf(cfg->out, "*** Randomize: %d\r\n", VT_STORM_CFG_RANDOMIZE); chprintf(cfg->out, "*** Randomize: %d\r\n", VT_STORM_CFG_RANDOMIZE);
chprintf(cfg->out, "*** Hammers: %d\r\n", VT_STORM_CFG_HAMMERS);
chprintf(cfg->out, "*** Minimum Delay: %d ticks\r\n", VT_STORM_CFG_MIN_DELAY); chprintf(cfg->out, "*** Minimum Delay: %d ticks\r\n", VT_STORM_CFG_MIN_DELAY);
chprintf(cfg->out, "*** System Time size: %d bits\r\n", CH_CFG_ST_RESOLUTION); chprintf(cfg->out, "*** System Time size: %d bits\r\n", CH_CFG_ST_RESOLUTION);
chprintf(cfg->out, "*** Intervals size: %d bits\r\n", CH_CFG_INTERVALS_SIZE); chprintf(cfg->out, "*** Intervals size: %d bits\r\n", CH_CFG_INTERVALS_SIZE);
chprintf(cfg->out, "*** SysTick: %d Hz\r\n", CH_CFG_ST_FREQUENCY); chprintf(cfg->out, "*** SysTick: %d Hz\r\n", CH_CFG_ST_FREQUENCY);
chprintf(cfg->out, "*** Delta: %d cycles\r\n", CH_CFG_ST_TIMEDELTA); chprintf(cfg->out, "*** Delta: %d ticks\r\n", CH_CFG_ST_TIMEDELTA);
chprintf(cfg->out, "\r\n"); chprintf(cfg->out, "\r\n");
#if VT_STORM_CFG_HAMMERS
/* Starting hammer timers.*/
gptStart(cfg->gpt1p, cfg->gptcfg1p);
gptStart(cfg->gpt2p, cfg->gptcfg2p);
gptStartContinuous(cfg->gpt1p, 99);
gptStartContinuous(cfg->gpt2p, 101);
#endif
for (i = 1; i <= VT_STORM_CFG_ITERATIONS; i++) { for (i = 1; i <= VT_STORM_CFG_ITERATIONS; i++) {
chprintf(cfg->out, "Iteration %d\r\n", i); chprintf(cfg->out, "Iteration %d\r\n", i);
chThdSleepS(TIME_MS2I(10)); chThdSleepS(TIME_MS2I(10));
delay = 120; delay = TIME_US2I(120);
saturated = false; saturated = false;
do { do {
/* Starting sweepers.*/ /* Starting sweepers.*/
@ -245,6 +265,10 @@ void vt_storm_execute(const vt_storm_config_t *cfg) {
chVTSetI(&sweeperm3, delay - 3, sweeperm3_cb, NULL); chVTSetI(&sweeperm3, delay - 3, sweeperm3_cb, NULL);
chVTSetI(&sweeperp3, delay + 3, sweeperp3_cb, NULL); chVTSetI(&sweeperp3, delay + 3, sweeperp3_cb, NULL);
chVTSetI(&wrapper, (sysinterval_t) - 1, wrapper_cb, NULL); chVTSetI(&wrapper, (sysinterval_t) - 1, wrapper_cb, NULL);
chVTSetI(&guard0, TIME_MS2I(250) + (CH_CFG_TIME_QUANTUM / 2), guard_cb, NULL);
chVTSetI(&guard1, TIME_MS2I(250) + (CH_CFG_TIME_QUANTUM - 1), guard_cb, NULL);
chVTSetI(&guard2, TIME_MS2I(250) + (CH_CFG_TIME_QUANTUM + 1), guard_cb, NULL);
chVTSetI(&guard3, TIME_MS2I(250) + (CH_CFG_TIME_QUANTUM * 2), guard_cb, NULL);
/* Letting them run for half second.*/ /* Letting them run for half second.*/
chThdSleepS(TIME_MS2I(500)); chThdSleepS(TIME_MS2I(500));
@ -257,6 +281,10 @@ void vt_storm_execute(const vt_storm_config_t *cfg) {
chVTResetI(&sweeperm3); chVTResetI(&sweeperm3);
chVTResetI(&sweeperp3); chVTResetI(&sweeperp3);
chVTResetI(&wrapper); chVTResetI(&wrapper);
chVTResetI(&guard0);
chVTResetI(&guard1);
chVTResetI(&guard2);
chVTResetI(&guard3);
chSysUnlock(); chSysUnlock();
if (saturated) { if (saturated) {
@ -266,16 +294,66 @@ void vt_storm_execute(const vt_storm_config_t *cfg) {
palToggleLine(config->line); palToggleLine(config->line);
chprintf(cfg->out, "."); chprintf(cfg->out, ".");
delay--; if (delay >= TIME_US2I(1)) {
} while (delay >= VT_STORM_CFG_MIN_DELAY); delay -= TIME_US2I(1);
}
} while (delay >= (sysinterval_t)VT_STORM_CFG_MIN_DELAY);
if (saturated) { if (saturated) {
chprintf(cfg->out, "\r\nSaturated at %u uS\r\n\r\n", TIME_I2US(delay)); chprintf(cfg->out, "\r\nSaturated at %u uS\r\n\r\n", TIME_I2US(delay));
} }
else { else {
chprintf(cfg->out, "\r\nNo Saturation Reached\r\n\r\n", TIME_I2US(delay)); chprintf(cfg->out, "\r\nNon saturated\r\n\r\n");
} }
} }
} }
#if VT_STORM_CFG_HAMMERS || defined(__DOXYGEN__)
/**
* @brief GPT callback 1.
*/
void vt_storm_gpt1_cb(GPTDriver *gptp) {
(void)gptp;
#if VT_STORM_CFG_RANDOMIZE != FALSE
/* Pseudo-random delay.*/
{
static volatile unsigned x = 0;
unsigned r;
chSysLockFromISR();
r = rand() & 31;
chSysUnlockFromISR();
while (r--) {
x++;
}
}
#endif
}
/**
* @brief GPT callback 2.
*/
void vt_storm_gpt2_cb(GPTDriver *gptp) {
(void)gptp;
#if VT_STORM_CFG_RANDOMIZE != FALSE
/* Pseudo-random delay.*/
{
static volatile unsigned x = 0;
unsigned r;
chSysLockFromISR();
r = rand() & 31;
chSysUnlockFromISR();
while (r--) {
x++;
}
}
#endif
}
#endif
/** @} */ /** @} */

View File

@ -52,11 +52,18 @@
#endif #endif
/** /**
* @brief Minimum delay for each iteration. * @brief Minimum delay for each iteration in system ticks.
*/ */
#if !defined(VT_STORM_CFG_MIN_DELAY) || defined(__DOXYGEN__) #if !defined(VT_STORM_CFG_MIN_DELAY) || defined(__DOXYGEN__)
#define VT_STORM_CFG_MIN_DELAY 5 #define VT_STORM_CFG_MIN_DELAY 5
#endif #endif
/**
* @brief Enable hammer timers.
*/
#if !defined(VT_STORM_CFG_HAMMERS) || defined(__DOXYGEN__)
#define VT_STORM_CFG_HAMMERS TRUE
#endif
/** @} */ /** @} */
/*===========================================================================*/ /*===========================================================================*/
@ -80,6 +87,24 @@ typedef struct {
* @brief LED line. * @brief LED line.
*/ */
ioline_t line; ioline_t line;
#if VT_STORM_CFG_HAMMERS || defined(__DOXYGEN__)
/**
* @brief GPT driver 1.
*/
GPTDriver *gpt1p;
/**
* @brief GPT driver 2.
*/
GPTDriver *gpt2p;
/**
* @brief GPT1 configuration 1.
*/
const GPTConfig *gptcfg1p;
/**
* @brief GPT1 configuration 2.
*/
const GPTConfig *gptcfg2p;
#endif
/** /**
* @brief System clock. * @brief System clock.
*/ */
@ -98,6 +123,10 @@ typedef struct {
extern "C" { extern "C" {
#endif #endif
void vt_storm_execute(const vt_storm_config_t *cfg); void vt_storm_execute(const vt_storm_config_t *cfg);
#if VT_STORM_CFG_HAMMERS
void vt_storm_gpt1_cb(GPTDriver *gptp);
void vt_storm_gpt2_cb(GPTDriver *gptp);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif