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

This commit is contained in:
gdisirio 2013-07-21 13:33:06 +00:00
parent 56ca204ed2
commit 6a24f95f53
6 changed files with 102 additions and 16 deletions

View File

@ -41,7 +41,7 @@
* setting also defines the system tick time unit.
*/
#if !defined(CH_CFG_FREQUENCY) || defined(__DOXYGEN__)
#define CH_CFG_FREQUENCY 1000
#define CH_CFG_FREQUENCY 10000
#endif
/**
@ -53,7 +53,7 @@
* this value.
*/
#if !defined(CH_CFG_TIMEDELTA) || defined(__DOXYGEN__)
#define CH_CFG_TIMEDELTA 0
#define CH_CFG_TIMEDELTA 2
#endif
/**

View File

@ -66,8 +66,17 @@ typedef struct {
list. */
virtual_timer_t *vt_prev; /**< @brief Last timer in the delta
list. */
systime_t vt_time; /**< @brief Must be initialized to -1. */
systime_t vt_delta; /**< @brief Must be initialized to -1. */
#if CH_CFG_TIMEDELTA == 0 || defined(__DOXYGEN__)
volatile systime_t vt_systime; /**< @brief System Time counter. */
#endif
#if CH_CFG_TIMEDELTA > 0 || defined(__DOXYGEN__)
/**
* @brief System time of the last tick event.
*/
systime_t vt_lasttime;/**< @brief System time of the last
tick event. */
#endif
} virtual_timers_list_t;
/**
@ -78,7 +87,7 @@ typedef struct {
struct virtual_timer {
virtual_timer_t *vt_next; /**< @brief Next timer in the list. */
virtual_timer_t *vt_prev; /**< @brief Previous timer in the list. */
systime_t vt_time; /**< @brief Time delta before timeout. */
systime_t vt_delta; /**< @brief Time delta before timeout. */
vtfunc_t vt_func; /**< @brief Timer callback function
pointer. */
void *vt_par; /**< @brief Timer callback function
@ -190,7 +199,11 @@ static inline systime_t chVTGetSystemTimeI(void) {
chDbgCheckClassI();
#if CH_CFG_TIMEDELTA == 0
return vtlist.vt_systime;
#else /* CH_CFG_TIMEDELTA > 0 */
return port_timer_get_time();
#endif /* CH_CFG_TIMEDELTA > 0 */
}
/**
@ -352,12 +365,13 @@ static inline void chVTDoTickI(void) {
chDbgCheckClassI();
#if CH_CFG_TIMEDELTA == 0
vtlist.vt_systime++;
if (&vtlist != (virtual_timers_list_t *)vtlist.vt_next) {
virtual_timer_t *vtp;
--vtlist.vt_next->vt_time;
while (!(vtp = vtlist.vt_next)->vt_time) {
--vtlist.vt_next->vt_delta;
while (!(vtp = vtlist.vt_next)->vt_delta) {
vtfunc_t fn = vtp->vt_func;
vtp->vt_func = (vtfunc_t)NULL;
vtp->vt_next->vt_prev = (void *)&vtlist;
@ -367,6 +381,22 @@ static inline void chVTDoTickI(void) {
chSysLockFromIsr();
}
}
#else /* CH_CFG_TIMEDELTA > 0 */
if (&vtlist != (virtual_timers_list_t *)vtlist.vt_next) {
virtual_timer_t *vtp;
--vtlist.vt_next->vt_delta;
while (!(vtp = vtlist.vt_next)->vt_delta) {
vtfunc_t fn = vtp->vt_func;
vtp->vt_func = (vtfunc_t)NULL;
vtp->vt_next->vt_prev = (void *)&vtlist;
vtlist.vt_next = vtp->vt_next;
chSysUnlockFromIsr();
fn(vtp->vt_par);
chSysLockFromIsr();
}
}
#endif /* CH_CFG_TIMEDELTA > 0 */
}
#endif /* _CHVT_H_ */

View File

@ -67,8 +67,12 @@ virtual_timers_list_t vtlist;
void _vt_init(void) {
vtlist.vt_next = vtlist.vt_prev = (void *)&vtlist;
vtlist.vt_time = (systime_t)-1;
vtlist.vt_delta = (systime_t)-1;
#if CH_CFG_TIMEDELTA == 0
vtlist.vt_systime = 0;
#else /* CH_CFG_TIMEDELTA > 0 */
vtlist.vt_lasttime = 0;
#endif /* CH_CFG_TIMEDELTA > 0 */
}
/**
@ -125,16 +129,42 @@ void chVTDoSetI(virtual_timer_t *vtp, systime_t delay,
vtp->vt_par = par;
vtp->vt_func = vtfunc;
p = vtlist.vt_next;
while (p->vt_time < delay) {
delay -= p->vt_time;
p = p->vt_next;
}
#if CH_CFG_TIMEDELTA > 0 || defined(__DOXYGEN__)
{
systime_t now = port_timer_get_time();
/* If the requested delay is lower than the minimum safe delta then it
is raised to the minimum safe value.*/
if (delay < CH_CFG_TIMEDELTA)
delay = CH_CFG_TIMEDELTA;
/* Now the delay is calculated as delta from the last tick interrupt
time.*/
delay += now - vtlist.vt_lasttime;
if (&vtlist != (virtual_timers_list_t *)p)
port_timer_start_alarm(vtlist.vt_lasttime + delay);
else if (delay < p->vt_delta)
port_timer_set_alarm(vtlist.vt_lasttime + delay);
}
#endif /* CH_CFG_TIMEDELTA > 0 */
/* The delta list is scanned in order to find the correct position for
this timer. */
while (p->vt_delta < delay) {
delay -= p->vt_delta;
p = p->vt_next;
}
/* The timer is inserted in the delta list.*/
vtp->vt_prev = (vtp->vt_next = p)->vt_prev;
vtp->vt_prev->vt_next = p->vt_prev = vtp;
vtp->vt_time = delay;
if (p != (void *)&vtlist)
p->vt_time -= delay;
vtp->vt_delta = delay
/* Special case when the timer is in last position in the list, the
value in the header must be restored.*/;
p->vt_delta -= delay;
vtlist.vt_delta = (systime_t)-1;
}
/**
@ -153,11 +183,28 @@ void chVTDoResetI(virtual_timer_t *vtp) {
"chVTDoResetI(), #1",
"timer not set or already triggered");
if (vtp->vt_next != (void *)&vtlist)
vtp->vt_next->vt_time += vtp->vt_time;
/* Removing the element from the delta list.*/
vtp->vt_next->vt_delta += vtp->vt_delta;
vtp->vt_prev->vt_next = vtp->vt_next;
vtp->vt_next->vt_prev = vtp->vt_prev;
vtp->vt_func = (vtfunc_t)NULL;
/* The above code changes the value in the header when the removed element
is the last of the list, restoring it.*/
vtlist.vt_delta = (systime_t)-1;
#if CH_CFG_TIMEDELTA > 0 || defined(__DOXYGEN__)
{
if (&vtlist == (virtual_timers_list_t *)vtlist.vt_next) {
/* Just removed the last element in the list, alarm timer stopped.*/
port_timer_stop_alarm();
}
else {
/* The alarm is set to the next element in the delta list.*/
port_timer_set_alarm(vtlist.vt_lasttime + vtlist.vt_next->vt_delta);
}
}
#endif /* CH_CFG_TIMEDELTA > 0 */
}
/** @} */

View File

@ -1,6 +1,7 @@
# List of the ChibiOS/RT Cortex-M4 STM32 port files.
PORTSRC = $(CHIBIOS)/os/ports/GCC/ARMCMx/crt0.c \
$(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F3xx/vectors.c \
$(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F3xx/chtimer.c \
${CHIBIOS}/os/ports/GCC/ARMCMx/chcore.c \
${CHIBIOS}/os/ports/GCC/ARMCMx/chcore_v7m.c \
${CHIBIOS}/os/ports/common/ARMCMx/nvic.c

View File

@ -32,6 +32,7 @@
/* Port interrupt handlers. */
/*===========================================================================*/
#if CH_CFG_TIMEDELTA == 0
/**
* @brief System Timer vector.
* @details This interrupt is used as system tick.
@ -47,6 +48,7 @@ CH_IRQ_HANDLER(SysTickVector) {
CH_IRQ_EPILOGUE();
}
#endif /* CH_CFG_TIMEDELTA == 0 */
#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
/**
@ -119,8 +121,10 @@ void _port_init(void) {
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL));
nvicSetSystemHandlerPriority(HANDLER_PENDSV,
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV));
#if CH_CFG_TIMEDELTA == 0
nvicSetSystemHandlerPriority(HANDLER_SYSTICK,
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK));
#endif
}
#if !CH_CFG_OPTIMIZE_SPEED

View File

@ -518,6 +518,10 @@ extern "C" {
}
#endif
#if CH_CFG_TIMEDELTA > 0
#include "chtimer.h"
#endif
#endif /* _FROM_ASM_ */
#endif /* _CHCORE_V7M_H_ */