浏览代码

update lm3s context switch code according to stm32 context switch code.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@194 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 15 年之前
父节点
当前提交
729a0f4516
共有 5 个文件被更改,包括 60 次插入109 次删除
  1. 55 60
      libcpu/arm/lm3s/context_rvds.S
  2. 1 1
      libcpu/arm/lm3s/fault.c
  3. 4 2
      libcpu/arm/lm3s/fault_rvds.S
  4. 0 4
      libcpu/arm/lm3s/interrupt.c
  5. 0 42
      libcpu/arm/lm3s/kservice.c

+ 55 - 60
libcpu/arm/lm3s/context_rvds.S

@@ -19,7 +19,7 @@
 
 NVIC_INT_CTRL   EQU     0xE000ED04               ; interrupt control state register
 NVIC_SYSPRI2    EQU     0xE000ED20               ; system priority register (2)
-NVIC_PENDSV_PRI EQU     0x00000000               ; PendSV priority value (lowest)
+NVIC_PENDSV_PRI EQU     0x00FF0000               ; PendSV priority value (lowest)
 NVIC_PENDSVSET  EQU     0x10000000               ; value to trigger PendSV exception
 
 	AREA |.text|, CODE, READONLY, ALIGN=2
@@ -55,18 +55,29 @@ rt_hw_interrupt_enable    PROC
 ; * 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
-	LDR		r2, =rt_interrupt_from_thread
+
+	; set rt_thread_switch_interrput_flag to 1
+	LDR 	r2, =rt_thread_switch_interrput_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]
 	
-	LDR		r2, =rt_interrupt_to_thread
+_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
+	LDR     r0, =NVIC_INT_CTRL      ; trigger the PendSV exception (causes context switch)
+	LDR     r1, =NVIC_PENDSVSET
 	STR     r1, [r0]
-	CPSIE   I                       ; enable interrupts at processor level
 	BX      LR
 	ENDP
 
@@ -75,6 +86,20 @@ rt_hw_context_switch    PROC
 ; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
 rt_hw_pend_sv	PROC
 	EXPORT rt_hw_pend_sv
+
+	; disable interrupt to protect context switch
+	MRS		r2, PRIMASK
+	CPSID   I
+
+	; get rt_thread_switch_interrupt_flag
+	LDR		r0, =rt_thread_switch_interrput_flag
+	LDR		r1, [r0]
+	CBZ		r1, pendsv_exit			; pendsv already handled
+
+	; clear rt_thread_switch_interrput_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
@@ -82,6 +107,7 @@ rt_hw_pend_sv	PROC
 	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
@@ -92,16 +118,22 @@ swtich_to_thread
 	LDMFD	r1!, {r4 - r11}			; pop r4 - r11 register
 	MSR		psp, r1					; update stack pointer
 
-	ORR     lr, lr, #0x04
+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]
 
@@ -110,69 +142,32 @@ rt_hw_context_switch_to    PROC
 	MOV		r0, #0x0
 	STR		r0, [r1]
 
+	; set interrupt flag to 1
+	LDR		r1, =rt_thread_switch_interrput_flag
+	MOV		r0, #1
+	STR		r0, [r1]
+
 	; set the PendSV exception priority
-    LDR     r0, =NVIC_SYSPRI2
-    LDR     r1, =NVIC_PENDSV_PRI
-    STR     r1, [r0]
+	LDR		r0, =NVIC_SYSPRI2
+	LDR		r1, =NVIC_PENDSV_PRI
+	STR		r1, [r0]
 
-    LDR     r0, =NVIC_INT_CTRL      ; trigger the PendSV exception (causes context switch)
-    LDR     r1, =NVIC_PENDSVSET
-    STR     r1, [r0]
+	; trigger the PendSV exception (causes context switch)
+	LDR		r0, =NVIC_INT_CTRL
+	LDR		r1, =NVIC_PENDSVSET
+	STR		r1, [r0]
 
-    CPSIE   I                       ; enable interrupts at processor level
+	; enable interrupts at processor level
+	CPSIE		I
 	
 	; never reach here!
 	ENDP
 
-;/*
-; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)
-; * {
-; *		if (rt_thread_switch_interrput_flag == 1)
-; * 	{
-; *			rt_interrupt_to_thread = to;
-; * 	}
-; * 	else
-; * 	{
-; *			rt_thread_switch_interrput_flag = 1;
-; * 		rt_interrupt_from_thread = from;
-; * 		rt_interrupt_to_thread = to;
-; * 	}
-; * }
-; */
-rt_hw_context_switch_interrupt    PROC
-	EXPORT rt_hw_context_switch_interrupt
-	LDR 	r2, =rt_thread_switch_interrput_flag
-	LDR 	r3, [r2]
-	CMP 	r3, #1
-	BEQ 	_reswitch
-	MOV 	r3, #1							; set rt_thread_switch_interrput_flag to 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]
-	BX		lr
-	ENDP
-
+; compatible with old version
 rt_hw_interrupt_thread_switch	PROC
 	EXPORT rt_hw_interrupt_thread_switch
-	LDR		r0, =rt_thread_switch_interrput_flag
-	LDR		r1, [r0]
-	CBZ		r1, _no_switch
-
-	; clear rt_thread_switch_interrput_flag to 0
-	MOV		r1, #0x00
-	STR		r1, [r0]
-
-	; trigger context switch
-    LDR     r0, =NVIC_INT_CTRL      ; trigger the PendSV exception (causes context switch)
-    LDR     r1, =NVIC_PENDSVSET
-    STR     r1, [r0]
-
-_no_switch
 	BX		lr
-
+	NOP
 	ENDP
 
 	END

+ 1 - 1
libcpu/arm/lm3s/fault.c

@@ -17,7 +17,6 @@ extern void list_thread(void);
 extern rt_thread_t rt_current_thread;
 void rt_hw_hard_fault_exception(struct stack_contex* contex)
 {
-	rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
 	rt_kprintf("psr: 0x%08x\n", contex->psr);
 	rt_kprintf(" pc: 0x%08x\n", contex->pc);
 	rt_kprintf(" lr: 0x%08x\n", contex->lr);
@@ -27,6 +26,7 @@ void rt_hw_hard_fault_exception(struct stack_contex* contex)
 	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

+ 4 - 2
libcpu/arm/lm3s/fault_rvds.S

@@ -24,10 +24,12 @@ rt_hw_hard_fault	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
+	ENDP
 	
-    END
+	END

+ 0 - 4
libcpu/arm/lm3s/interrupt.c

@@ -14,10 +14,6 @@
 
 #include <rtthread.h>
 
-#define MAX_HANDLERS	32
-
-extern rt_uint32_t rt_interrupt_nest;
-
 /* exception and interrupt handler table */
 rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
 rt_uint32_t rt_thread_switch_interrput_flag;

+ 0 - 42
libcpu/arm/lm3s/kservice.c

@@ -1,42 +0,0 @@
-#include <rtthread.h>
-
-#include <stdio.h>
-#include <string.h>
-
-/* 
- * Only need when RealView MDK is used.
- */
-void *rt_memset(void * s, int c, rt_ubase_t count)
-{
-	return memset(s, c, count);
-}
-
-void *rt_memcpy(void * dst, const void *src, rt_ubase_t count)
-{
-	return memcpy(dst, src, count);
-}
-
-rt_ubase_t rt_strncmp(const char * cs, const char * ct, rt_ubase_t count)
-{
-	return strncmp(cs, ct, count);
-}
-
-/**
- * This function will show the version of rt-thread rtos
- */
-void rt_show_version()
-{
-	rt_kprintf(" \\ | /\n");
-	rt_kprintf("- RT - Thread Operating System\n");
-	rt_kprintf(" / | \\ 0.%d.%d build %s\n", RT_VERSION, RT_SUBVERSION, __DATE__);
-	rt_kprintf(" 2006 - 2009 Copyright by rt-thread team\n");
-}
-
-void rt_kprintf(const char *fmt, ...)
-{
-	va_list args;
-
-	va_start(args, fmt);
-	vprintf(fmt, args);
-	va_end(args);
-}