From a484164f768cdea9b346b2af2c71376e8e260d21 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 31 Mar 2015 06:22:30 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7833 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/STM32/RT-STM32F407-DISCOVERY/Makefile | 2 +- demos/STM32/RT-STM32F407-DISCOVERY/chconf.h | 8 +-- demos/STM32/RT-STM32F407-DISCOVERY/main.c | 33 +++++++++++- os/hal/ports/STM32/LLD/TIMv1/st_lld.h | 1 + os/rt/include/chvt.h | 30 ++++++----- os/rt/src/chvt.c | 82 +++++++++++++++++++++++------ 6 files changed, 123 insertions(+), 33 deletions(-) diff --git a/demos/STM32/RT-STM32F407-DISCOVERY/Makefile b/demos/STM32/RT-STM32F407-DISCOVERY/Makefile index e56e7e88c..dbdde6a0a 100644 --- a/demos/STM32/RT-STM32F407-DISCOVERY/Makefile +++ b/demos/STM32/RT-STM32F407-DISCOVERY/Makefile @@ -5,7 +5,7 @@ # Compiler options here. ifeq ($(USE_OPT),) - USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 + USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16 endif # C specific options here (added to USE_OPT). diff --git a/demos/STM32/RT-STM32F407-DISCOVERY/chconf.h b/demos/STM32/RT-STM32F407-DISCOVERY/chconf.h index 01849821c..110cbe8e0 100644 --- a/demos/STM32/RT-STM32F407-DISCOVERY/chconf.h +++ b/demos/STM32/RT-STM32F407-DISCOVERY/chconf.h @@ -46,7 +46,7 @@ * @details Frequency of the system timer that drives the system ticks. This * setting also defines the system tick time unit. */ -#define CH_CFG_ST_FREQUENCY 10000 +#define CH_CFG_ST_FREQUENCY 100000 /** * @brief Time delta constant for the tick-less mode. @@ -333,7 +333,7 @@ * * @note The default is @p FALSE. */ -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK TRUE /** * @brief Debug option, parameters checks. @@ -342,7 +342,7 @@ * * @note The default is @p FALSE. */ -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS TRUE /** * @brief Debug option, consistency checks. @@ -352,7 +352,7 @@ * * @note The default is @p FALSE. */ -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS TRUE /** * @brief Debug option, trace buffer. diff --git a/demos/STM32/RT-STM32F407-DISCOVERY/main.c b/demos/STM32/RT-STM32F407-DISCOVERY/main.c index e6930f4e8..dbcebbba9 100644 --- a/demos/STM32/RT-STM32F407-DISCOVERY/main.c +++ b/demos/STM32/RT-STM32F407-DISCOVERY/main.c @@ -35,6 +35,31 @@ static THD_FUNCTION(Thread1, arg) { } } +virtual_timer_t vt1, vt2, vt3; + +static void cb1(void *p) { + + (void)p; + chSysLockFromISR(); +// if (chVTIsArmedI(&vt1)) +// chVTDoResetI(&vt1); + chSysUnlockFromISR(); +} + +static void cb2(void *p) { + + (void)p; + chSysLockFromISR(); +// if (!chVTIsArmedI(&vt3)) +// chVTDoSetI(&vt3, 19, cb1, NULL); + chSysUnlockFromISR(); +} + +static void cb3(void *p) { + + (void)p; +} + /* * Application entry point. */ @@ -70,6 +95,12 @@ int main(void) { while (TRUE) { if (palReadPad(GPIOA, GPIOA_BUTTON)) TestThread(&SD2); - chThdSleepMilliseconds(500); + chVTSet(&vt1, 7, cb1, NULL); + chThdSleep(5); + chSysLock(); + if (!chVTIsArmedI(&vt2)) + chVTDoSetI(&vt2, 13, cb2, NULL); + chSysUnlock(); +// chVTReset(&vt1); } } diff --git a/os/hal/ports/STM32/LLD/TIMv1/st_lld.h b/os/hal/ports/STM32/LLD/TIMv1/st_lld.h index 7e64b893b..9c5442158 100644 --- a/os/hal/ports/STM32/LLD/TIMv1/st_lld.h +++ b/os/hal/ports/STM32/LLD/TIMv1/st_lld.h @@ -164,6 +164,7 @@ static inline void st_lld_stop_alarm(void) { static inline void st_lld_set_alarm(systime_t time) { STM32_ST_TIM->CCR[0] = (uint32_t)time; + STM32_ST_TIM->SR = 0; } /** diff --git a/os/rt/include/chvt.h b/os/rt/include/chvt.h index 736d572b4..0bb127250 100644 --- a/os/rt/include/chvt.h +++ b/os/rt/include/chvt.h @@ -466,7 +466,6 @@ static inline void chVTDoTickI(void) { } #else /* CH_CFG_ST_TIMEDELTA > 0 */ virtual_timer_t *vtp; - systime_t now, delta; /* The list is assumed to be non-empty because an tick interrupt just occurred.*/ @@ -482,6 +481,10 @@ static inline void chVTDoTickI(void) { chVTGetSystemTimeX() + 1), "out of time window"); +/* if (now > 21) { + __BKPT(0); + }*/ + /* Timers processing loop.*/ while (true) { vtfunc_t fn; @@ -495,11 +498,6 @@ static inline void chVTDoTickI(void) { fn = vtp->vt_func; vtp->vt_func = NULL; - /* If the list is empty then the timer is stopped.*/ - if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.vt_next) { - port_timer_stop_alarm(); - } - /* Leaving the system critical zone in order to execute the callback and in order to give a preemption chance to higher priority interrupts.*/ @@ -513,25 +511,33 @@ static inline void chVTDoTickI(void) { chSysLockFromISR(); /* If the list is empty then ending the loop, the list has to be - re-checked because new timers could have been added from within - the callback.*/ + re-checked because new timers could have been added/removed from + within the callback or other ISRs.*/ vtp = ch.vtlist.vt_next; if (&ch.vtlist == (virtual_timers_list_t *)vtp) { + /* Timers list empty, stopping alarms.*/ + port_timer_stop_alarm(); return; } /* Getting the current system time and calculating the time window since the last time has expired.*/ now = chVTGetSystemTimeX(); - delta = now - ch.vtlist.vt_lasttime; /* The next element is outside the current time window, the loop is stopped here.*/ - if (vtp->vt_delta > delta) { + if (vtp->vt_delta > now - ch.vtlist.vt_lasttime) { /* Updating the alarm to the next deadline, deadline that must not be closer in time than the minimum time delta.*/ - delta = (vtp->vt_delta >= (systime_t)CH_CFG_ST_TIMEDELTA) ? - vtp->vt_delta : (systime_t)CH_CFG_ST_TIMEDELTA; + systime_t delta = ch.vtlist.vt_lasttime + vtp->vt_delta - now; + if (delta < (systime_t)CH_CFG_ST_TIMEDELTA) { + delta = (systime_t)CH_CFG_ST_TIMEDELTA; + } + +// if (now + delta >= 23) { +// __BKPT(0); +// } + port_timer_set_alarm(now + delta); chDbgAssert((chVTGetSystemTimeX() - ch.vtlist.vt_lasttime) < delta, diff --git a/os/rt/src/chvt.c b/os/rt/src/chvt.c index 61fa7e056..eae49bd3a 100644 --- a/os/rt/src/chvt.c +++ b/os/rt/src/chvt.c @@ -99,13 +99,18 @@ void chVTDoSetI(virtual_timer_t *vtp, systime_t delay, chDbgCheckClassI(); chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (delay != TIME_IMMEDIATE)); +/* systime_t tm = chVTGetSystemTimeX(); + if (tm >= 23) { + __BKPT(0); + }*/ + vtp->vt_par = par; vtp->vt_func = vtfunc; p = ch.vtlist.vt_next; -#if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__) +#if CH_CFG_ST_TIMEDELTA > 0 { - systime_t now = port_timer_get_time(); + systime_t now = chVTGetSystemTimeX(); /* If the requested delay is lower than the minimum safe delta then it is raised to the minimum safe value.*/ @@ -151,6 +156,11 @@ void chVTDoSetI(virtual_timer_t *vtp, systime_t delay, value in the header must be restored.*/; p->vt_delta -= delay; ch.vtlist.vt_delta = (systime_t)-1; + +/* systime_t tmx = chVTGetSystemTimeX(); + if (tmx >= 23) { + __BKPT(0); + }*/ } /** @@ -162,11 +172,24 @@ void chVTDoSetI(virtual_timer_t *vtp, systime_t delay, * @iclass */ void chVTDoResetI(virtual_timer_t *vtp) { +#if CH_CFG_ST_TIMEDELTA > 0 + virtual_timer_t *first; +#endif chDbgCheckClassI(); chDbgCheck(vtp != NULL); chDbgAssert(vtp->vt_func != NULL, "timer not set or already triggered"); +/* systime_t tm = chVTGetSystemTimeX(); + if (tm >= 23) { + __BKPT(0); + }*/ + + /* Checking if the element to be removed was the first in the list.*/ +#if CH_CFG_ST_TIMEDELTA > 0 + first = ch.vtlist.vt_next; +#endif + /* Removing the element from the delta list.*/ vtp->vt_next->vt_delta += vtp->vt_delta; vtp->vt_prev->vt_next = vtp->vt_next; @@ -177,24 +200,53 @@ void chVTDoResetI(virtual_timer_t *vtp) { is the last of the list, restoring it.*/ ch.vtlist.vt_delta = (systime_t)-1; -#if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__) +#if CH_CFG_ST_TIMEDELTA > 0 { + systime_t nowdelta, delta; + + /* Just removed the last element in the list, alarm timer stopped and + return.*/ if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.vt_next) { - /* Just removed the last element in the list, alarm timer stopped.*/ port_timer_stop_alarm(); + return; } - else { - /* Updating the alarm to the next deadline, deadline that must not be - closer in time than the minimum time delta.*/ - if (ch.vtlist.vt_next->vt_delta >= (systime_t)CH_CFG_ST_TIMEDELTA) { - port_timer_set_alarm(ch.vtlist.vt_lasttime + - ch.vtlist.vt_next->vt_delta); - } - else { - port_timer_set_alarm(ch.vtlist.vt_lasttime + - (systime_t)CH_CFG_ST_TIMEDELTA); - } + + /* If the removed element was not the first one then just return, the + alarm is already set to the first element.*/ + if (vtp != first) { + return; } + + /* If the new first element has a delta of zero then the alarm is not + modified, the already programmed alarm will serve it.*/ + if (ch.vtlist.vt_next->vt_delta == 0) { + return; + } + + /* Distance in ticks between the last alarm event and current time.*/ + nowdelta = chVTGetSystemTimeX() - ch.vtlist.vt_lasttime; + + /* If the current time surpassed the time of the next element in list + then the event interrupt is already pending, just return.*/ + if (nowdelta >= ch.vtlist.vt_next->vt_delta) { + return; + } + + /* Distance from the next scheduled event and now.*/ + delta = ch.vtlist.vt_next->vt_delta - nowdelta; + + /* Making sure to not schedule an event closer than CH_CFG_ST_TIMEDELTA + ticks from now.*/ + if (delta < (systime_t)CH_CFG_ST_TIMEDELTA) { + delta = (systime_t)CH_CFG_ST_TIMEDELTA; + } + + port_timer_set_alarm(ch.vtlist.vt_lasttime + nowdelta + delta); + + systime_t tmx = chVTGetSystemTimeX(); +/* if (tmx >= 23) { + __BKPT(0); + }*/ } #endif /* CH_CFG_ST_TIMEDELTA > 0 */ } -- cgit v1.2.3