aboutsummaryrefslogtreecommitdiffstats
path: root/os/rt/ports/ARMCMx/chcore_v6m.h
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2013-08-20 10:09:53 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2013-08-20 10:09:53 +0000
commit2bbf9f1ea0cfb30bf61d189cc8c5f3552b363f01 (patch)
tree770216e8d10de3a908aa6f08fdefe340795be38e /os/rt/ports/ARMCMx/chcore_v6m.h
parent706f6a3967f968ea92fb1eb1b44741245dafd190 (diff)
downloadChibiOS-2bbf9f1ea0cfb30bf61d189cc8c5f3552b363f01.tar.gz
ChibiOS-2bbf9f1ea0cfb30bf61d189cc8c5f3552b363f01.tar.bz2
ChibiOS-2bbf9f1ea0cfb30bf61d189cc8c5f3552b363f01.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6185 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/rt/ports/ARMCMx/chcore_v6m.h')
-rw-r--r--os/rt/ports/ARMCMx/chcore_v6m.h299
1 files changed, 173 insertions, 126 deletions
diff --git a/os/rt/ports/ARMCMx/chcore_v6m.h b/os/rt/ports/ARMCMx/chcore_v6m.h
index be1381e49..d16025640 100644
--- a/os/rt/ports/ARMCMx/chcore_v6m.h
+++ b/os/rt/ports/ARMCMx/chcore_v6m.h
@@ -16,13 +16,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- ---
-
- A special exception to the GPL can be applied should you wish to distribute
- a combined work that includes ChibiOS/RT, without being obliged to provide
- the source code for any proprietary components. See the file exception.txt
- for full details of how and when the exception can be applied.
*/
/**
@@ -37,10 +30,51 @@
#define _CHCORE_V6M_H_
/*===========================================================================*/
-/* Port constants. */
+/* Module constants. */
/*===========================================================================*/
/**
+ * @name Architecture and Compiler
+ * @{
+ */
+#if (CORTEX_MODEL == CORTEX_M0) || defined(__DOXYGEN__)
+/**
+ * @brief Macro defining the specific ARM architecture.
+ */
+#define CH_ARCHITECTURE_ARM_v6M
+
+/**
+ * @brief Name of the implemented architecture.
+ */
+#define CH_ARCHITECTURE_NAME "ARMv6-M"
+
+/**
+ * @brief Name of the architecture variant.
+ */
+#define CH_CORE_VARIANT_NAME "Cortex-M0"
+
+#elif (CORTEX_MODEL == CORTEX_M0PLUS)
+#define CH_ARCHITECTURE_ARM_v6M
+#define CH_ARCHITECTURE_NAME "ARMv6-M"
+#define CH_CORE_VARIANT_NAME "Cortex-M0+"
+#endif
+
+/**
+ * @brief Port-specific information string.
+ */
+#if !CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__)
+#define CH_PORT_INFO "Preemption through NMI"
+#else
+#define CH_PORT_INFO "Preemption through PendSV"
+#endif
+/** @} */
+
+/**
+ * @brief This port does not support a realtime counter.
+ */
+#define CH_PORT_SUPPORTS_RT FALSE
+
+/**
* @brief PendSV priority level.
* @note This priority is enforced to be equal to @p 0,
* this handler always has the highest priority that cannot preempt
@@ -49,11 +83,7 @@
#define CORTEX_PRIORITY_PENDSV 0
/*===========================================================================*/
-/* Port macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Port configurable parameters. */
+/* Module pre-compile time settings. */
/*===========================================================================*/
/**
@@ -65,8 +95,8 @@
* a stack frame when compiling without optimizations. You may
* reduce this value to zero when compiling with optimizations.
*/
-#if !defined(PORT_IDLE_THREAD_STACK_SIZE)
-#define PORT_IDLE_THREAD_STACK_SIZE 16
+#if !defined(CH_PORT_IDLE_THREAD_STACK_SIZE)
+#define CH_PORT_IDLE_THREAD_STACK_SIZE 16
#endif
/**
@@ -78,8 +108,8 @@
* with compiler optimizations disabled. The value can be reduced
* when compiler optimizations are enabled.
*/
-#if !defined(PORT_INT_REQUIRED_STACK)
-#define PORT_INT_REQUIRED_STACK 32
+#if !defined(CH_PORT_INT_REQUIRED_STACK)
+#define CH_PORT_INT_REQUIRED_STACK 32
#endif
/**
@@ -90,18 +120,6 @@
#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 Alternate preemption method.
* @details Activating this option will make the Kernel use the PendSV
* handler for preemption instead of the NMI handler.
@@ -111,7 +129,7 @@
#endif
/*===========================================================================*/
-/* Port derived parameters. */
+/* Derived constants and error checks. */
/*===========================================================================*/
/**
@@ -124,39 +142,7 @@
#endif
/*===========================================================================*/
-/* Port exported info. */
-/*===========================================================================*/
-
-/**
- * @brief Macro defining the specific ARM architecture.
- */
-#define CH_ARCHITECTURE_ARM_v6M
-
-/**
- * @brief Name of the implemented architecture.
- */
-#define CH_ARCHITECTURE_NAME "ARMv6-M"
-
-/**
- * @brief Name of the architecture variant.
- */
-#if (CORTEX_MODEL == CORTEX_M0) || defined(__DOXYGEN__)
-#define CH_CORE_VARIANT_NAME "Cortex-M0"
-#elif (CORTEX_MODEL == CORTEX_M1)
-#define CH_CORE_VARIANT_NAME "Cortex-M1"
-#endif
-
-/**
- * @brief Port-specific information string.
- */
-#if !CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__)
-#define CH_PORT_INFO "Preemption through NMI"
-#else
-#define CH_PORT_INFO "Preemption through PendSV"
-#endif
-
-/*===========================================================================*/
-/* Port implementation part. */
+/* Module data structures and types. */
/*===========================================================================*/
#if !defined(_FROM_ASM_)
@@ -170,7 +156,7 @@ typedef void *regarm_t;
to not have duplicated structure names into the documentation.*/
#if !defined(__DOXYGEN__)
-typedef uint64_t stkalign_t __attribute__ ((aligned (8)));
+typedef uint64_t stkalign_t;
struct extctx {
regarm_t r0;
@@ -198,7 +184,7 @@ struct intctx {
#endif /* !defined(__DOXYGEN__) */
/**
- * @brief Platform dependent part of the @p Thread structure.
+ * @brief Platform dependent part of the @p thread_t structure.
* @details In this port the structure just holds a pointer to the @p intctx
* structure representing the stack pointer at context switch time.
*/
@@ -206,6 +192,10 @@ struct context {
struct intctx *r13;
};
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
/**
* @brief Platform dependent part of the @p chThdCreateI() API.
* @details This code usually setup the context switching frame represented
@@ -228,10 +218,10 @@ struct context {
/**
* @brief Computes the thread working area global size.
*/
-#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
+#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(thread_t) + \
sizeof(struct intctx) + \
sizeof(struct extctx) + \
- (n) + (PORT_INT_REQUIRED_STACK))
+ (n) + (CH_PORT_INT_REQUIRED_STACK))
/**
* @brief Static working area allocation.
@@ -271,62 +261,152 @@ struct context {
#define PORT_FAST_IRQ_HANDLER(id) void id(void)
/**
+ * @brief Performs a context switch between two threads.
+ * @details This is the most critical code in any port, this function
+ * is responsible for the context switch between 2 threads.
+ * @note The implementation of this code affects <b>directly</b> the context
+ * switch performance so optimize here as much as you can.
+ *
+ * @param[in] ntp the thread to be switched in
+ * @param[in] otp the thread to be switched out
+ */
+#if !CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
+#define port_switch(ntp, otp) _port_switch(ntp, otp)
+#else
+#define port_switch(ntp, otp) { \
+ struct intctx *r13 = (struct intctx *)__get_PSP(); \
+ if ((stkalign_t *)(r13 - 1) < otp->p_stklimit) \
+ chSysHalt("stack overflow"); \
+ _port_switch(ntp, otp); \
+}
+#endif
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void port_halt(void);
+ void _port_irq_epilogue(regarm_t lr);
+ void _port_switch_from_isr(void);
+ void _port_exit_from_isr(void);
+ void _port_switch(thread_t *ntp, thread_t *otp);
+ void _port_thread_start(void);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
* @brief Port-related initialization code.
*/
-#define port_init() { \
- SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(0); \
- nvicSetSystemHandlerPriority(HANDLER_PENDSV, \
- CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV)); \
- nvicSetSystemHandlerPriority(HANDLER_SYSTICK, \
- CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); \
+static inline void port_init(void) {
+
+ NVIC_SetPriority(PendSV_IRQn, CORTEX_PRIORITY_PENDSV);
+}
+
+/**
+ * @brief Returns a word encoding the current interrupts status.
+ *
+ * @return The interrupts status.
+ */
+static inline syssts_t port_get_irq_status(void) {
+
+ return __get_PRIMASK();
+}
+
+/**
+ * @brief Checks the interrupt status.
+ *
+ * @param[in] sts the interrupt status word
+ *
+ * @return The interrupt status.
+ * @retvel false the word specified a disabled interrupts status.
+ * @retvel true the word specified an enabled interrupts status.
+ */
+static inline bool port_irq_enabled(syssts_t sts) {
+
+ return (sts & 1) == 0;
+}
+
+/**
+ * @brief Determines the current execution context.
+ *
+ * @return The execution context.
+ * @retval false not running in ISR mode.
+ * @retval true running in ISR mode.
+ */
+static inline bool port_is_isr_context(void) {
+
+ return (bool)((__get_IPSR() & 0x1FF) != 0);
}
/**
* @brief Kernel-lock action.
- * @details Usually this function just disables interrupts but may perform
- * more actions.
+ * @details In this port this function disables interrupts globally.
*/
-#define port_lock() asm volatile ("cpsid i" : : : "memory")
+static inline void port_lock(void) {
+
+ __disable_irq();
+}
/**
* @brief Kernel-unlock action.
- * @details Usually this function just enables interrupts but may perform
- * more actions.
+ * @details In this port this function enables interrupts globally.
*/
-#define port_unlock() asm volatile ("cpsie i" : : : "memory")
+static inline void port_unlock(void) {
+
+ __enable_irq();
+}
/**
* @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.
+ * @details In this port this function disables interrupts globally.
* @note Same as @p port_lock() in this port.
*/
-#define port_lock_from_isr() port_lock()
+static inline void port_lock_from_isr(void) {
+
+ port_lock();
+}
/**
* @brief Kernel-unlock action from an interrupt handler.
- * @details This function is invoked after invoking I-class APIs from interrupt
- * handlers. The implementation is architecture dependent, in its
- * simplest form it is void.
+ * @details In this port this function enables interrupts globally.
* @note Same as @p port_lock() in this port.
*/
-#define port_unlock_from_isr() port_unlock()
+static inline void port_unlock_from_isr(void) {
+
+ port_unlock();
+}
/**
* @brief Disables all the interrupt sources.
*/
-#define port_disable() asm volatile ("cpsid i" : : : "memory")
+static inline void port_disable(void) {
+
+ __disable_irq();
+}
/**
* @brief Disables the interrupt sources below kernel-level priority.
*/
-#define port_suspend() asm volatile ("cpsid i" : : : "memory")
+static inline void port_suspend(void) {
+
+ __disable_irq();
+}
/**
* @brief Enables all the interrupt sources.
*/
-#define port_enable() asm volatile ("cpsie i" : : : "memory")
+static inline void port_enable(void) {
+
+ __enable_irq();
+}
/**
* @brief Enters an architecture-dependent IRQ-waiting mode.
@@ -336,45 +416,12 @@ struct context {
* modes.
* @note Implemented as an inlined @p WFI instruction.
*/
-#if CORTEX_ENABLE_WFI_IDLE || defined(__DOXYGEN__)
-#define port_wait_for_interrupt() asm volatile ("wfi" : : : "memory")
-#else
-#define port_wait_for_interrupt()
-#endif
-
-/**
- * @brief Performs a context switch between two threads.
- * @details This is the most critical code in any port, this function
- * is responsible for the context switch between 2 threads.
- * @note The implementation of this code affects <b>directly</b> the context
- * switch performance so optimize here as much as you can.
- *
- * @param[in] ntp the thread to be switched in
- * @param[in] otp the thread to be switched out
- */
-#if !CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
-#define port_switch(ntp, otp) _port_switch(ntp, otp)
-#else
-#define port_switch(ntp, otp) { \
- register struct intctx *r13 asm ("r13"); \
- if ((stkalign_t *)(r13 - 1) < otp->p_stklimit) \
- chDbgPanic("stack overflow"); \
- _port_switch(ntp, otp); \
-}
-#endif
+static inline void port_wait_for_interrupt(void) {
-#ifdef __cplusplus
-extern "C" {
+#if CORTEX_ENABLE_WFI_IDLE
+ __WFI;
#endif
- void port_halt(void);
- 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
}
-#endif
#endif /* _FROM_ASM_ */