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

master
gdisirio 2011-12-28 08:56:04 +00:00
parent 9faabcc2d2
commit 978c2e8002
8 changed files with 86 additions and 97 deletions

View File

@ -530,7 +530,7 @@
/* Port-specific settings (override port settings defaulted in chcore.h). */
/*===========================================================================*/
#define CORTEX_USE_FPU FALSE
#define CORTEX_USE_FPU FALSE
#endif /* _CHCONF_H_ */

View File

@ -6,7 +6,7 @@ Settings: SYSCLK=168, ACR=0x705 (5 wait states)
*** ChibiOS/RT test suite
***
*** Kernel: 2.3.5unstable
*** Compiled: Dec 21 2011 - 19:56:38
*** Compiled: Dec 28 2011 - 09:52:16
*** Compiler: GCC 4.6.2
*** Architecture: ARMv7-ME
*** Core Variant: Cortex-M4F
@ -100,51 +100,51 @@ Settings: SYSCLK=168, ACR=0x705 (5 wait states)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.1 (Benchmark, messages #1)
--- Score : 559403 msgs/S, 1118806 ctxswc/S
--- Score : 574777 msgs/S, 1149554 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.2 (Benchmark, messages #2)
--- Score : 476766 msgs/S, 953532 ctxswc/S
--- Score : 493631 msgs/S, 987262 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.3 (Benchmark, messages #3)
--- Score : 476766 msgs/S, 953532 ctxswc/S
--- Score : 493627 msgs/S, 987254 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.4 (Benchmark, context switch)
--- Score : 1639344 ctxswc/S
--- Score : 1655616 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.5 (Benchmark, threads, full cycle)
--- Score : 371295 threads/S
--- Score : 384066 threads/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.6 (Benchmark, threads, create only)
--- Score : 496523 threads/S
--- Score : 510142 threads/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.7 (Benchmark, mass reschedule, 5 threads)
--- Score : 151017 reschedules/S, 906102 ctxswc/S
--- Score : 156416 reschedules/S, 938496 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.8 (Benchmark, round robin context switching)
--- Score : 1018640 ctxswc/S
--- Score : 1070720 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.9 (Benchmark, I/O Queues throughput)
--- Score : 1766624 bytes/S
--- Score : 1804688 bytes/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.10 (Benchmark, virtual timers set/reset)
--- Score : 1997996 timers/S
--- Score : 2124530 timers/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.11 (Benchmark, semaphores wait/signal)
--- Score : 2601996 wait+signal/S
--- Score : 2685380 wait+signal/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.12 (Benchmark, mutexes lock/unlock)
--- Score : 1766624 lock+unlock/S
--- Score : 1885800 lock+unlock/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.13 (Benchmark, RAM footprint)

View File

@ -6,7 +6,7 @@ Settings: SYSCLK=168, ACR=0x705 (5 wait states)
*** ChibiOS/RT test suite
***
*** Kernel: 2.3.5unstable
*** Compiled: Dec 26 2011 - 11:39:07
*** Compiled: Dec 28 2011 - 09:49:36
*** Compiler: GCC 4.6.2
*** Architecture: ARMv7-ME
*** Core Variant: Cortex-M4

View File

@ -205,6 +205,24 @@ struct intctx {};
#endif /* defined(__DOXYGEN__) */
/**
* @brief Excludes the default @p chSchIsPreemptionRequired()implementation.
*/
#define PORT_OPTIMIZED_ISPREEMPTIONREQUIRED
#if (CH_TIME_QUANTUM > 0) || defined(__DOXYGEN__)
/**
* @brief Inlineable version of this kernel function.
*/
#define chSchIsPreemptionRequired() \
(rlist.r_preempt ? firstprio(&rlist.r_queue) > currp->p_prio : \
firstprio(&rlist.r_queue) >= currp->p_prio)
#else /* CH_TIME_QUANTUM == 0 */
#define chSchIsPreemptionRequired() \
(firstprio(&rlist.r_queue) > currp->p_prio)
#endif /* CH_TIME_QUANTUM == 0 */
#endif /* _FROM_ASM_ */
#endif /* _CHCORE_H_ */

View File

@ -87,6 +87,41 @@ void PendSVVector(void) {
/* Port exported functions. */
/*===========================================================================*/
/**
* @brief IRQ epilogue code.
*
* @param[in] lr value of the @p LR register on ISR entry
*/
void _port_irq_epilogue(regarm_t lr) {
if (lr != (regarm_t)0xFFFFFFF1) {
register struct extctx *ctxp;
port_lock_from_isr();
/* 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->xpsr = (regarm_t)0x01000000;
/* The exit sequence is different depending on if a preemption is
required or not.*/
if (chSchIsPreemptionRequired()) {
/* Preemption is required we need to enforce a context switch.*/
ctxp->pc = _port_switch_from_isr;
}
else {
/* Preemption not required, we just need to exit the exception
atomically.*/
ctxp->pc = _port_exit_from_isr;
}
/* Note, returning without unlocking is intentional, this is done in
order to keep the rest of the context switching atomic.*/
}
}
/**
* @brief Post-IRQ switch code.
* @details The switch is performed in thread context then an NMI exception
@ -98,8 +133,8 @@ __attribute__((naked))
#endif
void _port_switch_from_isr(void) {
if (chSchIsPreemptionRequired())
chSchDoReschedule();
chSchDoReschedule();
asm volatile ("_port_exit_from_isr:" : : : "memory");
#if CORTEX_ALTERNATE_SWITCH
SCB_ICSR = ICSR_PENDSVSET;
port_unlock();
@ -112,24 +147,6 @@ void _port_switch_from_isr(void) {
;
}
#define PUSH_CONTEXT(sp) { \
asm volatile ("push {r4, r5, r6, r7, lr} \n\t" \
"mov r4, r8 \n\t" \
"mov r5, r9 \n\t" \
"mov r6, r10 \n\t" \
"mov r7, r11 \n\t" \
"push {r4, r5, r6, r7}" : : : "memory"); \
}
#define POP_CONTEXT(sp) { \
asm volatile ("pop {r4, r5, r6, r7} \n\t" \
"mov r8, r4 \n\t" \
"mov r9, r5 \n\t" \
"mov r10, r6 \n\t" \
"mov r11, r7 \n\t" \
"pop {r4, r5, r6, r7, pc}" : : "r" (sp) : "memory"); \
}
/**
* @brief Performs a context switch between two threads.
* @details This is the most critical code in any port, this function
@ -146,35 +163,22 @@ __attribute__((naked))
void _port_switch(Thread *ntp, Thread *otp) {
register struct intctx *r13 asm ("r13");
PUSH_CONTEXT(r13);
asm volatile ("push {r4, r5, r6, r7, lr} \n\t"
"mov r4, r8 \n\t"
"mov r5, r9 \n\t"
"mov r6, r10 \n\t"
"mov r7, r11 \n\t"
"push {r4, r5, r6, r7}" : : : "memory");
otp->p_ctx.r13 = r13;
r13 = ntp->p_ctx.r13;
POP_CONTEXT(r13);
}
/**
* @brief IRQ epilogue code.
*
* @param[in] lr value of the @p LR register on ISR entry
*/
void _port_irq_epilogue(regarm_t lr) {
if (lr != (regarm_t)0xFFFFFFF1) {
register struct extctx *ctxp;
port_lock_from_isr();
/* 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.*/
}
asm volatile ("pop {r4, r5, r6, r7} \n\t"
"mov r8, r4 \n\t"
"mov r9, r5 \n\t"
"mov r10, r6 \n\t"
"mov r11, r7 \n\t"
"pop {r4, r5, r6, r7, pc}" : : "r" (sp) : "memory");
}
/**

View File

@ -349,30 +349,14 @@ struct context {
}
#endif
/**
* @brief Excludes the default @p chSchIsPreemptionRequired()implementation.
*/
#define PORT_OPTIMIZED_ISPREEMPTIONREQUIRED
#if (CH_TIME_QUANTUM > 0) || defined(__DOXYGEN__)
/**
* @brief Inlineable version of this kernel function.
*/
#define chSchIsPreemptionRequired() \
(rlist.r_preempt ? firstprio(&rlist.r_queue) > currp->p_prio : \
firstprio(&rlist.r_queue) >= currp->p_prio)
#else /* CH_TIME_QUANTUM == 0 */
#define chSchIsPreemptionRequired() \
(firstprio(&rlist.r_queue) > currp->p_prio)
#endif /* CH_TIME_QUANTUM == 0 */
#ifdef __cplusplus
extern "C" {
#endif
void port_halt(void);
void _port_switch(Thread *ntp, Thread *otp);
void _port_irq_epilogue(regarm_t lr);
void _port_switch_from_isr(void);
void _port_exit_from_isr(void);
void _port_switch(Thread *ntp, Thread *otp);
void _port_thread_start(void);
#ifdef __cplusplus
}

View File

@ -188,7 +188,6 @@ void _port_irq_epilogue(void) {
else {
/* Preemption not required, we just need to exit the exception
atomically.*/
void _port_exit_from_isr(void);
ctxp->pc = _port_exit_from_isr;
}

View File

@ -486,31 +486,15 @@ struct context {
}
#endif
/**
* @brief Excludes the default @p chSchIsPreemptionRequired()implementation.
*/
#define PORT_OPTIMIZED_ISPREEMPTIONREQUIRED
#if (CH_TIME_QUANTUM > 0) || defined(__DOXYGEN__)
/**
* @brief Inlineable version of this kernel function.
*/
#define chSchIsPreemptionRequired() \
(rlist.r_preempt ? firstprio(&rlist.r_queue) > currp->p_prio : \
firstprio(&rlist.r_queue) >= currp->p_prio)
#else /* CH_TIME_QUANTUM == 0 */
#define chSchIsPreemptionRequired() \
(firstprio(&rlist.r_queue) > currp->p_prio)
#endif /* CH_TIME_QUANTUM == 0 */
#ifdef __cplusplus
extern "C" {
#endif
void port_halt(void);
void _port_init(void);
void _port_switch(Thread *ntp, Thread *otp);
void _port_irq_epilogue(void);
void _port_switch_from_isr(void);
void _port_exit_from_isr(void);
void _port_switch(Thread *ntp, Thread *otp);
void _port_thread_start(void);
#if !CH_OPTIMIZE_SPEED
void _port_lock(void);