aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--boards/OLIMEX_LPC_P2148/buzzer.c2
-rw-r--r--demos/ARMCM3-STM32F103ZG-FATFS/main.c2
-rw-r--r--docs/reports/SPC563M64-80.txt26
-rw-r--r--os/hal/platforms/STM32/i2c_lld.c2
-rw-r--r--os/hal/src/mmc_spi.c2
-rw-r--r--os/kernel/include/chvt.h88
-rw-r--r--os/kernel/src/chschd.c3
-rw-r--r--os/kernel/src/chvt.c3
-rw-r--r--os/various/evtimer.c9
-rw-r--r--readme.txt3
-rw-r--r--test/test.c4
-rw-r--r--testhal/STM32F1xx/UART/main.c3
-rw-r--r--testhal/STM32F4xx/UART/main.c3
-rw-r--r--testhal/STM32L1xx/UART/main.c3
-rw-r--r--todo.txt4
15 files changed, 111 insertions, 46 deletions
diff --git a/boards/OLIMEX_LPC_P2148/buzzer.c b/boards/OLIMEX_LPC_P2148/buzzer.c
index 39c501e07..8f1137446 100644
--- a/boards/OLIMEX_LPC_P2148/buzzer.c
+++ b/boards/OLIMEX_LPC_P2148/buzzer.c
@@ -69,7 +69,9 @@ void buzzInit(void) {
static void stop(void *p) {
StopCounter((TC *)p);
+ chSysLockFromIsr();
chEvtBroadcastI(&BuzzerSilentEventSource);
+ chSysUnlockFromIsr();
}
/**
diff --git a/demos/ARMCM3-STM32F103ZG-FATFS/main.c b/demos/ARMCM3-STM32F103ZG-FATFS/main.c
index 4181c7004..8199275cd 100644
--- a/demos/ARMCM3-STM32F103ZG-FATFS/main.c
+++ b/demos/ARMCM3-STM32F103ZG-FATFS/main.c
@@ -89,6 +89,7 @@ bool_t sdc_lld_is_write_protected(SDCDriver *sdcp) {
static void tmrfunc(void *p) {
SDCDriver *sdcp = p;
+ chSysLockFromIsr();
if (cnt > 0) {
if (sdcIsCardInserted(sdcp)) {
if (--cnt == 0) {
@@ -105,6 +106,7 @@ static void tmrfunc(void *p) {
}
}
chVTSetI(&tmr, MS2ST(SDC_POLLING_DELAY), tmrfunc, sdcp);
+ chSysUnlockFromIsr();
}
/**
diff --git a/docs/reports/SPC563M64-80.txt b/docs/reports/SPC563M64-80.txt
index d786aa30e..fc754adcc 100644
--- a/docs/reports/SPC563M64-80.txt
+++ b/docs/reports/SPC563M64-80.txt
@@ -5,8 +5,8 @@ Settings: SYSCLK=80
*** ChibiOS/RT test suite
***
-*** Kernel: 2.4.0
-*** Compiled: Jan 17 2012 - 14:35:40
+*** Kernel: 2.5.0
+*** Compiled: Feb 8 2012 - 10:21:46
*** Compiler: GCC 4.4.1
*** Architecture: Power Architecture
*** Core Variant: e200z3
@@ -100,35 +100,35 @@ Settings: SYSCLK=80
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.1 (Benchmark, messages #1)
---- Score : 283160 msgs/S, 566320 ctxswc/S
+--- Score : 278226 msgs/S, 556452 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.2 (Benchmark, messages #2)
---- Score : 226208 msgs/S, 452416 ctxswc/S
+--- Score : 224935 msgs/S, 449870 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.3 (Benchmark, messages #3)
---- Score : 226208 msgs/S, 452416 ctxswc/S
+--- Score : 224935 msgs/S, 449870 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.4 (Benchmark, context switch)
---- Score : 897232 ctxswc/S
+--- Score : 890960 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.5 (Benchmark, threads, full cycle)
---- Score : 180251 threads/S
+--- Score : 178638 threads/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.6 (Benchmark, threads, create only)
---- Score : 261812 threads/S
+--- Score : 255935 threads/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.7 (Benchmark, mass reschedule, 5 threads)
---- Score : 73862 reschedules/S, 443172 ctxswc/S
+--- Score : 73319 reschedules/S, 439914 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.8 (Benchmark, round robin context switching)
---- Score : 614140 ctxswc/S
+--- Score : 609448 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.9 (Benchmark, I/O Queues throughput)
@@ -136,7 +136,7 @@ Settings: SYSCLK=80
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.10 (Benchmark, virtual timers set/reset)
---- Score : 1093664 timers/S
+--- Score : 1094200 timers/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.11 (Benchmark, semaphores wait/signal)
@@ -144,11 +144,11 @@ Settings: SYSCLK=80
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.12 (Benchmark, mutexes lock/unlock)
---- Score : 841236 lock+unlock/S
+--- Score : 841232 lock+unlock/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.13 (Benchmark, RAM footprint)
---- System: 768 bytes
+--- System: 764 bytes
--- Thread: 72 bytes
--- Timer : 20 bytes
--- Semaph: 12 bytes
diff --git a/os/hal/platforms/STM32/i2c_lld.c b/os/hal/platforms/STM32/i2c_lld.c
index 996033da5..7458d9252 100644
--- a/os/hal/platforms/STM32/i2c_lld.c
+++ b/os/hal/platforms/STM32/i2c_lld.c
@@ -167,8 +167,10 @@ static void i2c_lld_safety_timeout(void *p) {
if (i2cp->thread) {
i2c_lld_abort_operation(i2cp);
+ chSysLockFromIsr();
i2cp->thread->p_u.rdymsg = RDY_TIMEOUT;
chSchReadyI(i2cp->thread);
+ chSysUnlockFromIsr();
}
}
diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c
index 8f11355b8..f4bcb51fd 100644
--- a/os/hal/src/mmc_spi.c
+++ b/os/hal/src/mmc_spi.c
@@ -105,6 +105,7 @@ static uint8_t crc7(uint8_t crc, const uint8_t *buffer, size_t len) {
static void tmrfunc(void *p) {
MMCDriver *mmcp = p;
+ chSysLockFromIsr();
if (mmcp->cnt > 0) {
if (mmcp->is_inserted()) {
if (--mmcp->cnt == 0) {
@@ -123,6 +124,7 @@ static void tmrfunc(void *p) {
}
}
chVTSetI(&mmcp->vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
+ chSysUnlockFromIsr();
}
/**
diff --git a/os/kernel/include/chvt.h b/os/kernel/include/chvt.h
index 95fb16408..355f66064 100644
--- a/os/kernel/include/chvt.h
+++ b/os/kernel/include/chvt.h
@@ -55,7 +55,8 @@
*
* @api
*/
-#define MS2ST(msec) ((systime_t)(((((msec) - 1L) * CH_FREQUENCY) / 1000L) + 1L))
+#define MS2ST(msec) ((systime_t)(((((msec) - 1L) * CH_FREQUENCY) / \
+ 1000L) + 1L))
/**
* @brief Microseconds to system ticks.
@@ -67,7 +68,8 @@
*
* @api
*/
-#define US2ST(usec) ((systime_t)(((((usec) - 1L) * CH_FREQUENCY) / 1000000L) + 1L))
+#define US2ST(usec) ((systime_t)(((((usec) - 1L) * CH_FREQUENCY) / \
+ 1000000L) + 1L))
/** @} */
/**
@@ -112,54 +114,100 @@ typedef struct {
volatile systime_t vt_systime; /**< @brief System Time counter. */
} VTList;
-extern VTList vtlist;
-
/**
* @name Macro Functions
* @{
*/
/**
* @brief Virtual timers ticker.
+ * @note The system lock is released before entering the callback and
+ * re-acquired immediately after. It is callback's responsibility
+ * to acquire the lock if needed. This is done in order to reduce
+ * interrupts jitter when many timers are in use.
*
* @iclass
*/
-#define chVTDoTickI() { \
- vtlist.vt_systime++; \
- if (&vtlist != (VTList *)vtlist.vt_next) { \
- VirtualTimer *vtp; \
- \
- --vtlist.vt_next->vt_time; \
- while (!(vtp = vtlist.vt_next)->vt_time) { \
- 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; \
- fn(vtp->vt_par); \
- } \
- } \
+#define chVTDoTickI() { \
+ vtlist.vt_systime++; \
+ if (&vtlist != (VTList *)vtlist.vt_next) { \
+ VirtualTimer *vtp; \
+ \
+ --vtlist.vt_next->vt_time; \
+ while (!(vtp = vtlist.vt_next)->vt_time) { \
+ 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(); \
+ } \
+ } \
}
/**
- * @brief Returns TRUE if the speciified timer is armed.
+ * @brief Returns @p TRUE if the specified timer is armed.
*
* @iclass
*/
#define chVTIsArmedI(vtp) ((vtp)->vt_func != NULL)
/**
+ * @brief Enables a virtual timer.
+ * @note The associated function is invoked from interrupt context.
+ *
+ * @param[out] vtp the @p VirtualTimer structure pointer
+ * @param[in] time the number of ticks before the operation timeouts, the
+ * special values are handled as follow:
+ * - @a TIME_INFINITE is allowed but interpreted as a
+ * normal time specification.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
+ * @param[in] vtfunc the timer callback function. After invoking the
+ * callback the timer is disabled and the structure can
+ * be disposed or reused.
+ * @param[in] par a parameter that will be passed to the callback
+ * function
+ *
+ * @api
+ */
+#define chVTSet(vtp, time, vtfunc, par) { \
+ chSysLock(); \
+ chVTSetI(vtp, time, vtfunc, par); \
+ chSysUnlock(); \
+}
+
+/**
+ * @brief Disables a Virtual Timer.
+ * @note The timer is first checked and disabled only if armed.
+ *
+ * @param[in] vtp the @p VirtualTimer structure pointer
+ *
+ * @api
+ */
+#define chVTReset(vtp) { \
+ chSysLock(); \
+ if (chVTIsArmedI(vtp)) \
+ chVTResetI(vtp); \
+ chSysUnlock(); \
+}
+
+/**
* @brief Current system time.
* @details Returns the number of system ticks since the @p chSysInit()
* invocation.
* @note The counter can reach its maximum and then restart from zero.
* @note This function is designed to work with the @p chThdSleepUntil().
*
- * @return The system time in ticks.r
+ * @return The system time in ticks.
*
* @api
*/
#define chTimeNow() (vtlist.vt_systime)
/** @} */
+extern VTList vtlist;
+
/*
* Virtual Timers APIs.
*/
diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c
index 808e06300..9739a595b 100644
--- a/os/kernel/src/chschd.c
+++ b/os/kernel/src/chschd.c
@@ -127,10 +127,12 @@ void chSchGoSleepS(tstate_t newstate) {
static void wakeup(void *p) {
Thread *tp = (Thread *)p;
+ chSysLockFromIsr();
switch (tp->p_state) {
case THD_STATE_READY:
/* Handling the special case where the thread has been made ready by
another thread with higher priority.*/
+ chSysUnlockFromIsr();
return;
#if CH_USE_SEMAPHORES || CH_USE_QUEUES || \
(CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT)
@@ -151,6 +153,7 @@ static void wakeup(void *p) {
}
tp->p_u.rdymsg = RDY_TIMEOUT;
chSchReadyI(tp);
+ chSysUnlockFromIsr();
}
/**
diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c
index 4869cebef..6389aaf6d 100644
--- a/os/kernel/src/chvt.c
+++ b/os/kernel/src/chvt.c
@@ -49,8 +49,7 @@ void _vt_init(void) {
/**
* @brief Enables a virtual timer.
- * @note The associated function is invoked by an interrupt handler within
- * the I-Locked state, see @ref system_states.
+ * @note The associated function is invoked from interrupt context.
*
* @param[out] vtp the @p VirtualTimer structure pointer
* @param[in] time the number of ticks before the operation timeouts, the
diff --git a/os/various/evtimer.c b/os/various/evtimer.c
index 314e0cc12..fedc5d6e4 100644
--- a/os/various/evtimer.c
+++ b/os/various/evtimer.c
@@ -32,8 +32,10 @@
static void tmrcb(void *p) {
EvTimer *etp = p;
+ chSysLockFromIsr();
chEvtBroadcastI(&etp->et_es);
chVTSetI(&etp->et_vt, etp->et_interval, tmrcb, etp);
+ chSysUnlockFromIsr();
}
/**
@@ -60,12 +62,7 @@ void evtStart(EvTimer *etp) {
*/
void evtStop(EvTimer *etp) {
- chSysLock();
-
- if (chVTIsArmedI(&etp->et_vt))
- chVTResetI(&etp->et_vt);
-
- chSysUnlock();
+ chVTReset(&etp->et_vt);
}
/** @} */
diff --git a/readme.txt b/readme.txt
index c4ac352a4..d757e889c 100644
--- a/readme.txt
+++ b/readme.txt
@@ -93,6 +93,9 @@
- NEW: Revision of the round-robin scheduling, now threads do not lose their
time slice when preempted. Each thread has its own time slices counter.
TODO: Seek optimizations.
+- NEW: Modified the Virtual Timers management, now the callback is invoked
+ not in lock mode. This change reduces the interrupt jitter caused by
+ multiple timers used at same time.
*** 2.3.5 ***
- FIX: Fixed RTC compile problem on STM32F103 (bug 3468445).
diff --git a/test/test.c b/test/test.c
index bce0b5788..55cfdf445 100644
--- a/test/test.c
+++ b/test/test.c
@@ -278,9 +278,7 @@ void test_start_timer(unsigned ms) {
systime_t duration = MS2ST(ms);
test_timer_done = FALSE;
- chSysLock();
- chVTSetI(&vt, duration, tmr, NULL);
- chSysUnlock();
+ chVTSet(&vt, duration, tmr, NULL);
}
/*
diff --git a/testhal/STM32F1xx/UART/main.c b/testhal/STM32F1xx/UART/main.c
index bdc222e35..0d36e2b89 100644
--- a/testhal/STM32F1xx/UART/main.c
+++ b/testhal/STM32F1xx/UART/main.c
@@ -26,7 +26,10 @@ static VirtualTimer vt1, vt2;
static void restart(void *p) {
(void)p;
+
+ chSysLockFromIsr();
uartStartSendI(&UARTD2, 14, "Hello World!\r\n");
+ chSysUnlockFromIsr();
}
static void ledoff(void *p) {
diff --git a/testhal/STM32F4xx/UART/main.c b/testhal/STM32F4xx/UART/main.c
index 377a75934..69aed3c19 100644
--- a/testhal/STM32F4xx/UART/main.c
+++ b/testhal/STM32F4xx/UART/main.c
@@ -26,7 +26,10 @@ static VirtualTimer vt1, vt2;
static void restart(void *p) {
(void)p;
+
+ chSysLockFromIsr();
uartStartSendI(&UARTD2, 14, "Hello World!\r\n");
+ chSysUnlockFromIsr();
}
static void ledoff(void *p) {
diff --git a/testhal/STM32L1xx/UART/main.c b/testhal/STM32L1xx/UART/main.c
index 8bb5ea6d7..65f834672 100644
--- a/testhal/STM32L1xx/UART/main.c
+++ b/testhal/STM32L1xx/UART/main.c
@@ -26,7 +26,10 @@ static VirtualTimer vt1, vt2;
static void restart(void *p) {
(void)p;
+
+ chSysLockFromIsr();
uartStartSendI(&UARTD1, 14, "Hello World!\r\n");
+ chSysUnlockFromIsr();
}
static void ledoff(void *p) {
diff --git a/todo.txt b/todo.txt
index 04ca10f0b..32c58b9b2 100644
--- a/todo.txt
+++ b/todo.txt
@@ -13,8 +13,8 @@ X SDC driver port to STM32F2 and STM32F4.
Within 2.5.x:
* Revision of scheduling strategy for threads at equal priority.
-- Handling of Virtual Timer callbacks out of critical zone.
-- Add normal API (not iclass) variants of the VT functions.
+* Handling of Virtual Timer callbacks out of critical zone.
+* Add normal API (not iclass) variants of the VT functions.
- Add the RTC service inside the kernel and port, remove from HAL.
- Add option to use the RTC counter instead of the systick counter into the
trace buffer.