git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7833 35acf78f-673a-0410-8e92-d51de3d6d3f4

master
Giovanni Di Sirio 2015-03-31 06:22:30 +00:00
parent 330e38629d
commit a484164f76
6 changed files with 123 additions and 33 deletions

View File

@ -5,7 +5,7 @@
# Compiler options here. # Compiler options here.
ifeq ($(USE_OPT),) ifeq ($(USE_OPT),)
USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16
endif endif
# C specific options here (added to USE_OPT). # C specific options here (added to USE_OPT).

View File

@ -46,7 +46,7 @@
* @details Frequency of the system timer that drives the system ticks. This * @details Frequency of the system timer that drives the system ticks. This
* setting also defines the system tick time unit. * 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. * @brief Time delta constant for the tick-less mode.
@ -333,7 +333,7 @@
* *
* @note The default is @p FALSE. * @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. * @brief Debug option, parameters checks.
@ -342,7 +342,7 @@
* *
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#define CH_DBG_ENABLE_CHECKS FALSE #define CH_DBG_ENABLE_CHECKS TRUE
/** /**
* @brief Debug option, consistency checks. * @brief Debug option, consistency checks.
@ -352,7 +352,7 @@
* *
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#define CH_DBG_ENABLE_ASSERTS FALSE #define CH_DBG_ENABLE_ASSERTS TRUE
/** /**
* @brief Debug option, trace buffer. * @brief Debug option, trace buffer.

View File

@ -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. * Application entry point.
*/ */
@ -70,6 +95,12 @@ int main(void) {
while (TRUE) { while (TRUE) {
if (palReadPad(GPIOA, GPIOA_BUTTON)) if (palReadPad(GPIOA, GPIOA_BUTTON))
TestThread(&SD2); TestThread(&SD2);
chThdSleepMilliseconds(500); chVTSet(&vt1, 7, cb1, NULL);
chThdSleep(5);
chSysLock();
if (!chVTIsArmedI(&vt2))
chVTDoSetI(&vt2, 13, cb2, NULL);
chSysUnlock();
// chVTReset(&vt1);
} }
} }

View File

@ -164,6 +164,7 @@ static inline void st_lld_stop_alarm(void) {
static inline void st_lld_set_alarm(systime_t time) { static inline void st_lld_set_alarm(systime_t time) {
STM32_ST_TIM->CCR[0] = (uint32_t)time; STM32_ST_TIM->CCR[0] = (uint32_t)time;
STM32_ST_TIM->SR = 0;
} }
/** /**

View File

@ -466,7 +466,6 @@ static inline void chVTDoTickI(void) {
} }
#else /* CH_CFG_ST_TIMEDELTA > 0 */ #else /* CH_CFG_ST_TIMEDELTA > 0 */
virtual_timer_t *vtp; virtual_timer_t *vtp;
systime_t now, delta;
/* The list is assumed to be non-empty because an tick interrupt just /* The list is assumed to be non-empty because an tick interrupt just
occurred.*/ occurred.*/
@ -482,6 +481,10 @@ static inline void chVTDoTickI(void) {
chVTGetSystemTimeX() + 1), chVTGetSystemTimeX() + 1),
"out of time window"); "out of time window");
/* if (now > 21) {
__BKPT(0);
}*/
/* Timers processing loop.*/ /* Timers processing loop.*/
while (true) { while (true) {
vtfunc_t fn; vtfunc_t fn;
@ -495,11 +498,6 @@ static inline void chVTDoTickI(void) {
fn = vtp->vt_func; fn = vtp->vt_func;
vtp->vt_func = NULL; 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 /* Leaving the system critical zone in order to execute the callback
and in order to give a preemption chance to higher priority and in order to give a preemption chance to higher priority
interrupts.*/ interrupts.*/
@ -513,25 +511,33 @@ static inline void chVTDoTickI(void) {
chSysLockFromISR(); chSysLockFromISR();
/* If the list is empty then ending the loop, the list has to be /* 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 re-checked because new timers could have been added/removed from
the callback.*/ within the callback or other ISRs.*/
vtp = ch.vtlist.vt_next; vtp = ch.vtlist.vt_next;
if (&ch.vtlist == (virtual_timers_list_t *)vtp) { if (&ch.vtlist == (virtual_timers_list_t *)vtp) {
/* Timers list empty, stopping alarms.*/
port_timer_stop_alarm();
return; return;
} }
/* Getting the current system time and calculating the time window since /* Getting the current system time and calculating the time window since
the last time has expired.*/ the last time has expired.*/
now = chVTGetSystemTimeX(); now = chVTGetSystemTimeX();
delta = now - ch.vtlist.vt_lasttime;
/* The next element is outside the current time window, the loop /* The next element is outside the current time window, the loop
is stopped here.*/ 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 /* Updating the alarm to the next deadline, deadline that must not be
closer in time than the minimum time delta.*/ closer in time than the minimum time delta.*/
delta = (vtp->vt_delta >= (systime_t)CH_CFG_ST_TIMEDELTA) ? systime_t delta = ch.vtlist.vt_lasttime + vtp->vt_delta - now;
vtp->vt_delta : (systime_t)CH_CFG_ST_TIMEDELTA; 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); port_timer_set_alarm(now + delta);
chDbgAssert((chVTGetSystemTimeX() - ch.vtlist.vt_lasttime) < delta, chDbgAssert((chVTGetSystemTimeX() - ch.vtlist.vt_lasttime) < delta,

View File

@ -99,13 +99,18 @@ void chVTDoSetI(virtual_timer_t *vtp, systime_t delay,
chDbgCheckClassI(); chDbgCheckClassI();
chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (delay != TIME_IMMEDIATE)); chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (delay != TIME_IMMEDIATE));
/* systime_t tm = chVTGetSystemTimeX();
if (tm >= 23) {
__BKPT(0);
}*/
vtp->vt_par = par; vtp->vt_par = par;
vtp->vt_func = vtfunc; vtp->vt_func = vtfunc;
p = ch.vtlist.vt_next; 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 /* If the requested delay is lower than the minimum safe delta then it
is raised to the minimum safe value.*/ 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.*/; value in the header must be restored.*/;
p->vt_delta -= delay; p->vt_delta -= delay;
ch.vtlist.vt_delta = (systime_t)-1; 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 * @iclass
*/ */
void chVTDoResetI(virtual_timer_t *vtp) { void chVTDoResetI(virtual_timer_t *vtp) {
#if CH_CFG_ST_TIMEDELTA > 0
virtual_timer_t *first;
#endif
chDbgCheckClassI(); chDbgCheckClassI();
chDbgCheck(vtp != NULL); chDbgCheck(vtp != NULL);
chDbgAssert(vtp->vt_func != NULL, "timer not set or already triggered"); 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.*/ /* Removing the element from the delta list.*/
vtp->vt_next->vt_delta += vtp->vt_delta; vtp->vt_next->vt_delta += vtp->vt_delta;
vtp->vt_prev->vt_next = vtp->vt_next; 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.*/ is the last of the list, restoring it.*/
ch.vtlist.vt_delta = (systime_t)-1; 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) { 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(); port_timer_stop_alarm();
return;
} }
else {
/* Updating the alarm to the next deadline, deadline that must not be /* If the removed element was not the first one then just return, the
closer in time than the minimum time delta.*/ alarm is already set to the first element.*/
if (ch.vtlist.vt_next->vt_delta >= (systime_t)CH_CFG_ST_TIMEDELTA) { if (vtp != first) {
port_timer_set_alarm(ch.vtlist.vt_lasttime + return;
ch.vtlist.vt_next->vt_delta);
}
else {
port_timer_set_alarm(ch.vtlist.vt_lasttime +
(systime_t)CH_CFG_ST_TIMEDELTA);
}
} }
/* 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 */ #endif /* CH_CFG_ST_TIMEDELTA > 0 */
} }