Keil CM4 FPU support added.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3675 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
gdisirio 2011-12-28 13:15:23 +00:00
parent 740abb96c0
commit 3afa9b188f
8 changed files with 399 additions and 197 deletions

View File

@ -204,7 +204,7 @@
<hadIRAM>1</hadIRAM>
<hadXRAM>0</hadXRAM>
<uocXRam>0</uocXRam>
<RvdsVP>1</RvdsVP>
<RvdsVP>2</RvdsVP>
<hadIRAM2>1</hadIRAM2>
<hadIROM2>0</hadIROM2>
<StupSel>8</StupSel>
@ -346,7 +346,7 @@
<MiscControls></MiscControls>
<Define>__heap_base__=Image$$RW_IRAM1$$ZI$$Limit __heap_end__=Image$$RW_IRAM2$$Base</Define>
<Undefine></Undefine>
<IncludePath>..\;..\..\..\os\kernel\include;..\..\..\os\ports\RVCT\ARMCMx;..\..\..\os\ports\RVCT\ARMCMx\STM32F4xx;..\..\..\os\hal\include;..\..\..\os\hal\platforms\STM32;..\..\..\os\hal\platforms\STM32\GPIOv2;..\..\..\os\hal\platforms\STM32F4xx;..\..\..\boards\ST_STM32F4_DISCOVERY;..\..\..\test</IncludePath>
<IncludePath>..\;..\..\..\os\kernel\include;..\..\..\os\ports\common\ARMCMx;..\..\..\os\ports\common\ARMCMx\CMSIS\include;..\..\..\os\ports\RVCT\ARMCMx;..\..\..\os\ports\RVCT\ARMCMx\STM32F4xx;..\..\..\os\hal\include;..\..\..\os\hal\platforms\STM32;..\..\..\os\hal\platforms\STM32\GPIOv2;..\..\..\os\hal\platforms\STM32F4xx;..\..\..\boards\ST_STM32F4_DISCOVERY;..\..\..\test</IncludePath>
</VariousControls>
</Cads>
<Aads>
@ -421,11 +421,6 @@
<FileType>1</FileType>
<FilePath>..\..\..\os\ports\RVCT\ARMCMx\chcore_v7m.c</FilePath>
</File>
<File>
<FileName>nvic.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\..\os\ports\RVCT\ARMCMx\nvic.c</FilePath>
</File>
<File>
<FileName>chcore.h</FileName>
<FileType>5</FileType>
@ -441,11 +436,6 @@
<FileType>5</FileType>
<FilePath>..\..\..\os\ports\RVCT\ARMCMx\chtypes.h</FilePath>
</File>
<File>
<FileName>nvic.h</FileName>
<FileType>5</FileType>
<FilePath>..\..\..\os\ports\RVCT\ARMCMx\nvic.h</FilePath>
</File>
<File>
<FileName>cmparams.h</FileName>
<FileType>5</FileType>
@ -456,6 +446,16 @@
<FileType>2</FileType>
<FilePath>..\..\..\os\ports\RVCT\ARMCMx\STM32F4xx\vectors.s</FilePath>
</File>
<File>
<FileName>nvic.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\..\os\ports\common\ARMCMx\nvic.c</FilePath>
</File>
<File>
<FileName>nvic.h</FileName>
<FileType>5</FileType>
<FilePath>..\..\..\os\ports\common\ARMCMx\nvic.h</FilePath>
</File>
</Files>
</Group>
<Group>

View File

@ -6,8 +6,8 @@ Compiler: RealView C/C++ Compiler V4.1.0.791 [Evaluation].
*** ChibiOS/RT test suite
***
*** Kernel: 2.3.4unstable
*** Compiled: Nov 26 2011 - 22:18:53
*** Kernel: 2.3.5unstable
*** Compiled: Dec 28 2011 - 13:36:15
*** Compiler: RVCT
*** Architecture: ARMv7-ME
*** Core Variant: Cortex-M4
@ -101,51 +101,51 @@ Compiler: RealView C/C++ Compiler V4.1.0.791 [Evaluation].
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.1 (Benchmark, messages #1)
--- Score : 711240 msgs/S, 1422480 ctxswc/S
--- Score : 711270 msgs/S, 1422540 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.2 (Benchmark, messages #2)
--- Score : 610371 msgs/S, 1220742 ctxswc/S
--- Score : 610399 msgs/S, 1220798 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.3 (Benchmark, messages #3)
--- Score : 610371 msgs/S, 1220742 ctxswc/S
--- Score : 610399 msgs/S, 1220798 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.4 (Benchmark, context switch)
--- Score : 2376704 ctxswc/S
--- Score : 2393744 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.5 (Benchmark, threads, full cycle)
--- Score : 448805 threads/S
--- Score : 447628 threads/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.6 (Benchmark, threads, create only)
--- Score : 640666 threads/S
--- Score : 638254 threads/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.7 (Benchmark, mass reschedule, 5 threads)
--- Score : 205448 reschedules/S, 1232688 ctxswc/S
--- Score : 205457 reschedules/S, 1232742 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.8 (Benchmark, round robin context switching)
--- Score : 1434640 ctxswc/S
--- Score : 1434680 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.9 (Benchmark, I/O Queues throughput)
--- Score : 1724868 bytes/S
--- Score : 1724960 bytes/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.10 (Benchmark, virtual timers set/reset)
--- Score : 2223216 timers/S
--- Score : 2223332 timers/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.11 (Benchmark, semaphores wait/signal)
--- Score : 3197168 wait+signal/S
--- Score : 3197328 wait+signal/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.12 (Benchmark, mutexes lock/unlock)
--- Score : 1929332 lock+unlock/S
--- Score : 1929428 lock+unlock/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.13 (Benchmark, RAM footprint)

View File

@ -53,7 +53,7 @@
#if (CORTEX_MODEL == CORTEX_M0) || (CORTEX_MODEL == CORTEX_M3) || \
(CORTEX_MODEL == CORTEX_M4)
#elif (CORTEX_MODEL == CORTEX_M1)
#warning "untested Cortex-M model"
#error "untested Cortex-M model"
#else
#error "unknown or unsupported Cortex-M model"
#endif
@ -105,7 +105,7 @@
* a stack frame when compiling without optimizations. You may
* reduce this value to zero when compiling with optimizations.
*/
#ifndef PORT_IDLE_THREAD_STACK_SIZE
#if !defined(PORT_IDLE_THREAD_STACK_SIZE)
#define PORT_IDLE_THREAD_STACK_SIZE 16
#endif
@ -120,14 +120,14 @@
* @p chSchDoReschedule() can have a stack frame, expecially with
* compiler optimizations disabled.
*/
#ifndef PORT_INT_REQUIRED_STACK
#if !defined(PORT_INT_REQUIRED_STACK)
#define PORT_INT_REQUIRED_STACK 16
#endif
/**
* @brief Enables the use of the WFI instruction in the idle thread loop.
*/
#ifndef CORTEX_ENABLE_WFI_IDLE
#if !defined(CORTEX_ENABLE_WFI_IDLE)
#define CORTEX_ENABLE_WFI_IDLE FALSE
#endif
@ -136,25 +136,12 @@
* @note The default SYSTICK handler priority is calculated as the priority
* level in the middle of the numeric priorities range.
*/
#ifndef CORTEX_PRIORITY_SYSTICK
#if !defined(CORTEX_PRIORITY_SYSTICK)
#define CORTEX_PRIORITY_SYSTICK (CORTEX_PRIORITY_LEVELS >> 1)
#else
#elif !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SYSTICK)
/* If it is externally redefined then better perform a validity check on it.*/
#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SYSTICK)
#error "invalid priority level specified for CORTEX_PRIORITY_SYSTICK"
#endif
#endif
/**
* @brief Stack alignment enforcement.
* @note The default value is 64 in order to comply with EABI, reducing
* the value to 32 can save some RAM space if you don't care about
* binary compatibility with EABI compiled libraries.
* @note Allowed values are 32 or 64.
*/
#ifndef CORTEX_STACK_ALIGNMENT
#define CORTEX_STACK_ALIGNMENT 64
#endif
/*===========================================================================*/
/* Port derived parameters (common). */
@ -189,86 +176,51 @@
#include "nvic.h"
/* The following declarations are there just for Doxygen documentation, the
real declarations are inside the sub-headers.*/
#if defined(__DOXYGEN__)
/**
* @brief Stack and memory alignment enforcement.
* @note In this architecture the stack alignment is enforced to 64 bits,
* 32 bits alignment is supported by hardware but deprecated by ARM,
* the implementation choice is to not offer the option.
*/
#if (CORTEX_STACK_ALIGNMENT == 64) || defined(__DOXYGEN__)
#if defined(__DOXYGEN__)
/* Dummy declaration, for Doxygen only.*/
typedef uint64_t stkalign_t;
#else
typedef uint64_t stkalign_t __attribute__ ((aligned (8)));
#endif
#elif CORTEX_STACK_ALIGNMENT == 32
typedef uint32_t stkalign_t __attribute__ ((aligned (4)));
#else
#error "invalid stack alignment selected"
#endif
#if defined(__DOXYGEN__)
/**
* @brief Interrupt saved context.
* @details This structure represents the stack frame saved during a
* preemption-capable interrupt handler.
* @note It is implemented to match the Cortex-Mx exception context.
*/
struct extctx {
/* Dummy definition, just for Doxygen.*/
};
struct extctx {};
/**
* @brief System saved context.
* @details This structure represents the inner stack frame during a context
* switching.
*/
struct intctx {
/* Dummy definition, just for Doxygen.*/
};
#endif
struct intctx {};
#endif /* defined(__DOXYGEN__) */
/**
* @brief Platform dependent part of the @p Thread structure.
* @details In this port the structure just holds a pointer to the @p intctx
* structure representing the stack pointer at context switch time.
* @brief Excludes the default @p chSchIsPreemptionRequired()implementation.
*/
struct context {
struct intctx *r13;
};
#define PORT_OPTIMIZED_ISPREEMPTIONREQUIRED
#if (CH_TIME_QUANTUM > 0) || defined(__DOXYGEN__)
/**
* @brief Platform dependent part of the @p chThdCreateI() API.
* @details This code usually setup the context switching frame represented
* by an @p intctx structure.
* @brief Inlineable version of this kernel function.
*/
#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
wsize - \
sizeof(struct intctx)); \
tp->p_ctx.r13->r4 = (void *)pf; \
tp->p_ctx.r13->r5 = (void *)arg; \
tp->p_ctx.r13->lr = (void *)_port_thread_start; \
}
/**
* @brief Enforces a correct alignment for a stack area size value.
*/
#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
/**
* @brief Computes the thread working area global size.
*/
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
sizeof(struct intctx) + \
sizeof(struct extctx) + \
(n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
* @details This macro is used to allocate a static thread working area
* aligned as both position and size.
*/
#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]
#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_ */

View File

@ -28,6 +28,10 @@
#include "ch.h"
/*===========================================================================*/
/* Port interrupt handlers. */
/*===========================================================================*/
/**
* @brief System Timer vector.
* @details This interrupt is used as system tick.
@ -44,4 +48,158 @@ CH_IRQ_HANDLER(SysTickVector) {
CH_IRQ_EPILOGUE();
}
#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
/**
* @brief SVC vector.
* @details The SVC vector is used for exception mode re-entering after a
* context switch.
* @note The PendSV vector is only used in advanced kernel mode.
*/
void SVCallVector(void) {
struct extctx *ctxp;
register uint32_t psp __asm("psp");
/* Current PSP value.*/
ctxp = (struct extctx *)psp;
/* Discarding the current exception context and positioning the stack to
point to the real one.*/
ctxp++;
#if CORTEX_USE_FPU
/* Restoring the special register SCB_FPCCR.*/
SCB_FPCCR = (uint32_t)ctxp->fpccr;
SCB_FPCAR = SCB_FPCAR + sizeof (struct extctx);
#endif
psp = (uint32_t)ctxp;
port_unlock_from_isr();
}
#endif /* !CORTEX_SIMPLIFIED_PRIORITY */
#if CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__)
/**
* @brief PendSV vector.
* @details The PendSV vector is used for exception mode re-entering after a
* context switch.
* @note The PendSV vector is only used in compact kernel mode.
*/
void PendSVVector(void) {
struct extctx *ctxp;
register uint32_t psp __asm("psp");
/* Current PSP value.*/
ctxp = (struct extctx *)psp;
/* Discarding the current exception context and positioning the stack to
point to the real one.*/
ctxp++;
#if CORTEX_USE_FPU
/* Restoring the special register SCB_FPCCR.*/
SCB_FPCCR = (uint32_t)ctxp->fpccr;
SCB_FPCAR = SCB_FPCAR + sizeof (struct extctx);
#endif
psp = (uint32_t)ctxp;
}
#endif /* CORTEX_SIMPLIFIED_PRIORITY */
/*===========================================================================*/
/* Port exported functions. */
/*===========================================================================*/
/**
* @brief Port-related initialization code.
*/
void _port_init(void) {
/* Initialization of the vector table and priority related settings.*/
SCB_VTOR = CORTEX_VTOR_INIT;
SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0);
#if CORTEX_USE_FPU
{
register uint32_t control __asm("control");
register uint32_t fpscr __asm("fpscr");
/* Initializing the FPU context save in lazy mode.*/
SCB_FPCCR = FPCCR_ASPEN | FPCCR_LSPEN;
/* CP10 and CP11 set to full access in the startup code.*/
/* SCB_CPACR |= 0x00F00000;*/
/* Enables FPU context save/restore on exception entry/exit (FPCA bit).*/
control |= 4;
/* FPSCR and FPDSCR initially zero.*/
fpscr = 0;
SCB_FPDSCR = 0;
}
#endif
/* Initialization of the system vectors used by the port.*/
nvicSetSystemHandlerPriority(HANDLER_SVCALL,
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL));
nvicSetSystemHandlerPriority(HANDLER_PENDSV,
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV));
nvicSetSystemHandlerPriority(HANDLER_SYSTICK,
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK));
}
/**
* @brief Exception exit redirection to _port_switch_from_isr().
*/
void _port_irq_epilogue(void) {
port_lock_from_isr();
if ((SCB_ICSR & ICSR_RETTOBASE) != 0) {
struct extctx *ctxp;
register uint32_t psp __asm("psp");
/* Current PSP value.*/
ctxp = (struct extctx *)psp;
/* Adding an artificial exception return context, there is no need to
populate it fully.*/
ctxp--;
psp = (uint32_t)ctxp;
ctxp->xpsr = (regarm_t)0x01000000;
/* The exit sequence is different depending on if a preemption is
required or not.*/
if (chSchIsPreemptionRequired()) {
#if CORTEX_USE_FPU
/* Triggering a lazy FPU state save.*/
register volatile uint32_t fpscr __asm("fpscr");
(void)fpscr;
#endif
/* Preemption is required we need to enforce a context switch.*/
ctxp->pc = (regarm_t)_port_switch_from_isr;
}
else {
/* Preemption not required, we just need to exit the exception
atomically.*/
ctxp->pc = (regarm_t)_port_exit_from_isr;
}
#if CORTEX_USE_FPU
{
uint32_t fpccr;
/* Saving the special register SCB_FPCCR into the reserved offset of
the Cortex-M4 exception frame.*/
(ctxp + 1)->fpccr = (regarm_t)(fpccr = SCB_FPCCR);
/* Now the FPCCR is modified in order to not restore the FPU status
from the artificial return context.*/
SCB_FPCCR = fpccr | FPCCR_LSPACT;
}
#endif
/* 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

@ -38,15 +38,78 @@
*/
#define CORTEX_BASEPRI_DISABLED 0
/*===========================================================================*/
/* Port macros. */
/*===========================================================================*/
/*===========================================================================*/
/* Port configurable parameters. */
/*===========================================================================*/
/**
* @brief Simplified priority handling flag.
* @details Activating this option will make the Kernel work in compact mode.
* @brief Stack size for the system idle thread.
* @details This size depends on the idle thread implementation, usually
* the idle thread should take no more space than those reserved
* by @p PORT_INT_REQUIRED_STACK.
* @note In this port it is set to 16 because the idle thread does have
* a stack frame when compiling without optimizations. You may
* reduce this value to zero when compiling with optimizations.
*/
#ifndef CORTEX_SIMPLIFIED_PRIORITY
#if !defined(PORT_IDLE_THREAD_STACK_SIZE)
#define PORT_IDLE_THREAD_STACK_SIZE 16
#endif
/**
* @brief Per-thread stack overhead for interrupts servicing.
* @details This constant is used in the calculation of the correct working
* area size.
* This value can be zero on those architecture where there is a
* separate interrupt stack and the stack space between @p intctx and
* @p extctx is known to be zero.
* @note In this port it is conservatively set to 16 because the function
* @p chSchDoReschedule() can have a stack frame, expecially with
* compiler optimizations disabled.
*/
#if !defined(PORT_INT_REQUIRED_STACK)
#define PORT_INT_REQUIRED_STACK 16
#endif
/**
* @brief Enables the use of the WFI instruction in the idle thread loop.
*/
#if !defined(CORTEX_ENABLE_WFI_IDLE)
#define CORTEX_ENABLE_WFI_IDLE FALSE
#endif
/**
* @brief SYSTICK handler priority.
* @note The default SYSTICK handler priority is calculated as the priority
* level in the middle of the numeric priorities range.
*/
#if !defined(CORTEX_PRIORITY_SYSTICK)
#define CORTEX_PRIORITY_SYSTICK (CORTEX_PRIORITY_LEVELS >> 1)
#elif !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SYSTICK)
/* If it is externally redefined then better perform a validity check on it.*/
#error "invalid priority level specified for CORTEX_PRIORITY_SYSTICK"
#endif
/**
* @brief FPU support in context switch.
* @details Activating this option activates the FPU support in the kernel.
*/
#if !defined(CORTEX_USE_FPU)
#define CORTEX_USE_FPU CORTEX_HAS_FPU
#elif CORTEX_USE_FPU && !CORTEX_HAS_FPU
/* This setting requires an FPU presence check in case it is externally
redefined.*/
#error "the selected core does not have an FPU"
#endif
/**
* @brief Simplified priority handling flag.
* @details Activating this option makes the Kernel work in compact mode.
*/
#if !defined(CORTEX_SIMPLIFIED_PRIORITY)
#define CORTEX_SIMPLIFIED_PRIORITY FALSE
#endif
@ -57,14 +120,12 @@
* @p CORTEX_MAXIMUM_PRIORITY priority level as fast interrupts
* priority level.
*/
#ifndef CORTEX_PRIORITY_SVCALL
#if !defined(CORTEX_PRIORITY_SVCALL)
#define CORTEX_PRIORITY_SVCALL (CORTEX_MAXIMUM_PRIORITY + 1)
#else
#elif !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SVCALL)
/* If it is externally redefined then better perform a validity check on it.*/
#if !CORTEX_IS_VALID_PRIORITY(CORTEX_PRIORITY_SVCALL)
#error "invalid priority level specified for CORTEX_PRIORITY_SVCALL"
#endif
#endif
/**
* @brief NVIC VTOR initialization expression.
@ -119,8 +180,12 @@
#elif (CORTEX_MODEL == CORTEX_M4)
#define CH_ARCHITECTURE_ARM_v7ME
#define CH_ARCHITECTURE_NAME "ARMv7-ME"
#if CORTEX_USE_FPU
#define CH_CORE_VARIANT_NAME "Cortex-M4F"
#else
#define CH_CORE_VARIANT_NAME "Cortex-M4"
#endif
#endif
/**
* @brief Port-specific information string.
@ -142,7 +207,18 @@
*/
typedef void *regarm_t;
/**
* @brief Stack and memory alignment enforcement.
* @note In this architecture the stack alignment is enforced to 64 bits,
* 32 bits alignment is supported by hardware but deprecated by ARM,
* the implementation choice is to not offer the option.
*/
typedef uint64_t stkalign_t;
/* The documentation of the following declarations is in chconf.h in order
to not have duplicated structure names into the documentation.*/
#if !defined(__DOXYGEN__)
struct extctx {
regarm_t r0;
regarm_t r1;
@ -152,9 +228,47 @@ struct extctx {
regarm_t lr_thd;
regarm_t pc;
regarm_t xpsr;
#if CORTEX_USE_FPU
regarm_t s0;
regarm_t s1;
regarm_t s2;
regarm_t s3;
regarm_t s4;
regarm_t s5;
regarm_t s6;
regarm_t s7;
regarm_t s8;
regarm_t s9;
regarm_t s10;
regarm_t s11;
regarm_t s12;
regarm_t s13;
regarm_t s14;
regarm_t s15;
regarm_t fpscr;
regarm_t fpccr;
#endif /* CORTEX_USE_FPU */
};
struct intctx {
#if CORTEX_USE_FPU
regarm_t s16;
regarm_t s17;
regarm_t s18;
regarm_t s19;
regarm_t s20;
regarm_t s21;
regarm_t s22;
regarm_t s23;
regarm_t s24;
regarm_t s25;
regarm_t s26;
regarm_t s27;
regarm_t s28;
regarm_t s29;
regarm_t s30;
regarm_t s31;
#endif /* CORTEX_USE_FPU */
regarm_t r4;
regarm_t r5;
regarm_t r6;
@ -165,7 +279,51 @@ struct intctx {
regarm_t r11;
regarm_t lr;
};
#endif
#endif /* !defined(__DOXYGEN__) */
/**
* @brief Platform dependent part of the @p Thread structure.
* @details In this port the structure just holds a pointer to the @p intctx
* structure representing the stack pointer at context switch time.
*/
struct context {
struct intctx *r13;
};
/**
* @brief Platform dependent part of the @p chThdCreateI() API.
* @details This code usually setup the context switching frame represented
* by an @p intctx structure.
*/
#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
wsize - \
sizeof(struct intctx)); \
tp->p_ctx.r13->r4 = (regarm_t)pf; \
tp->p_ctx.r13->r5 = (regarm_t)arg; \
tp->p_ctx.r13->lr = (regarm_t)_port_thread_start; \
}
/**
* @brief Enforces a correct alignment for a stack area size value.
*/
#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
/**
* @brief Computes the thread working area global size.
*/
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
sizeof(struct intctx) + \
sizeof(struct extctx) + \
(n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
* @details This macro is used to allocate a static thread working area
* aligned as both position and size.
*/
#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]
/**
* @brief IRQ prologue code.
@ -198,16 +356,7 @@ struct intctx {
/**
* @brief Port-related initialization code.
*/
#define port_init() { \
SCB_VTOR = CORTEX_VTOR_INIT; \
SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0); \
nvicSetSystemHandlerPriority(HANDLER_SVCALL, \
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL)); \
nvicSetSystemHandlerPriority(HANDLER_PENDSV, \
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV)); \
nvicSetSystemHandlerPriority(HANDLER_SYSTICK, \
CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); \
}
#define port_init() _port_init()
/**
* @brief Kernel-lock action.
@ -242,7 +391,6 @@ struct intctx {
/**
* @brief Kernel-lock action from an interrupt handler.
* @details This function is invoked before invoking I-class APIs from
* interrupt handlers. The implementation is architecture dependent,
* in its simplest form it is void.
* @note Same as @p port_lock() in this port.
@ -333,9 +481,11 @@ struct intctx {
extern "C" {
#endif
void port_halt(void);
void _port_switch(Thread *ntp, Thread *otp);
void _port_init(void);
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);
#ifdef __cplusplus
}

View File

@ -25,10 +25,8 @@
#include "chconf.h"
#include "chcore.h"
EXTCTX_SIZE EQU 32
CONTEXT_OFFSET EQU 12
SCB_ICSR EQU 0xE000ED04
ICSR_RETTOBASE EQU 0x00000800
ICSR_PENDSVSET EQU 0x10000000
PRESERVE8
@ -36,7 +34,6 @@ ICSR_PENDSVSET EQU 0x10000000
AREA |.text|, CODE, READONLY
IMPORT chThdExit
IMPORT chSchIsPreemptionRequired
IMPORT chSchDoReschedule
#if CH_DBG_SYSTEM_STATE_CHECK
IMPORT dbg_check_unlock
@ -49,8 +46,14 @@ ICSR_PENDSVSET EQU 0x10000000
EXPORT _port_switch
_port_switch PROC
push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
#if CORTEX_USE_FPU
vpush {s16-s31}
#endif
str sp, [r1, #CONTEXT_OFFSET]
ldr sp, [r0, #CONTEXT_OFFSET]
#if CORTEX_USE_FPU
vpop {s16-s31}
#endif
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
ENDP
@ -79,17 +82,16 @@ _port_thread_start PROC
* Exception handlers return here for context switching.
*/
EXPORT _port_switch_from_isr
EXPORT _port_exit_from_isr
_port_switch_from_isr PROC
#if CH_DBG_SYSTEM_STATE_CHECK
bl dbg_check_lock
#endif
bl chSchIsPreemptionRequired
cbz r0, noreschedule
bl chSchDoReschedule
noreschedule
#if CH_DBG_SYSTEM_STATE_CHECK
bl dbg_check_unlock
#endif
_port_exit_from_isr
#if CORTEX_SIMPLIFIED_PRIORITY
mov r3, #SCB_ICSR :AND: 0xFFFF
movt r3, #SCB_ICSR :SHR: 16
@ -102,72 +104,4 @@ waithere b waithere
#endif
ENDP
/*
* Reschedule verification and setup after an IRQ.
*/
EXPORT _port_irq_epilogue
_port_irq_epilogue PROC
#if CORTEX_SIMPLIFIED_PRIORITY
cpsid i
#else
movs r3, #CORTEX_BASEPRI_KERNEL
msr BASEPRI, r3
#endif
mov r3, #SCB_ICSR :AND: 0xFFFF
movt r3, #SCB_ICSR :SHR: 16
ldr r3, [r3, #0]
ands r3, r3, #ICSR_RETTOBASE
bne skipexit
#if CORTEX_SIMPLIFIED_PRIORITY
cpsie i
#else
/* Note, R3 is already zero.*/
msr BASEPRI, r3
#endif
bx lr
skipexit
mrs r3, PSP
subs r3, r3, #EXTCTX_SIZE
msr PSP, r3
ldr r2, =_port_switch_from_isr
str r2, [r3, #24]
mov r2, #0x01000000
str r2, [r3, #28]
bx lr
ENDP
/*
* SVC vector.
* Discarding the current exception context and positioning the stack to
* point to the real one.
*/
#if !CORTEX_SIMPLIFIED_PRIORITY
EXPORT SVCallVector
SVCallVector PROC
mrs r3, PSP
adds r3, r3, #EXTCTX_SIZE
msr PSP, r3
movs r3, #CORTEX_BASEPRI_DISABLED
msr BASEPRI, r3
bx lr
nop
ENDP
#endif
/*
* PendSV vector.
* Discarding the current exception context and positioning the stack to
* point to the real one.
*/
#if CORTEX_SIMPLIFIED_PRIORITY
EXPORT PendSVVector
PendSVVector PROC
mrs r3, PSP
adds r3, r3, #EXTCTX_SIZE
msr PSP, r3
bx lr
nop
ENDP
#endif
END

View File

@ -75,6 +75,14 @@ Reset_Handler PROC
msr CONTROL, r0
isb
bl __early_init
IF {CPU} = "Cortex-M4.fp"
LDR R0, =0xE000ED88 ; Enable CP10,CP11
LDR R1, [R0]
ORR R1, R1, #(0xF << 20)
STR R1, [R0]
ENDIF
ldr r0, =__main
bx r0
ENDP

View File

@ -87,7 +87,7 @@
- NEW: Added a linker script that demonstrates how to put stacks and other
critical structures in the CCM RAM instead normal RAM.
- NEW: Added experimental support for the Cortex-M4 FPU (default when the
FPU is present).
FPU is present but can be disabled).
- NEW: Improved I2C driver model and STM32 implementation by Barthess.
- CHANGE: Removed the option to change the stack alignment in the GCC
Cortex-Mx ports, now alignment is always 64 bits.