git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3668 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
9faabcc2d2
commit
978c2e8002
|
@ -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_ */
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue