diff options
-rw-r--r-- | demos/STM32/RT-STM32F407-DISCOVERY/Makefile | 2 | ||||
-rw-r--r-- | demos/STM32/RT-STM32F407-DISCOVERY/chconf.h | 8 | ||||
-rw-r--r-- | demos/STM32/RT-STM32F407-DISCOVERY/main.c | 33 | ||||
-rw-r--r-- | os/hal/ports/STM32/LLD/TIMv1/st_lld.h | 1 | ||||
-rw-r--r-- | os/rt/include/chvt.h | 30 | ||||
-rw-r--r-- | 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 */
}
|