aboutsummaryrefslogtreecommitdiffstats
path: root/ports
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-01-18 13:44:50 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-01-18 13:44:50 +0000
commit48d08ca9476ca38ba936ec7ff5ae3b79d8b02bd2 (patch)
treed4127b3644c8d3aa71498cac3439c82217ded90d /ports
parent140c2d06cdffd63ef06b258064f0065b8ddef140 (diff)
downloadChibiOS-48d08ca9476ca38ba936ec7ff5ae3b79d8b02bd2.tar.gz
ChibiOS-48d08ca9476ca38ba936ec7ff5ae3b79d8b02bd2.tar.bz2
ChibiOS-48d08ca9476ca38ba936ec7ff5ae3b79d8b02bd2.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@634 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'ports')
-rw-r--r--ports/ARM7/chcore.c4
-rw-r--r--ports/ARM7/port.dox5
-rw-r--r--ports/ARMCM3/chcore.c10
-rw-r--r--ports/ARMCM3/chcore.h45
-rw-r--r--ports/ARMCM3/crt0.s21
-rw-r--r--ports/ARMCM3/nvic.c20
-rw-r--r--ports/ARMCM3/nvic.h17
-rw-r--r--ports/ARMCM3/port.dox108
8 files changed, 207 insertions, 23 deletions
diff --git a/ports/ARM7/chcore.c b/ports/ARM7/chcore.c
index d7d51c85b..9ffe94ac5 100644
--- a/ports/ARM7/chcore.c
+++ b/ports/ARM7/chcore.c
@@ -28,14 +28,18 @@
* Prints a message on the system console.
* @param msg pointer to the message
*/
+/** @cond never */
__attribute__((weak))
+/** @endcond */
void port_puts(char *msg) {
}
/**
* Halts the system.
*/
+/** @cond never */
__attribute__((weak))
+/** @endcond */
void port_halt(void) {
port_disable();
diff --git a/ports/ARM7/port.dox b/ports/ARM7/port.dox
index cf3532f96..9a9f319a6 100644
--- a/ports/ARM7/port.dox
+++ b/ports/ARM7/port.dox
@@ -105,7 +105,7 @@
/** @} */
/**
- * @defgroup ARM7CONF Configuration Options
+ * @defgroup ARM7_CONF Configuration Options
* @{
* @brief ARM7 specific configuration options.
* @details The ARM7 port allows some architecture-specific configurations
@@ -133,7 +133,8 @@
* @brief ARM7 specific port code, structures and macros.
*
* @ingroup ARM7
- * @file ports/ARM7/chcore.h Port related structures and macros.
* @file ports/ARM7/chtypes.h Port types.
+ * @file ports/ARM7/chcore.h Port related structures and macros.
+ * @file ports/ARM7/chcore.c Port related code.
*/
/** @} */
diff --git a/ports/ARMCM3/chcore.c b/ports/ARMCM3/chcore.c
index acbc97d9b..3432a6577 100644
--- a/ports/ARMCM3/chcore.c
+++ b/ports/ARMCM3/chcore.c
@@ -32,7 +32,9 @@
* it in your application code.
* @param msg pointer to the message string
*/
+/** @cond never */
__attribute__((weak))
+/** @endcond */
void port_puts(char *msg) {
}
@@ -41,7 +43,9 @@ void port_puts(char *msg) {
* @note The function is declared as a weak symbol, it is possible to redefine
* it in your application code.
*/
+/** @cond never */
__attribute__((weak))
+/** @endcond */
void port_halt(void) {
port_disable();
@@ -53,7 +57,9 @@ void port_halt(void) {
* Start a thread by invoking its work function.
* If the work function returns @p chThdExit() is automatically invoked.
*/
+/** @cond never */
__attribute__((naked, weak))
+/** @endcond */
void threadstart(void) {
asm volatile ("blx r1 \n\t" \
@@ -79,7 +85,9 @@ CH_IRQ_HANDLER void SysTickVector(void) {
/**
* The SVC vector is used for commanded context switch.
*/
+/** @cond never */
__attribute__((naked))
+/** @endcond */
void SVCallVector(Thread *otp, Thread *ntp) {
/* { r0 = otp, r1 = ntp } */
/* get the BASEPRI in r3 */
@@ -146,7 +154,9 @@ void SVCallVector(Thread *otp, Thread *ntp) {
/**
* Preemption invoked context switch.
*/
+/** @cond never */
__attribute__((naked))
+/** @endcond */
void PendSVVector(void) {
Thread *otp;
register struct intctx *sp_thd asm("r12");
diff --git a/ports/ARMCM3/chcore.h b/ports/ARMCM3/chcore.h
index 831e03527..4ac271c79 100644
--- a/ports/ARMCM3/chcore.h
+++ b/ports/ARMCM3/chcore.h
@@ -28,16 +28,51 @@
/*
* Port-related configuration parameters.
*/
+
+/** Enables the use of the WFI ins. */
+#ifndef ENABLE_WFI_IDLE
+#define ENABLE_WFI_IDLE 0
+#endif
+
+/** BASEPRI user level, 0 = disabled. */
#ifndef BASEPRI_USER
-#define BASEPRI_USER 0 /* User level BASEPRI, 0 = disabled. */
+#define BASEPRI_USER 0
#endif
+/**
+ * BASEPRI level within kernel lock.
+ * Priority levels higher than this one (lower values) are unaffected by
+ * the OS activity and can be classified as fast interrupt sources, see
+ * @ref interrupt_classes.
+ */
#ifndef BASEPRI_KERNEL
-#define BASEPRI_KERNEL 0x10 /* BASEPRI level within kernel lock. */
+#define BASEPRI_KERNEL 0x40
#endif
-#ifndef ENABLE_WFI_IDLE
-#define ENABLE_WFI_IDLE 0 /* Enables the use of the WFI ins. */
+/**
+ * SVCALL handler priority.
+ * @note This priority must always be one level above the @p BASEPRI_KERNEL
+ * value.
+ * @note It is recommended to leave this priority level for this handler alone.
+ */
+#ifndef PRIORITY_SVCALL
+#define PRIORITY_SVCALL (BASEPRI_KERNEL - 0x10)
+#endif
+
+/** SYSTICK handler priority. */
+#ifndef PRIORITY_SYSTICK
+#define PRIORITY_SYSTICK 0x80
+#endif
+
+/**
+ * PENDSV handler priority.
+ * @note It is recommended to leave this priority level for this handler alone.
+ * @note This is a reserved handler and its priority must always be the
+ * lowest priority in the system in order to be always executed last
+ * in the interrupt servicing chain.
+ */
+#ifndef PRIORITY_PENDSV
+#define PRIORITY_PENDSV 0xF0
#endif
/**
@@ -233,7 +268,7 @@ typedef struct {
/**
* This port function is implemented as inlined code for performance reasons.
*/
-#define port_switch(otp, ntp) { \
+#define port_switch(otp, ntp) { \
register Thread *_otp asm ("r0") = (otp); \
register Thread *_ntp asm ("r1") = (ntp); \
asm volatile ("svc #0" : : "r" (_otp), "r" (_ntp)); \
diff --git a/ports/ARMCM3/crt0.s b/ports/ARMCM3/crt0.s
index a7ebb59be..d31b36475 100644
--- a/ports/ARMCM3/crt0.s
+++ b/ports/ARMCM3/crt0.s
@@ -37,6 +37,8 @@
.thumb_func
.global ResetHandler
ResetHandler:
+ /* Interrupts globally masked. */
+ cpsid i
/*
* Stack pointers initialization.
*/
@@ -47,9 +49,7 @@ ResetHandler:
msr PSP, r0
// ldr r1, =__process_stack_size__
// sub r0, r0, r1
- /*
- * Early initialization.
- */
+ /* Early initialization. */
bl hwinit0
/*
* Data initialization.
@@ -76,22 +76,13 @@ bloop:
itt lo
strlo r0, [r1], #4
blo bloop
- /*
- * Switches to the Process Stack and disables the interrupts globally.
- */
+ /* Switches to the Process Stack. */
movs r0, #CONTROL_MODE_PRIVILEGED | CONTROL_USE_PSP
msr CONTROL, r0
isb
- movs r0, #0x10
- msr BASEPRI, r0
- cpsie i
- /*
- * Late initialization.
- */
+ /* Late initialization. */
bl hwinit1
- /*
- * main(0, NULL).
- */
+ /* main(0, NULL). */
movs r0, #0
mov r1, r0
bl main
diff --git a/ports/ARMCM3/nvic.c b/ports/ARMCM3/nvic.c
index dbb4935c0..a054ed163 100644
--- a/ports/ARMCM3/nvic.c
+++ b/ports/ARMCM3/nvic.c
@@ -20,9 +20,27 @@
#include <ch.h>
#include <nvic.h>
+/**
+ * Sets the priority of an interrupt handler and enables it.
+ * @param n the interrupt number
+ * @param prio the interrupt priority
+ * @note The parameters are not tested for correctness.
+ */
void NVICEnableVector(uint32_t n, uint32_t prio) {
- int sh = (n & 3) << 3;
+ unsigned sh = (n & 3) << 3;
NVIC_IPR(n >> 2) = (NVIC_IPR(n >> 2) & ~(0xFF << sh)) | (prio << sh);
NVIC_ISER(n >> 5) = 1 << (n & 0x1F);
}
+
+/**
+ * Changes the priority of a system handler.
+ * @param handler the system handler number
+ * @param prio the system handler priority
+ * @note The parameters are not tested for correctness.
+ */
+void NVICSetSystemHandlerPriority(uint32_t handler, uint32_t prio) {
+ unsigned sh = (handler & 3) * 8;
+
+ SCB_SHPR(handler >> 2) = (SCB_SHPR(handler >> 2) & ~(0xFF << sh)) | (prio << sh);
+}
diff --git a/ports/ARMCM3/nvic.h b/ports/ARMCM3/nvic.h
index 13a04fe78..3876410e5 100644
--- a/ports/ARMCM3/nvic.h
+++ b/ports/ARMCM3/nvic.h
@@ -20,6 +20,22 @@
#ifndef _NVIC_H_
#define _NVIC_H_
+/*
+ * System vector constants for @p NVICSetSystemHandlerPriority().
+ */
+#define HANDLER_MEM_MANAGE 0
+#define HANDLER_BUS_FAULT 1
+#define HANDLER_USAGE_FAULT 2
+#define HANDLER_RESERVED_3 3
+#define HANDLER_RESERVED_4 4
+#define HANDLER_RESERVED_5 5
+#define HANDLER_RESERVED_6 6
+#define HANDLER_SVCALL 7
+#define HANDLER_DEBUG_MONITOR 8
+#define HANDLER_RESERVED_9 9
+#define HANDLER_PENDSV 10
+#define HANDLER_SYSTICK 11
+
typedef volatile unsigned char IOREG8;
typedef volatile unsigned int IOREG32;
@@ -132,6 +148,7 @@ typedef struct {
extern "C" {
#endif
void NVICEnableVector(uint32_t n, uint32_t prio);
+ void NVICSetSystemHandlerPriority(uint32_t handler, uint32_t prio);
#ifdef __cplusplus
}
#endif
diff --git a/ports/ARMCM3/port.dox b/ports/ARMCM3/port.dox
new file mode 100644
index 000000000..28372e399
--- /dev/null
+++ b/ports/ARMCM3/port.dox
@@ -0,0 +1,108 @@
+/**
+ * @defgroup ARMCM3 ARM Cortex-M3
+ * @{
+ * @details The ARM Cortex-M3 architecture is quite complex for a
+ * microcontroller and some explanations are required about the port choices.
+ *
+ * @section ARMCM3_STATES Mapping of the System States in the ARM Cortex-M3 port
+ * The ChibiOS/RT logical @ref system_states are mapped as follow in the ARM
+ * Cortex-M3 port:
+ * - <b>Initialization</b>. This state is represented by the startup code and
+ * the initialization code before @p chSysInit() is executed. It has not a
+ * special hardware state associated.
+ * - <b>Normal</b>. This is the state the system has after executing
+ * @p chSysInit(). In this state the ARM Cortex-M3 has the BASEPRI register
+ * set at @p BASEPRI_USER level, interrupts are not masked. The processor
+ * is running in thread-privileged mode.
+ * - <b>Suspended</b>. In this state the interrupt sources are not globally
+ * masked but the BASEPRI register is set to @p BASEPRI_KERNEL thus masking
+ * any interrupt source with lower or equal priority. The processor
+ * is running in thread-privileged mode.
+ * - <b>Disabled</b>. Interrupt sources are globally masked. The processor
+ * is running in thread-privileged mode.
+ * - <b>Sleep</b>. This state is entered with the execution of the specific
+ * instruction @p <b>wfi</b>.
+ * - <b>S-Locked</b>. In this state the interrupt sources are not globally
+ * masked but the BASEPRI register is set to @p BASEPRI_KERNEL thus masking
+ * any interrupt source with lower or equal priority. The processor
+ * is running in thread-privileged mode.
+ * - <b>I-Locked</b>. In this state the interrupt sources are not globally
+ * masked but the BASEPRI register is set to @p BASEPRI_KERNEL thus masking
+ * any interrupt source with lower or equal priority. The processor
+ * is running in exception-privileged mode.
+ * - <b>Serving Regular Interrupt</b>. In this state the interrupt sources are
+ * not globally masked but only interrupts with higher priority can preempt
+ * the current handler. The processor is running in exception-privileged mode.
+ * - <b>Serving Fast Interrupt</b>. It is basically the same of the SRI state
+ * but it is not possible to switch to the I-Locked state because fast
+ * interrupts can preempt the kernel critical zone.
+ * - <b>Serving Non-Maskable Interrupt</b>. The Cortex-M3 has a specific
+ * asynchronous NMI vector and several synchronous fault vectors that can
+ * be considered to be in this category.
+ * - <b>Halted</b>. Implemented as an infinite loop after globally masking all
+ * the maskable interrupt sources. The ARM state is whatever the processor
+ * was running when @p chSysHalt() was invoked.
+ *
+ * @section ARMCM3_NOTES The ARM Cortex-M3 port notes
+ * The ARM Cortex-M3 port is organized as follow:
+ * - The @p main() function is invoked in thread-privileged mode.
+ * - Each thread has a private process stack, the system has a single main
+ * stack where all the interrupts and exceptions are processed.
+ * - Only the 4 MSb of the priority level are used, the 4 LSb are assumed
+ * to be zero.
+ * - The threads are started in thread-privileged mode with BASEPRI level
+ * 0x00 (disabled).
+ * - The kernel raises its BASEPRI level to @p BASEPRI_KERNEL in order to
+ * protect the kernel data structures.
+ * - Interrupt nesting and the other advanced NVIC features are supported.
+ * - The SVC instruction and vector, with parameter #0, is internally used
+ * for commanded context switching.<br>
+ * It is possible to share the SVC handler at the cost of slower context
+ * switching.
+ * - The PendSV vector is internally used for preemption context switching.
+ *
+ * @ingroup Ports
+ */
+/** @} */
+
+/**
+ * @defgroup ARMCM3_CONF Configuration Options
+ * @{
+ * @brief ARM Cortex-M3 Configuration Options.
+ * The ARMCM3 port allows some architecture-specific configurations settings
+ * that can be specified externally, as example on the compiler command line:
+ * - @p INT_REQUIRED_STACK, this value represent the amount of stack space used
+ * by an interrupt handler between the @p extctx and @p intctx
+ * structures.<br>
+ * In the current implementation this value is guaranteed to be zero so
+ * there is no need to modify this value unless changes are done at the
+ * interrupts handling code.
+ * - @p BASEPRI_USER, this is the @p BASEPRI value for the user threads. The
+ * default value is @p 0 (disabled).<br>
+ * Usually there is no need to change this value, please refer to the
+ * Cortex-M3 technical reference manual for a detailed description.
+ * - @p BASEPRI_KERNEL, this is the @p BASEPRI value for the kernel lock code.
+ * The default value is 0x10.<br>
+ * Code running at higher priority levels must not invoke any OS API.<br>
+ * Usually there is no need to change this value, please refer to the
+ * Cortex-M3 technical reference manual for a detailed description.
+ * - @p ENABLE_WFI_IDLE, if set to @p 1 enables the use of the @p <b>wfi</b>
+ * instruction from within the idle loop. This is defaulted to 0 because
+ * it can create problems with some debuggers. Setting this option to 1
+ * reduces the system power requirements.
+ *
+ * @ingroup ARMCM3
+ */
+/** @} */
+
+/**
+ * @defgroup ARMCM3_CORE ARM Cortex-M3 Core Implementation
+ * @{
+ * @brief ARM Cortex-M3 specific port code, structures and macros.
+ *
+ * @ingroup ARMCM3
+ * @file ports/ARMCM3/chtypes.h Port types.
+ * @file ports/ARMCM3/chcore.h Port related structures and macros.
+ * @file ports/ARMCM3/chcore.c Port related code.
+ */
+/** @} */