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;
/* Delta between current time and last execution time.*/
now = chVTGetSystemTimeX();
nowdelta = chTimeDiffX(vtlp->lasttime, now);
/* Looping through timers consuming all timers with deltas lower or equal /* Looping through timers consuming all timers with deltas lower or equal
than the interval between "now" and "lasttime". than the interval between "now" and "lasttime".*/
Note that the list scan is limited by the delta list header having while (true) {
"vtlp->dlist.delta == (sysinterval_t)-1" which is greater than all
deltas.*/
dlp = vtlp->dlist.next;
while (nowdelta >= dlp->delta) {
virtual_timer_t *vtp = (virtual_timer_t *)dlp;
systime_t lasttime;
vtfunc_t fn; vtfunc_t fn;
/* First timer in the delta list.*/
vtp = (virtual_timer_t *)vtlp->dlist.next;
/* Delta between current time and last execution time.*/
now = chVTGetSystemTimeX();
nowdelta = chTimeDiffX(vtlp->lasttime, now);
/* Loop break condition.
Note that the list scan is limited by the delta list header having
"vtlp->dlist.delta == (sysinterval_t)-1" which is greater than all
deltas*/
if (nowdelta < vtp->dlist.delta) {
break;
}
/* 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,9 +92,10 @@ 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);
@ -112,9 +114,10 @@ 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);
@ -132,9 +135,10 @@ 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);
@ -152,9 +156,10 @@ 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);
@ -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