aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-01-08 12:09:18 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-01-08 12:09:18 +0000
commiteb665ad2407a28c57a6d5802b3bcfa474b8c6e3f (patch)
treeb937607d434f1cb1461b41d7c1cca4cff3a959d8 /os
parent7dc2098ccdebe3b2f54f1c9a60d3355bf0d59489 (diff)
downloadChibiOS-eb665ad2407a28c57a6d5802b3bcfa474b8c6e3f.tar.gz
ChibiOS-eb665ad2407a28c57a6d5802b3bcfa474b8c6e3f.tar.bz2
ChibiOS-eb665ad2407a28c57a6d5802b3bcfa474b8c6e3f.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2615 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/hal/platforms/LPC11xx/hal_lld.h10
-rw-r--r--os/hal/platforms/LPC11xx/spi_lld.c28
-rw-r--r--os/hal/platforms/LPC11xx/spi_lld.h6
-rw-r--r--os/ports/IAR/ARMCMx/chcore_v6m.c90
-rw-r--r--os/ports/IAR/ARMCMx/chcore_v6m.h17
-rw-r--r--os/ports/IAR/ARMCMx/chcore_v7m.h2
-rw-r--r--os/ports/IAR/ARMCMx/chcoreasm_v6m.s134
7 files changed, 178 insertions, 109 deletions
diff --git a/os/hal/platforms/LPC11xx/hal_lld.h b/os/hal/platforms/LPC11xx/hal_lld.h
index 1d9941ba3..f94b058fd 100644
--- a/os/hal/platforms/LPC11xx/hal_lld.h
+++ b/os/hal/platforms/LPC11xx/hal_lld.h
@@ -101,7 +101,7 @@
/*===========================================================================*/
/**
- * @brief Calculated SYSOSCCTRL setting.
+ * @brief Calculated SYSOSCCTRL setting.
*/
#if (SYSOSCCLK < 18000000) || defined(__DOXYGEN__)
#define LPC11xx_SYSOSCCTRL 0
@@ -110,7 +110,7 @@
#endif
/**
- * @brief PLL input clock frequency.
+ * @brief PLL input clock frequency.
*/
#if (LPC11xx_PLLCLK_SOURCE == SYSPLLCLKSEL_SYSOSC) || defined(__DOXYGEN__)
#define LPC11xx_SYSPLLCLKIN SYSOSCCLK
@@ -131,7 +131,7 @@
#endif
/**
- * @brief PSEL mask in SYSPLLCTRL register.
+ * @brief PSEL mask in SYSPLLCTRL register.
*/
#if (LPC11xx_SYSPLL_DIV == 2) || defined(__DOXYGEN__)
#define LPC11xx_SYSPLLCTRL_PSEL (0 << 5)
@@ -146,7 +146,7 @@
#endif
/**
- * @brief CCP frequency.
+ * @brief CCP frequency.
*/
#define LPC11xx_SYSPLLCCO (LPC11xx_SYSPLLCLKIN * LPC11xx_SYSPLL_MUL * \
LPC11xx_SYSPLL_DIV)
@@ -181,7 +181,7 @@
#endif
/**
- * @brief Flash wait states.
+ * @brief Flash wait states.
*/
#if (LPC11xx_SYSCLK <= 20000000) || defined(__DOXYGEN__)
#define LPC11xx_FLASHCFG_FLASHTIM 0
diff --git a/os/hal/platforms/LPC11xx/spi_lld.c b/os/hal/platforms/LPC11xx/spi_lld.c
index 8c826cf9e..47766088c 100644
--- a/os/hal/platforms/LPC11xx/spi_lld.c
+++ b/os/hal/platforms/LPC11xx/spi_lld.c
@@ -64,10 +64,16 @@ static void ssp_fifo_preload(SPIDriver *spip) {
while(((ssp->SR & SR_TNF) != 0) && (n > 0)) {
if (spip->spd_txptr != NULL) {
- if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT)
- ssp->DR = *(uint16_t *)spip->spd_txptr++;
- else
- ssp->DR = *(uint8_t *)spip->spd_txptr++;
+ if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
+ const uint16_t *p = spip->spd_txptr;
+ ssp->DR = *p++;
+ spip->spd_txptr = p;
+ }
+ else {
+ const uint8_t *p = spip->spd_txptr;
+ ssp->DR = *p++;
+ spip->spd_txptr = p;
+ }
}
else
ssp->DR = 0xFFFFFFFF;
@@ -92,10 +98,16 @@ static void spi_serve_interrupt(SPIDriver *spip) {
ssp->ICR = ICR_RT | ICR_ROR;
while ((ssp->SR & SR_RNE) != 0) {
if (spip->spd_rxptr != NULL) {
- if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT)
- *(uint16_t *)spip->spd_rxptr++ = ssp->DR;
- else
- *(uint8_t *)spip->spd_rxptr++ = ssp->DR;
+ if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
+ uint16_t *p = spip->spd_rxptr;
+ *p++ = ssp->DR;
+ spip->spd_rxptr = p;
+ }
+ else {
+ uint8_t *p = spip->spd_rxptr;
+ *p++ = ssp->DR;
+ spip->spd_rxptr = p;
+ }
}
else
(void)ssp->DR;
diff --git a/os/hal/platforms/LPC11xx/spi_lld.h b/os/hal/platforms/LPC11xx/spi_lld.h
index 7b6374172..e0525387a 100644
--- a/os/hal/platforms/LPC11xx/spi_lld.h
+++ b/os/hal/platforms/LPC11xx/spi_lld.h
@@ -35,7 +35,7 @@
/*===========================================================================*/
/**
- * @brief Hardware FIFO depth.
+ * @brief Hardware FIFO depth.
*/
#define LPC11xx_SSP_FIFO_DEPTH 8
@@ -163,7 +163,7 @@
#endif
/**
- * @brief SCK0 signal selector.
+ * @brief SCK0 signal selector.
*/
#if !defined(LPC11xx_SPI_SCK0_SELECTOR) || defined(__DOXYGEN__)
#define LPC11xx_SPI_SCK0_SELECTOR SCK0_IS_PIO2_11
@@ -284,7 +284,7 @@ struct SPIDriver {
*/
LPC_SSP_TypeDef *spd_ssp;
/**
- * @brief Number of bytes yet to be received.
+ * @brief Number of bytes yet to be received.
*/
uint32_t spd_rxcnt;
/**
diff --git a/os/ports/IAR/ARMCMx/chcore_v6m.c b/os/ports/IAR/ARMCMx/chcore_v6m.c
index 4c8ab0646..25b360809 100644
--- a/os/ports/IAR/ARMCMx/chcore_v6m.c
+++ b/os/ports/IAR/ARMCMx/chcore_v6m.c
@@ -53,94 +53,4 @@ CH_IRQ_HANDLER(SysTickVector) {
CH_IRQ_EPILOGUE();
}
-/**
- * @brief Post-IRQ switch code.
- * @details On entry the stack and the registers are restored by the exception
- * return, the PC value is stored in @p _port_saved_pc, the interrupts
- * are disabled.
- */
-void _port_switch_from_irq(void) {
- /* Note, saves r4 to make space for the PC.*/
- asm ("push {r0, r1, r2, r3, r4} \n\t"
- "mrs r0, APSR \n\t"
- "mov r1, r12 \n\t"
- "push {r0, r1, lr} \n\t"
- "ldr r0, =_port_saved_pc \n\t"
- "ldr r0, [r0] \n\t"
- "add r0, r0, #1 \n\t"
- "str r0, [sp, #28]");
-
- chSchDoRescheduleI();
-
- /* Note, the last registers are restored alone after re-enabling the
- interrupts in order to minimize the (very remote and unlikely)
- possibility that the stack is filled by continuous and saturating
- interrupts that would not allow that last words to be pulled out of
- the stack.*/
- asm ("pop {r0, r1, r2} \n\t"
- "mov r12, r1 \n\t"
- "msr APSR, r0 \n\t"
- "mov lr, r2 \n\t"
- "cpsie i \n\t"
- "pop {r0, r1, r2, r3, pc}");
-}
-
-#define PUSH_CONTEXT(sp) { \
- asm ("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}"); \
-}
-
-#define POP_CONTEXT(sp) { \
- asm ("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}"); \
-}
-
-/**
- * @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
- */
-void port_switch(Thread *ntp, Thread *otp) {
-
- /* Stack overflow check, if enabled.*/
-#if CH_DBG_ENABLE_STACK_CHECK
- if ((void *)(r13 - 1) < (void *)(otp + 1))
- asm volatile ("movs r0, #0 \n\t"
- "b chDbgPanic");
-#endif /* CH_DBG_ENABLE_STACK_CHECK */
-
- PUSH_CONTEXT(r13);
-
- asm ("str sp, [r1, #12] \n\t"
- "ldr sp, [r0, #12]");
-
- POP_CONTEXT(r13);
-}
-
-/**
- * @brief Start a thread by invoking its work function.
- * @details If the work function returns @p chThdExit() is automatically
- * invoked.
- */
-void _port_thread_start(void) {
-
- port_unlock();
- asm ("mov r0, r5 \n\t"
- "blx r4 \n\t"
- "bl chThdExit");
-}
-
/** @} */
diff --git a/os/ports/IAR/ARMCMx/chcore_v6m.h b/os/ports/IAR/ARMCMx/chcore_v6m.h
index 3c1189ce6..fe6c68a92 100644
--- a/os/ports/IAR/ARMCMx/chcore_v6m.h
+++ b/os/ports/IAR/ARMCMx/chcore_v6m.h
@@ -216,6 +216,18 @@ struct intctx {
#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
+ */
+#define port_switch(ntp, otp) _port_switch(ntp, otp)
+
#if !defined(__DOXYGEN__)
extern regarm_t _port_saved_pc;
extern unsigned _port_irq_nesting;
@@ -225,8 +237,9 @@ extern unsigned _port_irq_nesting;
extern "C" {
#endif
void port_halt(void);
- void port_switch(Thread *ntp, Thread *otp);
- void _port_switch_from_irq(void);
+ void _port_switch(Thread *ntp, Thread *otp);
+ void _port_irq_epilogue(void);
+ void _port_switch_from_isr(void);
void _port_thread_start(void);
#ifdef __cplusplus
}
diff --git a/os/ports/IAR/ARMCMx/chcore_v7m.h b/os/ports/IAR/ARMCMx/chcore_v7m.h
index 7f7112d45..ba0c83f5a 100644
--- a/os/ports/IAR/ARMCMx/chcore_v7m.h
+++ b/os/ports/IAR/ARMCMx/chcore_v7m.h
@@ -225,7 +225,7 @@ struct intctx {
* @param[in] ntp the thread to be switched in
* @param[in] otp the thread to be switched out
*/
-#define port_switch(ntp, otp) _port_switch(ntp, otp)
+#define port_switch(ntp, otp) _port_switch(ntp, otp)
#ifdef __cplusplus
extern "C" {
diff --git a/os/ports/IAR/ARMCMx/chcoreasm_v6m.s b/os/ports/IAR/ARMCMx/chcoreasm_v6m.s
new file mode 100644
index 000000000..c9ee6a0c8
--- /dev/null
+++ b/os/ports/IAR/ARMCMx/chcoreasm_v6m.s
@@ -0,0 +1,134 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+ MODULE ?chcoreasm_v6m
+
+ AAPCS INTERWORK, VFP_COMPATIBLE
+ PRESERVE8
+
+/*
+ * Imports the Cortex-Mx parameters header and performs the same calculations
+ * done in chcore.h.
+ */
+#include "cmparams.h"
+
+#define CORTEX_PRIORITY_MASK(n) ((n) << (8 - CORTEX_PRIORITY_BITS))
+
+#ifndef CORTEX_PRIORITY_SVCALL
+#define CORTEX_PRIORITY_SVCALL 1
+#endif
+
+EXTCTX_SIZE SET 32
+CONTEXT_OFFSET SET 12
+
+ SECTION .text:CODE:NOROOT(2)
+
+ EXTERN chThdExit
+ EXTERN chSchIsRescRequiredExI
+ EXTERN chSchDoRescheduleI
+ EXTERN _port_saved_pc
+ EXTERN _port_irq_nesting
+
+ THUMB
+
+/*
+ * Performs a context switch between two threads.
+ */
+ PUBLIC _port_switch
+_port_switch:
+ push {r4, r5, r6, r7, lr}
+ mov r4, r8
+ mov r5, r9
+ mov r6, r10
+ mov r7, r11
+ push {r4, r5, r6, r7}
+ mov r3, sp
+ str r3, [r1, #CONTEXT_OFFSET]
+ ldr r3, [r0, #CONTEXT_OFFSET]
+ mov sp, r3
+ pop {r4, r5, r6, r7}
+ mov r8, r4
+ mov r9, r5
+ mov r10, r6
+ mov r11, r7
+ pop {r4, r5, r6, r7, pc}
+
+/*
+ * Start a thread by invoking its work function.
+ * If the work function returns @p chThdExit() is automatically invoked.
+ */
+ PUBLIC _port_thread_start
+_port_thread_start:
+ cpsie i
+ mov r0, r5
+ blx r4
+ bl chThdExit
+
+/*
+ * Post-IRQ switch code.
+ * Exception handlers return here for context switching.
+ */
+ PUBLIC _port_switch_from_isr
+_port_switch_from_isr:
+ /* Note, saves r4 to make space for the PC.*/
+ push {r0, r1, r2, r3, r4}
+ mrs r0, APSR
+ mov r1, r12
+ push {r0, r1, lr}
+ ldr r0, =_port_saved_pc
+ ldr r0, [r0]
+ adds r0, r0, #1
+ str r0, [sp, #28]
+ bl chSchDoRescheduleI
+ pop {r0, r1, r2}
+ mov r12, r1
+ msr APSR, r0
+ mov lr, r2
+ cpsie i
+ pop {r0, r1, r2, r3, pc}
+
+/*
+ * Reschedule verification and setup after an IRQ.
+ */
+ PUBLIC _port_irq_epilogue
+_port_irq_epilogue:
+ push {r4, lr}
+ cpsid i
+ ldr r2, =_port_irq_nesting
+ ldr r3, [r2]
+ subs r3, r3, #1
+ str r3, [r2]
+ cmp r3, #0
+ beq .L34
+ cpsie i
+ pop {r4, pc}
+.L34:
+ bl chSchIsRescRequiredExI
+ cmp r0, #0
+ beq .L31
+ mrs r1, PSP
+ ldr r2, =_port_saved_pc
+ ldr r3, [r1, #24]
+ str r3, [r2]
+ ldr r3, =_port_switch_from_isr
+ str r3, [r1, #24]
+.L31:
+ pop {r4, pc}
+
+ END