1
0
Эх сурвалжийг харах

update cortex-m3 libcpu

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1776 bbd45198-f89e-11dd-88c7-29a3b14d5316
wuyangyong 13 жил өмнө
parent
commit
8c54e1c47b

+ 188 - 0
libcpu/arm/cortex-m3/context_rvds.S

@@ -0,0 +1,188 @@
+;/*
+; * File      : context_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2009, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; * 2009-01-17     Bernard      first version
+; */
+
+;/**
+; * @addtogroup CORTEX-M3
+; */
+;/*@{*/
+
+NVIC_INT_CTRL   EQU     0xE000ED04               ; interrupt control state register
+NVIC_SYSPRI2    EQU     0xE000ED20               ; system priority register (2)
+NVIC_PENDSV_PRI EQU     0x00FF0000               ; PendSV priority value (lowest)
+NVIC_PENDSVSET  EQU     0x10000000               ; value to trigger PendSV exception
+
+    AREA |.text|, CODE, READONLY, ALIGN=2
+    THUMB
+    REQUIRE8
+    PRESERVE8
+
+    IMPORT rt_thread_switch_interrupt_flag
+    IMPORT rt_interrupt_from_thread
+    IMPORT rt_interrupt_to_thread
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+rt_hw_interrupt_disable    PROC
+    EXPORT  rt_hw_interrupt_disable
+    MRS     r0, PRIMASK
+    CPSID   I
+    BX      LR
+    ENDP
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+rt_hw_interrupt_enable    PROC
+    EXPORT  rt_hw_interrupt_enable
+    MSR     PRIMASK, r0
+    BX      LR
+    ENDP
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+rt_hw_context_switch_interrupt
+    EXPORT rt_hw_context_switch_interrupt
+rt_hw_context_switch    PROC
+    EXPORT rt_hw_context_switch
+
+    ; set rt_thread_switch_interrupt_flag to 1
+    LDR     r2, =rt_thread_switch_interrupt_flag
+    LDR     r3, [r2]
+    CMP     r3, #1
+    BEQ     _reswitch
+    MOV     r3, #1
+    STR     r3, [r2]
+
+    LDR     r2, =rt_interrupt_from_thread   ; set rt_interrupt_from_thread
+    STR     r0, [r2]
+
+_reswitch
+    LDR     r2, =rt_interrupt_to_thread     ; set rt_interrupt_to_thread
+    STR     r1, [r2]
+
+    LDR     r0, =NVIC_INT_CTRL              ; trigger the PendSV exception (causes context switch)
+    LDR     r1, =NVIC_PENDSVSET
+    STR     r1, [r0]
+    BX      LR
+    ENDP
+
+; r0 --> swith from thread stack
+; r1 --> swith to thread stack
+; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
+PendSV_Handler   PROC
+    EXPORT PendSV_Handler
+
+    ; disable interrupt to protect context switch
+    MRS     r2, PRIMASK
+    CPSID   I
+
+    ; get rt_thread_switch_interrupt_flag
+    LDR     r0, =rt_thread_switch_interrupt_flag
+    LDR     r1, [r0]
+    CBZ     r1, pendsv_exit         ; pendsv already handled
+
+    ; clear rt_thread_switch_interrupt_flag to 0
+    MOV     r1, #0x00
+    STR     r1, [r0]
+
+    LDR     r0, =rt_interrupt_from_thread
+    LDR     r1, [r0]
+    CBZ     r1, swtich_to_thread    ; skip register save at the first time
+
+    MRS     r1, psp                 ; get from thread stack pointer
+    STMFD   r1!, {r4 - r11}         ; push r4 - r11 register
+    LDR     r0, [r0]
+    STR     r1, [r0]                ; update from thread stack pointer
+
+swtich_to_thread
+    LDR     r1, =rt_interrupt_to_thread
+    LDR     r1, [r1]
+    LDR     r1, [r1]                ; load thread stack pointer
+
+    LDMFD   r1!, {r4 - r11}         ; pop r4 - r11 register
+    MSR     psp, r1                 ; update stack pointer
+
+pendsv_exit
+    ; restore interrupt
+    MSR     PRIMASK, r2
+
+    ORR     lr, lr, #0x04
+    BX      lr
+    ENDP
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; * this fucntion is used to perform the first thread switch
+; */
+rt_hw_context_switch_to    PROC
+    EXPORT rt_hw_context_switch_to
+    ; set to thread
+    LDR     r1, =rt_interrupt_to_thread
+    STR     r0, [r1]
+
+    ; set from thread to 0
+    LDR     r1, =rt_interrupt_from_thread
+    MOV     r0, #0x0
+    STR     r0, [r1]
+
+    ; set interrupt flag to 1
+    LDR     r1, =rt_thread_switch_interrupt_flag
+    MOV     r0, #1
+    STR     r0, [r1]
+
+    ; set the PendSV exception priority
+    LDR     r0, =NVIC_SYSPRI2
+    LDR     r1, =NVIC_PENDSV_PRI
+    LDR.W   r2, [r0,#0x00]       ; read
+    ORR     r1,r1,r2             ; modify
+    STR     r1, [r0]             ; write-back
+
+    ; trigger the PendSV exception (causes context switch)
+    LDR     r0, =NVIC_INT_CTRL
+    LDR     r1, =NVIC_PENDSVSET
+    STR     r1, [r0]
+
+    ; enable interrupts at processor level
+    CPSIE   I
+
+    ; never reach here!
+    ENDP
+
+; compatible with old version
+rt_hw_interrupt_thread_switch PROC
+    EXPORT rt_hw_interrupt_thread_switch
+    BX      lr
+    NOP
+    ENDP
+
+    IMPORT rt_hw_hard_fault_exception
+    EXPORT HardFault_Handler
+HardFault_Handler    PROC
+
+    ; get current context
+    MRS     r0, psp                 ; get fault thread stack pointer
+    PUSH    {lr}
+    BL      rt_hw_hard_fault_exception
+    POP     {lr}
+
+    ORR     lr, lr, #0x04
+    BX      lr
+    ENDP
+
+    END

+ 106 - 106
libcpu/arm/cortex-m3/cpuport.c

@@ -1,106 +1,106 @@
-/******************************************************************//**
- * @file 		cpu.c
- * @brief 	This file is part of RT-Thread RTOS
- * 	COPYRIGHT (C) 2011, RT-Thread Development Team
- * @author 	Bernard, onelife
- * @version 	0.4 beta
- **********************************************************************
- * @section License
- * The license and distribution terms for this file may be found in the file LICENSE in this 
- * distribution or at http://www.rt-thread.org/license/LICENSE
- **********************************************************************
- * @section Change Logs
- * Date			Author		Notes
- * 2009-01-05 	Bernard 		first version
- * 2011-02-14	onelife		Modify for EFM32
- * 2011-06-17	onelife		Merge all of the C source code into cpuport.c
- *********************************************************************/
- 
-/******************************************************************//**
-* @addtogroup cortex-m3
-* @{
-*********************************************************************/
-
-/* Includes -------------------------------------------------------------------*/
-#include <rtthread.h>
-
-/* Private typedef -------------------------------------------------------------*/
-struct stack_contex
-{
-	rt_uint32_t r0;
-	rt_uint32_t r1;
-	rt_uint32_t r2;
-	rt_uint32_t r3;
-	rt_uint32_t r12;
-	rt_uint32_t lr;
-	rt_uint32_t pc;
-	rt_uint32_t psr;
-};
-
-/* Private define --------------------------------------------------------------*/
-/* Private macro --------------------------------------------------------------*/
-/* Private variables ------------------------------------------------------------*/
-/* exception and interrupt handler table */
-rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
-rt_uint32_t rt_thread_switch_interrupt_flag;
-
-/* Private function prototypes ---------------------------------------------------*/
-/* Private functions ------------------------------------------------------------*/
-rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
-	rt_uint8_t *stack_addr, void *texit)
-{
-	unsigned long *stk;
-
-	stk 	 = (unsigned long *)stack_addr;
-	*(stk)   = 0x01000000L;					/* PSR */
-	*(--stk) = (unsigned long)tentry;		/* entry point, pc */
-	*(--stk) = (unsigned long)texit;		/* lr */
-	*(--stk) = 0;							/* r12 */
-	*(--stk) = 0;							/* r3 */
-	*(--stk) = 0;							/* r2 */
-	*(--stk) = 0;							/* r1 */
-	*(--stk) = (unsigned long)parameter;	/* r0 : argument */
-
-	*(--stk) = 0;							/* r11 */
-	*(--stk) = 0;							/* r10 */
-	*(--stk) = 0;							/* r9 */
-	*(--stk) = 0;							/* r8 */
-	*(--stk) = 0;							/* r7 */
-	*(--stk) = 0;							/* r6 */
-	*(--stk) = 0;							/* r5 */
-	*(--stk) = 0;							/* r4 */
-
-	/* return task's current stack address */
-	return (rt_uint8_t *)stk;
-}
-
-extern void list_thread(void);
-extern rt_thread_t rt_current_thread;
-void rt_hw_hard_fault_exception(struct stack_contex* contex)
-{
-	rt_kprintf("psr: 0x%08x\n", contex->psr);
-	rt_kprintf(" pc: 0x%08x\n", contex->pc);
-	rt_kprintf(" lr: 0x%08x\n", contex->lr);
-	rt_kprintf("r12: 0x%08x\n", contex->r12);
-	rt_kprintf("r03: 0x%08x\n", contex->r3);
-	rt_kprintf("r02: 0x%08x\n", contex->r2);
-	rt_kprintf("r01: 0x%08x\n", contex->r1);
-	rt_kprintf("r00: 0x%08x\n", contex->r0);
-
-	rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
-#ifdef RT_USING_FINSH
-	list_thread();
-#endif
-	while (1);
-}
-
-void rt_hw_cpu_shutdown()
-{
-	rt_kprintf("shutdown...\n");
-
-	RT_ASSERT(0);
-}
-
-/******************************************************************//**
- * @}
-*********************************************************************/
+/******************************************************************//**
+ * @file 		cpuport.c
+ * @brief 	This file is part of RT-Thread RTOS
+ * 	COPYRIGHT (C) 2011, RT-Thread Development Team
+ * @author 	Bernard, onelife
+ * @version 	0.4 beta
+ **********************************************************************
+ * @section License
+ * The license and distribution terms for this file may be found in the file LICENSE in this 
+ * distribution or at http://www.rt-thread.org/license/LICENSE
+ **********************************************************************
+ * @section Change Logs
+ * Date			Author		Notes
+ * 2009-01-05 	Bernard 	first version
+ * 2011-02-14	onelife		Modify for EFM32
+ * 2011-06-17	onelife		Merge all of the C source code into cpuport.c
+ *********************************************************************/
+ 
+/******************************************************************//**
+* @addtogroup cortex-m3
+* @{
+*********************************************************************/
+
+/* Includes -------------------------------------------------------------------*/
+#include <rtthread.h>
+
+/* Private typedef -------------------------------------------------------------*/
+struct stack_contex
+{
+	rt_uint32_t r0;
+	rt_uint32_t r1;
+	rt_uint32_t r2;
+	rt_uint32_t r3;
+	rt_uint32_t r12;
+	rt_uint32_t lr;
+	rt_uint32_t pc;
+	rt_uint32_t psr;
+};
+
+/* Private define --------------------------------------------------------------*/
+/* Private macro --------------------------------------------------------------*/
+/* Private variables ------------------------------------------------------------*/
+/* exception and interrupt handler table */
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrupt_flag;
+
+/* Private function prototypes ---------------------------------------------------*/
+/* Private functions ------------------------------------------------------------*/
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+	rt_uint8_t *stack_addr, void *texit)
+{
+	unsigned long *stk;
+
+	stk 	 = (unsigned long *)stack_addr;
+	*(stk)   = 0x01000000L;					/* PSR */
+	*(--stk) = (unsigned long)tentry;		/* entry point, pc */
+	*(--stk) = (unsigned long)texit;		/* lr */
+	*(--stk) = 0;							/* r12 */
+	*(--stk) = 0;							/* r3 */
+	*(--stk) = 0;							/* r2 */
+	*(--stk) = 0;							/* r1 */
+	*(--stk) = (unsigned long)parameter;	/* r0 : argument */
+
+	*(--stk) = 0;							/* r11 */
+	*(--stk) = 0;							/* r10 */
+	*(--stk) = 0;							/* r9 */
+	*(--stk) = 0;							/* r8 */
+	*(--stk) = 0;							/* r7 */
+	*(--stk) = 0;							/* r6 */
+	*(--stk) = 0;							/* r5 */
+	*(--stk) = 0;							/* r4 */
+
+	/* return task's current stack address */
+	return (rt_uint8_t *)stk;
+}
+
+extern void list_thread(void);
+extern rt_thread_t rt_current_thread;
+void rt_hw_hard_fault_exception(struct stack_contex* contex)
+{
+	rt_kprintf("psr: 0x%08x\n", contex->psr);
+	rt_kprintf(" pc: 0x%08x\n", contex->pc);
+	rt_kprintf(" lr: 0x%08x\n", contex->lr);
+	rt_kprintf("r12: 0x%08x\n", contex->r12);
+	rt_kprintf("r03: 0x%08x\n", contex->r3);
+	rt_kprintf("r02: 0x%08x\n", contex->r2);
+	rt_kprintf("r01: 0x%08x\n", contex->r1);
+	rt_kprintf("r00: 0x%08x\n", contex->r0);
+
+	rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
+#ifdef RT_USING_FINSH
+	list_thread();
+#endif
+	while (1);
+}
+
+void rt_hw_cpu_shutdown()
+{
+	rt_kprintf("shutdown...\n");
+
+	RT_ASSERT(0);
+}
+
+/******************************************************************//**
+ * @}
+*********************************************************************/