Improved preemption for Cortex-M0 port.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2797 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
gdisirio 2011-03-06 08:02:26 +00:00
parent 645fce5f28
commit 3cc5ac6d9a
4 changed files with 39 additions and 50 deletions

View File

@ -126,7 +126,7 @@ Settings: CLK=48, (2 wait states)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.8 (Benchmark, round robin context switching)
--- Score : 253328 ctxswc/S
--- Score : 253332 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.9 (Benchmark, I/O Queues throughput)

View File

@ -27,11 +27,6 @@
#include "ch.h"
/**
* @brief PC register temporary storage.
*/
regarm_t _port_saved_pc;
/**
* @brief System Timer vector.
* @details This interrupt is used as system tick.
@ -48,40 +43,39 @@ CH_IRQ_HANDLER(SysTickVector) {
CH_IRQ_EPILOGUE();
}
/**
* @brief NMI vector.
* @details The NMI vector is used for exception mode re-entering after a
* context switch.
*/
void NMIVector(void) {
register struct extctx *ctxp;
/* Discarding the current exception context and positioning the stack to
point to the real one.*/
asm volatile ("mrs %0, PSP" : "=r" (ctxp) : : "memory");
ctxp++;
asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory");
port_unlock_from_isr();
}
/**
* @brief Post-IRQ switch code.
* @details On entry the stack and the registers are restored by the exception
* return, the PC value is stored in @p _port_saved_pc, the interrupts
* are disabled.
* @details The switch is performed in thread context then an NMI exception
* is enforced in order to return to the exact point before the
* preemption.
*/
#if !defined(__DOXYGEN__)
__attribute__((naked))
#endif
void _port_switch_from_isr(void) {
/* Note, saves r4 to make space for the PC.*/
asm volatile ("push {r0, r1, r2, r3, r4} \n\t"
"mrs r0, APSR \n\t"
"mov r1, r12 \n\t"
"push {r0, r1, lr} \n\t"
"ldr r0, =_port_saved_pc \n\t"
"ldr r0, [r0] \n\t"
"add r0, r0, #1 \n\t"
"str r0, [sp, #28]" : : : "memory");
chSchDoRescheduleI();
/* Note, the last register is restored alone after re-enabling the
interrupts in order to minimize the (very remote and unlikely)
possibility that the stack is filled by continuous and saturating
interrupts that would not allow that last words to be pulled out of
the stack.*/
asm volatile ("pop {r0, r1, r2} \n\t"
"mov r12, r1 \n\t"
"msr APSR, r0 \n\t"
"mov lr, r2 \n\t"
"pop {r0, r1, r2, r3} \n\t"
"cpsie i \n\t"
"pop {pc}" : : : "memory");
SCB_ICSR = ICSR_NMIPENDSET;
/* The following loop should never be executed, the NMI will kick in
immediately.*/
while (TRUE)
;
}
#define PUSH_CONTEXT(sp) { \

View File

@ -32,10 +32,8 @@
/* Port implementation part. */
/*===========================================================================*/
/**
* @brief Cortex-Mx exception context.
*/
struct cmxctx {
#if !defined(__DOXYGEN__)
struct extctx {
regarm_t r0;
regarm_t r1;
regarm_t r2;
@ -46,18 +44,6 @@ struct cmxctx {
regarm_t xpsr;
};
#if !defined(__DOXYGEN__)
struct extctx {
regarm_t xpsr;
regarm_t r12;
regarm_t lr;
regarm_t r0;
regarm_t r1;
regarm_t r2;
regarm_t r3;
regarm_t pc;
};
struct intctx {
regarm_t r8;
regarm_t r9;
@ -131,11 +117,17 @@ struct intctx {
if (_saved_lr != (regarm_t)0xFFFFFFF1) { \
port_lock_from_isr(); \
if (chSchIsRescRequiredExI()) { \
register struct cmxctx *ctxp; \
register struct extctx *ctxp; \
\
asm volatile ("mrs %0, PSP" : "=r" (ctxp) : ); \
_port_saved_pc = ctxp->pc; \
/* Adding an artificial exception return context, there is no need to \
populate it fully.*/ \
asm volatile ("mrs %0, PSP" : "=r" (ctxp) : : "memory"); \
ctxp--; \
asm volatile ("msr PSP, %0" : : "r" (ctxp) : "memory"); \
ctxp->pc = _port_switch_from_isr; \
ctxp->xpsr = (regarm_t)0x01000000; \
/* Note, returning without unlocking is intentional, this is done in \
order to keep the rest of the context switching atomic.*/ \
return; \
} \
port_unlock_from_isr(); \

View File

@ -84,6 +84,9 @@
2.2.1).
- FIX: Error in MAC driver (bug 3179783)(backported to 2.2.1).
- FIX: Fixed wrong serial driver macros (bug 3173336)(backported to 2.2.1).
- NEW: Inproved preemption implementation for the Cortex-M0, now it uses
the NMI vector in order to restore the original context. The change makes
IRQ handling faster and also saves some RAM/ROM space (backported to 2.2.3).
- NEW: Added "IRQ STORM" long duration tests for the STM32 and LPC11xx. The
test demonstrates the system stability in a thread-intensive, progressively
CPU-saturating, IRQ-intensive long duration test.