Tickless mode fixed hopefully.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7837 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
246b79ae4a
commit
2ec209bdfa
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
# Compiler options here.
|
# Compiler options here.
|
||||||
ifeq ($(USE_OPT),)
|
ifeq ($(USE_OPT),)
|
||||||
USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16
|
USE_OPT = -O2 -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).
|
||||||
|
|
|
@ -35,31 +35,6 @@ 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.
|
||||||
*/
|
*/
|
||||||
|
@ -95,12 +70,5 @@ int main(void) {
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
if (palReadPad(GPIOA, GPIOA_BUTTON))
|
if (palReadPad(GPIOA, GPIOA_BUTTON))
|
||||||
TestThread(&SD2);
|
TestThread(&SD2);
|
||||||
chVTSet(&vt1, 7, cb1, NULL);
|
|
||||||
chThdSleep(5);
|
|
||||||
chSysLock();
|
|
||||||
if (!chVTIsArmedI(&vt2))
|
|
||||||
chVTDoSetI(&vt2, 13, cb2, NULL);
|
|
||||||
chSysUnlock();
|
|
||||||
// chVTReset(&vt1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
105
os/rt/src/chvt.c
105
os/rt/src/chvt.c
|
@ -162,21 +162,17 @@ 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");
|
||||||
|
|
||||||
/* Checking if the element to be removed was the first in the list.*/
|
#if CH_CFG_ST_TIMEDELTA == 0
|
||||||
#if CH_CFG_ST_TIMEDELTA > 0
|
|
||||||
first = ch.vtlist.vt_next;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Removing the element from the delta list.*/
|
/* The delta of the timer is added to the next timer.*/
|
||||||
vtp->vt_next->vt_delta += vtp->vt_delta;
|
vtp->vt_next->vt_delta += vtp->vt_delta;
|
||||||
|
|
||||||
|
/* Removing the element from the delta list.*/
|
||||||
vtp->vt_prev->vt_next = vtp->vt_next;
|
vtp->vt_prev->vt_next = vtp->vt_next;
|
||||||
vtp->vt_next->vt_prev = vtp->vt_prev;
|
vtp->vt_next->vt_prev = vtp->vt_prev;
|
||||||
vtp->vt_func = NULL;
|
vtp->vt_func = NULL;
|
||||||
|
@ -184,50 +180,63 @@ void chVTDoResetI(virtual_timer_t *vtp) {
|
||||||
/* The above code changes the value in the header when the removed element
|
/* The above code changes the value in the header when the removed element
|
||||||
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;
|
||||||
|
#else /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||||
|
systime_t nowdelta, delta;
|
||||||
|
|
||||||
#if CH_CFG_ST_TIMEDELTA > 0
|
/* If the timer is not the first of the list then it is simply unlinked
|
||||||
{
|
else the operation is more complex.*/
|
||||||
systime_t nowdelta, delta;
|
if (ch.vtlist.vt_next != vtp) {
|
||||||
|
/* Removing the element from the delta list.*/
|
||||||
|
vtp->vt_prev->vt_next = vtp->vt_next;
|
||||||
|
vtp->vt_next->vt_prev = vtp->vt_prev;
|
||||||
|
vtp->vt_func = NULL;
|
||||||
|
|
||||||
/* Just removed the last element in the list, alarm timer stopped and
|
/* The above code can change the value in the header when the removed
|
||||||
return.*/
|
element is the last of the list, restoring it.*/
|
||||||
if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.vt_next) {
|
ch.vtlist.vt_delta = (systime_t)-1;
|
||||||
port_timer_stop_alarm();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the removed element was not the first one then just return, the
|
return;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Removing the first timer from the list.*/
|
||||||
|
ch.vtlist.vt_next = vtp->vt_next;
|
||||||
|
ch.vtlist.vt_next->vt_prev = (virtual_timer_t *)&ch.vtlist;
|
||||||
|
|
||||||
|
/* If the list become empty then the alarm timer is stopped and done.*/
|
||||||
|
if (&ch.vtlist == (virtual_timers_list_t *)ch.vtlist.vt_next) {
|
||||||
|
port_timer_stop_alarm();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The delta of the removed timer is added to the new first timer.*/
|
||||||
|
ch.vtlist.vt_next->vt_delta += vtp->vt_delta;
|
||||||
|
|
||||||
|
/* If the new first timer 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);
|
||||||
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
|
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue