From a0135fd1bb3dca6bd8a20a98c95d750759f43fb0 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 31 May 2021 07:49:50 +0000 Subject: [PATCH] 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 --- os/rt/src/chvt.c | 49 ++++---- .../cfg/stm32g474re_nucleo64/chconf.h | 2 +- .../cfg/stm32g474re_nucleo64/halconf.h | 2 +- .../cfg/stm32g474re_nucleo64/mcuconf.h | 8 +- .../cfg/stm32g474re_nucleo64/portab.c | 28 +++++ testrt/VT_STORM/source/vt_storm.c | 108 +++++++++++++++--- testrt/VT_STORM/source/vt_storm.h | 31 ++++- 7 files changed, 180 insertions(+), 48 deletions(-) diff --git a/os/rt/src/chvt.c b/os/rt/src/chvt.c index 7bfa2c3f6..8f9d44a85 100644 --- a/os/rt/src/chvt.c +++ b/os/rt/src/chvt.c @@ -534,31 +534,35 @@ void chVTDoTickI(void) { } } #else /* CH_CFG_ST_TIMEDELTA > 0 */ - delta_list_t *dlp; + virtual_timer_t *vtp; sysinterval_t delta, nowdelta; 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 - than the interval between "now" and "lasttime". - 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.*/ - dlp = vtlp->dlist.next; - while (nowdelta >= dlp->delta) { - virtual_timer_t *vtp = (virtual_timer_t *)dlp; - systime_t lasttime; + 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.*/ + 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.*/ - lasttime = chTimeAddX(vtlp->lasttime, dlp->delta); - vtlp->lasttime = lasttime; + vtlp->lasttime = chTimeAddX(vtlp->lasttime, vtp->dlist.delta); /* Removing the timer from the list.*/ - (void) vt_dequeue(dlp); + (void) vt_dequeue(&vtp->dlist); /* Marking the timer as not armed.*/ fn = vtp->func; @@ -575,13 +579,6 @@ void chVTDoTickI(void) { chSysUnlockFromISR(); fn(vtp->par); 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.*/ @@ -589,10 +586,10 @@ void chVTDoTickI(void) { return; } - /* Calculating the next alarm time.*/ - delta = dlp->delta - nowdelta; + /* Calculating the delta to the next alarm time.*/ + 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) { delta = (sysinterval_t)CH_CFG_ST_TIMEDELTA; } diff --git a/testrt/VT_STORM/cfg/stm32g474re_nucleo64/chconf.h b/testrt/VT_STORM/cfg/stm32g474re_nucleo64/chconf.h index 94004b6eb..90218a40f 100644 --- a/testrt/VT_STORM/cfg/stm32g474re_nucleo64/chconf.h +++ b/testrt/VT_STORM/cfg/stm32g474re_nucleo64/chconf.h @@ -52,7 +52,7 @@ * setting also defines the system tick time unit. */ #if !defined(CH_CFG_ST_FREQUENCY) -#define CH_CFG_ST_FREQUENCY 1000000 +#define CH_CFG_ST_FREQUENCY 21250000 #endif /** diff --git a/testrt/VT_STORM/cfg/stm32g474re_nucleo64/halconf.h b/testrt/VT_STORM/cfg/stm32g474re_nucleo64/halconf.h index 757d5a99b..e60e89904 100644 --- a/testrt/VT_STORM/cfg/stm32g474re_nucleo64/halconf.h +++ b/testrt/VT_STORM/cfg/stm32g474re_nucleo64/halconf.h @@ -79,7 +79,7 @@ * @brief Enables the GPT subsystem. */ #if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) -#define HAL_USE_GPT FALSE +#define HAL_USE_GPT TRUE #endif /** diff --git a/testrt/VT_STORM/cfg/stm32g474re_nucleo64/mcuconf.h b/testrt/VT_STORM/cfg/stm32g474re_nucleo64/mcuconf.h index 6e1ee0ea3..4f6ab48b4 100644 --- a/testrt/VT_STORM/cfg/stm32g474re_nucleo64/mcuconf.h +++ b/testrt/VT_STORM/cfg/stm32g474re_nucleo64/mcuconf.h @@ -131,8 +131,8 @@ #define STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY 7 #define STM32_IRQ_TIM1_CC_PRIORITY 7 #define STM32_IRQ_TIM2_PRIORITY 7 -#define STM32_IRQ_TIM3_PRIORITY 7 -#define STM32_IRQ_TIM4_PRIORITY 7 +#define STM32_IRQ_TIM3_PRIORITY 3 +#define STM32_IRQ_TIM4_PRIORITY 4 #define STM32_IRQ_TIM5_PRIORITY 7 #define STM32_IRQ_TIM6_PRIORITY 7 #define STM32_IRQ_TIM7_PRIORITY 7 @@ -222,8 +222,8 @@ */ #define STM32_GPT_USE_TIM1 FALSE #define STM32_GPT_USE_TIM2 FALSE -#define STM32_GPT_USE_TIM3 FALSE -#define STM32_GPT_USE_TIM4 FALSE +#define STM32_GPT_USE_TIM3 TRUE +#define STM32_GPT_USE_TIM4 TRUE #define STM32_GPT_USE_TIM5 FALSE #define STM32_GPT_USE_TIM6 FALSE #define STM32_GPT_USE_TIM7 FALSE diff --git a/testrt/VT_STORM/cfg/stm32g474re_nucleo64/portab.c b/testrt/VT_STORM/cfg/stm32g474re_nucleo64/portab.c index cc5ff4ddb..42d690eee 100644 --- a/testrt/VT_STORM/cfg/stm32g474re_nucleo64/portab.c +++ b/testrt/VT_STORM/cfg/stm32g474re_nucleo64/portab.c @@ -35,12 +35,40 @@ /* 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. */ const vt_storm_config_t portab_vt_storm_config = { (BaseSequentialStream *)&PORTAB_SD1, PORTAB_LINE_LED1, +#if VT_STORM_CFG_HAMMERS + &GPTD3, + &GPTD4, + &gpt3cfg, + &gpt4cfg, +#endif STM32_SYSCLK }; diff --git a/testrt/VT_STORM/source/vt_storm.c b/testrt/VT_STORM/source/vt_storm.c index 11586a718..ff69a1b23 100644 --- a/testrt/VT_STORM/source/vt_storm.c +++ b/testrt/VT_STORM/source/vt_storm.c @@ -52,6 +52,7 @@ static const vt_storm_config_t *config; static virtual_timer_t watchdog; static virtual_timer_t wrapper; static virtual_timer_t sweeper0, sweeperm1, sweeperp1, sweeperm3, sweeperp3; +static virtual_timer_t guard0, guard1, guard2, guard3; static volatile sysinterval_t delay; static volatile bool saturated; @@ -91,9 +92,10 @@ static void sweeper0_cb(void *p) { static volatile unsigned x = 0; unsigned r; - r = rand() & 31; - while (r--) + r = rand() & 15; + while (r--) { x++; + } } #endif chVTSetI(&wrapper, (sysinterval_t)-1, wrapper_cb, NULL); @@ -112,9 +114,10 @@ static void sweeperm1_cb(void *p) { static volatile unsigned x = 0; unsigned r; - r = rand() & 31; - while (r--) + r = rand() & 15; + while (r--) { x++; + } } #endif chVTSetI(&sweeperm1, delay - 1, sweeperm1_cb, NULL); @@ -132,9 +135,10 @@ static void sweeperp1_cb(void *p) { static volatile unsigned x = 0; unsigned r; - r = rand() & 31; - while (r--) + r = rand() & 15; + while (r--) { x++; + } } #endif chVTSetI(&sweeperp1, delay + 1, sweeperp1_cb, NULL); @@ -152,9 +156,10 @@ static void sweeperm3_cb(void *p) { static volatile unsigned x = 0; unsigned r; - r = rand() & 31; - while (r--) + r = rand() & 15; + while (r--) { x++; + } } #endif chVTSetI(&sweeperm3, delay - 3, sweeperm3_cb, NULL); @@ -172,15 +177,21 @@ static void sweeperp3_cb(void *p) { static volatile unsigned x = 0; unsigned r; - r = rand() & 31; - while (r--) + r = rand() & 15; + while (r--) { x++; + } } #endif chVTSetI(&sweeperp3, delay + 3, sweeperp3_cb, NULL); chSysUnlockFromISR(); } +static void guard_cb(void *p) { + + (void)p; +} + /*===========================================================================*/ /* Module exported functions. */ /*===========================================================================*/ @@ -221,19 +232,28 @@ void vt_storm_execute(const vt_storm_config_t *cfg) { #endif chprintf(cfg->out, "***\r\n"); 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, "*** 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, "*** 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"); +#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++) { chprintf(cfg->out, "Iteration %d\r\n", i); chThdSleepS(TIME_MS2I(10)); - delay = 120; + delay = TIME_US2I(120); saturated = false; do { /* Starting sweepers.*/ @@ -245,6 +265,10 @@ void vt_storm_execute(const vt_storm_config_t *cfg) { chVTSetI(&sweeperm3, delay - 3, sweeperm3_cb, NULL); chVTSetI(&sweeperp3, delay + 3, sweeperp3_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.*/ chThdSleepS(TIME_MS2I(500)); @@ -257,6 +281,10 @@ void vt_storm_execute(const vt_storm_config_t *cfg) { chVTResetI(&sweeperm3); chVTResetI(&sweeperp3); chVTResetI(&wrapper); + chVTResetI(&guard0); + chVTResetI(&guard1); + chVTResetI(&guard2); + chVTResetI(&guard3); chSysUnlock(); if (saturated) { @@ -266,16 +294,66 @@ void vt_storm_execute(const vt_storm_config_t *cfg) { palToggleLine(config->line); chprintf(cfg->out, "."); - delay--; - } while (delay >= VT_STORM_CFG_MIN_DELAY); + if (delay >= TIME_US2I(1)) { + delay -= TIME_US2I(1); + } + } while (delay >= (sysinterval_t)VT_STORM_CFG_MIN_DELAY); if (saturated) { chprintf(cfg->out, "\r\nSaturated at %u uS\r\n\r\n", TIME_I2US(delay)); } 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 + /** @} */ diff --git a/testrt/VT_STORM/source/vt_storm.h b/testrt/VT_STORM/source/vt_storm.h index e1ebd0f9f..8356baa62 100644 --- a/testrt/VT_STORM/source/vt_storm.h +++ b/testrt/VT_STORM/source/vt_storm.h @@ -52,11 +52,18 @@ #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__) #define VT_STORM_CFG_MIN_DELAY 5 #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. */ 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. */ @@ -98,6 +123,10 @@ typedef struct { extern "C" { #endif 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 } #endif