Przeglądaj źródła

Merge branch 'master' of https://github.com/RT-Thread/rt-thread

Bernard Xiong 12 lat temu
rodzic
commit
c5927f51b3

+ 5 - 5
bsp/mini2440/rtconfig.py

@@ -12,14 +12,14 @@ TextBase = '0x30000000'
 CROSS_TOOL 	= 'gcc'
 
 if os.getenv('RTT_CC'):
-	CROSS_TOOL = os.getenv('RTT_CC')
+    CROSS_TOOL = os.getenv('RTT_CC')
 
 if  CROSS_TOOL == 'gcc':
-	PLATFORM 	= 'gcc'
-	EXEC_PATH 	= 'C:/Program Files/CodeSourcery/Sourcery G++ Lite/bin'
+    PLATFORM 	= 'gcc'
+    EXEC_PATH 	= 'C:/Program Files/CodeSourcery/Sourcery G++ Lite/bin'
 elif CROSS_TOOL == 'keil':
-	PLATFORM 	= 'armcc'
-	EXEC_PATH 	= 'C:/Keil'
+    PLATFORM 	= 'armcc'
+    EXEC_PATH 	= 'C:/Keil'
 elif CROSS_TOOL == 'iar':
     print '================ERROR============================'
     print 'Not support iar yet!'

+ 0 - 20
bsp/rm48x50/application/application.c

@@ -17,9 +17,6 @@
 #include "system.h"
 #include "het.h"
 
-int ulRegTest1Counter;
-int ulRegTest2Counter;
-
 static rt_uint8_t user_thread_stack[512];
 static struct rt_thread user_thread;
 static void user_thread_entry(void *p)
@@ -35,28 +32,11 @@ static void user_thread_entry(void *p)
     }
 }
 
-static rt_uint8_t test_thread_stack[512];
-static struct rt_thread test_thread;
-void vRegTestTask1(void*);
-
-static rt_uint8_t test_thread_stack2[512];
-static struct rt_thread test_thread2;
-void vRegTestTask2(void*);
-
 int rt_application_init()
 {
     rt_thread_init(&user_thread, "user1", user_thread_entry, RT_NULL,
             user_thread_stack, sizeof(user_thread_stack), 21, 20);
     rt_thread_startup(&user_thread);
-
-    rt_thread_init(&test_thread, "test1", vRegTestTask1, RT_NULL,
-            test_thread_stack, sizeof(test_thread_stack), 21, 20);
-    rt_thread_startup(&test_thread);
-
-    rt_thread_init(&test_thread2, "test2", vRegTestTask2, RT_NULL,
-            test_thread_stack2, sizeof(test_thread_stack2), 22, 20);
-    rt_thread_startup(&test_thread2);
-
     return 0;
 }
 

+ 0 - 472
bsp/rm48x50/application/reg_test.asm

@@ -1,472 +0,0 @@
-;/*
-;    FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.
-;
-;
-;    ***************************************************************************
-;     *                                                                       *
-;     *    FreeRTOS tutorial books are available in pdf and paperback.        *
-;     *    Complete, revised, and edited pdf reference manuals are also       *
-;     *    available.                                                         *
-;     *                                                                       *
-;     *    Purchasing FreeRTOS documentation will not only help you, by       *
-;     *    ensuring you get running as quickly as possible and with an        *
-;     *    in-depth knowledge of how to use FreeRTOS, it will also help       *
-;     *    the FreeRTOS project to continue with its mission of providing     *
-;     *    professional grade, cross platform, de facto standard solutions    *
-;     *    for microcontrollers - completely free of charge!                  *
-;     *                                                                       *
-;     *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *
-;     *                                                                       *
-;     *    Thank you for using FreeRTOS, and thank you for your support!      *
-;     *                                                                       *
-;    ***************************************************************************
-;
-;
-;    This file is part of the FreeRTOS distribution.
-;
-;    FreeRTOS is free software; you can redistribute it and/or modify it under
-;    the terms of the GNU General Public License (version 2) as published by the
-;    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
-;    >>>NOTE<<< The modification to the GPL is included to allow you to
-;    distribute a combined work that includes FreeRTOS without being obliged to
-;    provide the source code for proprietary components outside of the FreeRTOS
-;    kernel.  FreeRTOS 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 and the FreeRTOS license exception along with FreeRTOS; if not it
-;    can be viewed here: http://www.freertos.org/a00114.html and also obtained
-;    by writing to Richard Barry, contact details for whom are available on the
-;    FreeRTOS WEB site.
-;
-;    1 tab == 4 spaces!
-;    
-;    ***************************************************************************
-;     *                                                                       *
-;     *    Having a problem?  Start by reading the FAQ "My application does   *
-;     *    not run, what could be wrong?                                      *
-;     *                                                                       *
-;     *    http://www.FreeRTOS.org/FAQHelp.html                               *
-;     *                                                                       *
-;    ***************************************************************************
-;
-;    
-;    http://www.FreeRTOS.org - Documentation, training, latest information, 
-;    license and contact details.
-;    
-;    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-;    including FreeRTOS+Trace - an indispensable productivity tool.
-;
-;    Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell 
-;    the code with commercial support, indemnification, and middleware, under 
-;    the OpenRTOS brand: http://www.OpenRTOS.com.  High Integrity Systems also
-;    provide a safety engineered and independently SIL3 certified version under 
-;    the SafeRTOS brand: http://www.SafeRTOS.com.
-;*/
-
-;-------------------------------------------------
-; port to RT-Thread by Grissiom
-;
-		.def	vRegTestTask1
-		.ref	ulRegTest1Counter
-        .ref    rt_thread_delay
-
-		.text
-		.arm
-
-vRegTestTask1:
-		; Fill each general purpose register with a known value.
-		mov		r0,  #0xFF
-		mov		r1,  #0x11
-		mov		r2,  #0x22
-		mov		r3,  #0x33
-		mov     r4,  #0x44		
-		mov     r5,  #0x55
-		mov     r6,  #0x66
-		mov     r7,  #0x77
-		mov     r8,  #0x88
-		mov     r9,  #0x99
-		mov     r10, #0xAA
-		mov     r11, #0xBB
-		mov     r12, #0xCC
-		mov		r14, #0xEE
-
-	.if (__TI_VFP_SUPPORT__)
-		; Fill each FPU register with a known value.
-		vmov 	d0, r0, r1
-		vmov 	d1, r2, r3
-		vmov 	d2, r4, r5
-		vmov 	d3, r6, r7
-		vmov 	d4, r8, r9
-		vmov 	d5, r10, r11
-		vmov 	d6, r0, r1
-		vmov 	d7, r2, r3
-		vmov 	d8, r4, r5
-		vmov 	d9, r6, r7
-		vmov 	d10, r8, r9
-		vmov 	d11, r10, r11
-		vmov 	d12, r0, r1
-		vmov 	d13, r2, r3
-		vmov 	d14, r4, r5
-		vmov 	d15, r6, r7
-	.endif
-
-	
-vRegTestLoop1:
-
-        STMFD  sp!, {r0-r3, r12}
-		; Force yeild
-        MOV r0, #5
-		BL rt_thread_delay
-        LDMFD  sp!, {r0-r3, r12}
-
-	.if (__TI_VFP_SUPPORT__)
-		; Check all the VFP registers still contain the values set above.
-		; First save registers that are clobbered by the test.
-		STMFD sp!, { r0-r1 }
-
-		vmov 	r0, r1, d0
-		cmp 	r0, #0xFF
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x11
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d1
-		cmp 	r0, #0x22
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x33
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d2
-		cmp 	r0, #0x44
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x55
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d3
-		cmp 	r0, #0x66
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x77
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d4
-		cmp 	r0, #0x88
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x99
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d5
-		cmp 	r0, #0xAA
-		bne 	reg1_error_loopf
-		cmp 	r1, #0xBB
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d6
-		cmp 	r0, #0xFF
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x11
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d7
-		cmp 	r0, #0x22
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x33
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d8
-		cmp 	r0, #0x44
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x55
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d9
-		cmp 	r0, #0x66
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x77
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d10
-		cmp 	r0, #0x88
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x99
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d11
-		cmp 	r0, #0xAA
-		bne 	reg1_error_loopf
-		cmp 	r1, #0xBB
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d12
-		cmp 	r0, #0xFF
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x11
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d13
-		cmp 	r0, #0x22
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x33
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d14
-		cmp 	r0, #0x44
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x55
-		bne 	reg1_error_loopf
-		vmov 	r0, r1, d15
-		cmp 	r0, #0x66
-		bne 	reg1_error_loopf
-		cmp 	r1, #0x77
-		bne 	reg1_error_loopf
-
-		; Restore the registers that were clobbered by the test.
-		LDMFD sp!, 	{r0-r1}
-
-		; VFP register test passed.  Jump to the core register test.
-		b 		reg1_loopf_pass
-
-reg1_error_loopf:
-		; If this line is hit then a VFP register value was found to be
-		; incorrect.
-		b reg1_error_loopf
-
-reg1_loopf_pass:
-
-	.endif ;__TI_VFP_SUPPORT__
-
-		; Test each general purpose register to check that it still contains the
-		; expected known value, jumping to vRegTestError1 if any register contains
-		; an unexpected value.
-		cmp		r0, #0xFF
-		bne		vRegTestError1		
-		cmp		r1, #0x11
-		bne		vRegTestError1		
-		cmp		r2, #0x22
-		bne		vRegTestError1		
-		cmp		r3, #0x33
-		bne		vRegTestError1		
-		cmp		r4, #0x44
-		bne		vRegTestError1		
-		cmp		r5, #0x55
-		bne		vRegTestError1		
-		cmp		r6, #0x66
-		bne		vRegTestError1		
-		cmp		r7, #0x77
-		bne		vRegTestError1		
-		cmp		r8, #0x88
-		bne		vRegTestError1		
-		cmp		r9, #0x99
-		bne		vRegTestError1		
-		cmp		r10, #0xAA
-		bne		vRegTestError1		
-		cmp		r11, #0xBB
-		bne		vRegTestError1		
-		cmp		r12, #0xCC
-		bne		vRegTestError1		
-	
-		; This task is still running without jumping to vRegTestError1, so increment
-		; the loop counter so the check task knows the task is running error free.
-		stmfd   sp!, { r0-r1 }
-		ldr		r0, Count1Const
-		ldr		r1, [r0]
-		add		r1, r1, #1
-		str     r1, [r0]
-		ldmfd   sp!, { r0-r1 }
-		
-		; Loop again, performing the same tests.
-		b		vRegTestLoop1
-
-Count1Const	.word	ulRegTest1Counter
-	
-vRegTestError1:
-		b       vRegTestError1
-
-
-;-------------------------------------------------
-;
-		.def	vRegTestTask2
-		.ref	ulRegTest2Counter
-		.text
-		.arm
-;
-vRegTestTask2:
-		; Fill each general purpose register with a known value.
-		mov		r0,  #0xFF000000
-		mov		r1,  #0x11000000
-		mov		r2,  #0x22000000
-		mov		r3,  #0x33000000
-		mov     r4,  #0x44000000		
-		mov     r5,  #0x55000000
-		mov     r6,  #0x66000000
-		mov     r7,  #0x77000000
-		mov     r8,  #0x88000000
-		mov     r9,  #0x99000000
-		mov     r10, #0xAA000000
-		mov     r11, #0xBB000000
-		mov     r12, #0xCC000000
-		mov     r14, #0xEE000000
-	
-	.if (__TI_VFP_SUPPORT__)
-
-		; Fill each FPU register with a known value.
-		vmov 	d0, r0, r1
-		vmov 	d1, r2, r3
-		vmov 	d2, r4, r5
-		vmov 	d3, r6, r7
-		vmov 	d4, r8, r9
-		vmov 	d5, r10, r11
-		vmov 	d6, r0, r1
-		vmov 	d7, r2, r3
-		vmov 	d8, r4, r5
-		vmov 	d9, r6, r7
-		vmov 	d10, r8, r9
-		vmov 	d11, r10, r11
-		vmov 	d12, r0, r1
-		vmov 	d13, r2, r3
-		vmov 	d14, r4, r5
-		vmov 	d15, r6, r7
-	.endif
-
-vRegTestLoop2:
-
-	.if (__TI_VFP_SUPPORT__)
-		; Check all the VFP registers still contain the values set above.
-		; First save registers that are clobbered by the test.
-		STMFD sp!, { r0-r1 }
-
-		vmov r0, r1, d0
-		cmp r0, #0xFF000000
-		bne reg2_error_loopf
-		cmp r1, #0x11000000
-		bne reg2_error_loopf
-		vmov r0, r1, d1
-		cmp r0, #0x22000000
-		bne reg2_error_loopf
-		cmp r1, #0x33000000
-		bne reg2_error_loopf
-		vmov r0, r1, d2
-		cmp r0, #0x44000000
-		bne reg2_error_loopf
-		cmp r1, #0x55000000
-		bne reg2_error_loopf
-		vmov r0, r1, d3
-		cmp r0, #0x66000000
-		bne reg2_error_loopf
-		cmp r1, #0x77000000
-		bne reg2_error_loopf
-		vmov r0, r1, d4
-		cmp r0, #0x88000000
-		bne reg2_error_loopf
-		cmp r1, #0x99000000
-		bne reg2_error_loopf
-		vmov r0, r1, d5
-		cmp r0, #0xAA000000
-		bne reg2_error_loopf
-		cmp r1, #0xBB000000
-		bne reg2_error_loopf
-		vmov r0, r1, d6
-		cmp r0, #0xFF000000
-		bne reg2_error_loopf
-		cmp r1, #0x11000000
-		bne reg2_error_loopf
-		vmov r0, r1, d7
-		cmp r0, #0x22000000
-		bne reg2_error_loopf
-		cmp r1, #0x33000000
-		bne reg2_error_loopf
-		vmov r0, r1, d8
-		cmp r0, #0x44000000
-		bne reg2_error_loopf
-		cmp r1, #0x55000000
-		bne reg2_error_loopf
-		vmov r0, r1, d9
-		cmp r0, #0x66000000
-		bne reg2_error_loopf
-		cmp r1, #0x77000000
-		bne reg2_error_loopf
-		vmov r0, r1, d10
-		cmp r0, #0x88000000
-		bne reg2_error_loopf
-		cmp r1, #0x99000000
-		bne reg2_error_loopf
-		vmov r0, r1, d11
-		cmp r0, #0xAA000000
-		bne reg2_error_loopf
-		cmp r1, #0xBB000000
-		bne reg2_error_loopf
-		vmov r0, r1, d12
-		cmp r0, #0xFF000000
-		bne reg2_error_loopf
-		cmp r1, #0x11000000
-		bne reg2_error_loopf
-		vmov r0, r1, d13
-		cmp r0, #0x22000000
-		bne reg2_error_loopf
-		cmp r1, #0x33000000
-		bne reg2_error_loopf
-		vmov r0, r1, d14
-		cmp r0, #0x44000000
-		bne reg2_error_loopf
-		cmp r1, #0x55000000
-		bne reg2_error_loopf
-		vmov r0, r1, d15
-		cmp r0, #0x66000000
-		bne reg2_error_loopf
-		cmp r1, #0x77000000
-		bne reg2_error_loopf
-
-		; Restore the registers that were clobbered by the test.
-		LDMFD sp!, {r0-r1}
-
-		; VFP register test passed.  Jump to the core register test.
-		b reg2_loopf_pass
-
-reg2_error_loopf:
-		; If this line is hit then a VFP register value was found to be
-		; incorrect.
-		b 	reg2_error_loopf
-
-reg2_loopf_pass:
-
-	.endif ;__TI_VFP_SUPPORT__
-
-		; Test each general purpose register to check that it still contains the
-		; expected known value, jumping to vRegTestError2 if any register contains
-		; an unexpected value.
-		cmp		r0, #0xFF000000
-		bne		vRegTestError2		
-		cmp		r1, #0x11000000
-		bne		vRegTestError2	
-		cmp		r2, #0x22000000
-		bne		vRegTestError2	
-		cmp		r3, #0x33000000
-		bne		vRegTestError2	
-		cmp		r4, #0x44000000
-		bne		vRegTestError2	
-		cmp		r5, #0x55000000
-		bne		vRegTestError2	
-		cmp		r6, #0x66000000
-		bne		vRegTestError2	
-		cmp		r7, #0x77000000
-		bne		vRegTestError2	
-		cmp		r8, #0x88000000
-		bne		vRegTestError2	
-		cmp		r9, #0x99000000
-		bne		vRegTestError2	
-		cmp		r10, #0xAA000000
-		bne		vRegTestError2	
-		cmp		r11, #0xBB000000
-		bne		vRegTestError2	
-		cmp		r12, #0xCC000000
-		bne		vRegTestError2	
-		cmp     r14, #0xEE000000
-		bne		vRegTestError2	
-	
-		; This task is still running without jumping to vRegTestError2, so increment
-		; the loop counter so the check task knows the task is running error free.
-		stmfd   sp!, { r0-r1 }
-		ldr		r0, Count2Const
-		ldr		r1, [r0]
-		add		r1, r1, #1
-		str     r1, [r0]
-		ldmfd   sp!, { r0-r1 }
-		
-		; Loop again, performing the same tests.
-		b		vRegTestLoop2
-
-Count2Const	.word	ulRegTest2Counter
-	
-vRegTestError2:
-		b       vRegTestError2
-
-;-------------------------------------------------
-	
-	
-	

+ 5 - 0
bsp/rm48x50/application/startup.c

@@ -48,6 +48,11 @@ extern unsigned char * const system_data_end;
  */
 void rtthread_startup(void)
 {
+    /*// RM48 does not have cache implemented
+     *rt_hw_cpu_icache_enable();
+     *rt_hw_cpu_dcache_enable();
+     */
+
 	/* init hardware interrupt */
 	rt_hw_interrupt_init();
 

+ 1 - 0
bsp/rm48x50/rtconfig.h

@@ -212,6 +212,7 @@
 // </section>
 
 #define RT_VFP_LAZY_STACKING
+#define RT_USING_CPU_FFS
 // </RDTConfigurator>
 
 #endif

+ 0 - 3
bsp/stm32f10x/SConstruct

@@ -33,9 +33,6 @@ objs = PrepareBuilding(env, RTT_ROOT)
 # STM32 firemare library building script
 objs = objs + SConscript( GetCurrentDir() + '/Libraries/SConscript', variant_dir='build/bsp/Libraries', duplicate=0)
 
-if GetDepend('RT_USING_RTGUI'):
-    objs = objs + SConscript(RTT_ROOT + '/examples/gui/SConscript', variant_dir='build/examples/gui', duplicate=0)
-
 # build program 
 env.Program(TARGET, objs)
 

+ 1 - 0
components/drivers/include/drivers/usb_common.h

@@ -368,6 +368,7 @@ typedef struct ureqest* ureq_t;
 #define SCSI_INQUIRY_CMD                0x12
 #define SCSI_ALLOW_MEDIUM_REMOVAL       0x1e
 #define SCSI_MODE_SENSE_6               0x1a
+#define SCSI_START_STOP                 0x1b
 #define SCSI_READ_CAPACITIES            0x23
 #define SCSI_READ_CAPACITY              0x25
 #define SCSI_READ_10                    0x28

+ 5 - 0
components/drivers/include/drivers/usb_device.h

@@ -146,6 +146,11 @@ enum udev_msg_type
     USB_MSG_DATA_NOTIFY,
     USB_MSG_SOF,
     USB_MSG_RESET,
+    /* we don't need to add a "PLUG_IN" event because after the cable is
+     * plugged in(before any SETUP) the classed have nothing to do. If the host
+     * is ready, it will send RESET and we will have USB_MSG_RESET. So, a RESET
+     * should reset and run the class while plug_in is not. */
+    USB_MSG_PLUG_OUT,
 };
 typedef enum udev_msg_type udev_msg_type;
 

+ 28 - 15
components/drivers/usb/usbdevice/class/mstorage.c

@@ -33,6 +33,7 @@ static rt_device_t disk;
 static rt_uint32_t _block;
 static rt_uint32_t _count, _size;
 static struct rt_device_blk_geometry geometry;
+static rt_uint32_t _removed = 0;
 
 static struct udevice_descriptor dev_desc =
 {
@@ -126,13 +127,13 @@ static rt_err_t _request_sense(udevice_t device, uep_t ep_in)
 
     data.ErrorCode = 0x70;
     data.Valid     = 0;
-    data.SenseKey  = 5;
+    data.SenseKey  = 2; //TODO
     data.Information[0] = 0;
     data.Information[1] = 0;
     data.Information[2] = 0;
     data.Information[3] = 0;
-    data.AdditionalSenseLength = 0x0b;
-    data.AdditionalSenseCode   = 0x20;
+    data.AdditionalSenseLength = 0x0a;
+    data.AdditionalSenseCode   = 0x3a; //TODO
     data.AdditionalSenseCodeQualifier =0;
 
     dcd_ep_write(device->dcd, ep_in, (rt_uint8_t*)&data, sizeof(struct request_sense_data));
@@ -299,6 +300,19 @@ static rt_err_t _verify_10(udevice_t device)
     return RT_EOK;
 }
 
+static void _send_status(udevice_t device, mass_eps_t eps, ustorage_csw_t csw)
+{
+    dcd_ep_write(device->dcd, eps->ep_in, (rt_uint8_t*)csw, SIZEOF_CSW);
+    dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
+    status = STATUS_CBW;   
+}
+
+static void _start_stop(ustorage_cbw_t cbw)
+{
+    //TODO
+    _removed = 1;
+}
+
 /**
  * This function will handle mass storage bulk in endpoint request.
  *
@@ -313,13 +327,11 @@ static rt_err_t _ep_in_handler(udevice_t device, uclass_t cls, rt_size_t size)
     RT_ASSERT(device != RT_NULL);
 
     eps = cls->eps;
-    if(status == STATUS_CSW)
+    if (status == STATUS_CSW)
     {
-        dcd_ep_write(device->dcd, eps->ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
-        status = STATUS_CBW;
-        dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
+        _send_status(device, eps, &csw);
     }
-    if(status == STATUS_SEND)
+    else if (status == STATUS_SEND)
     {
         rt_device_read(disk, _block, eps->ep_in->buffer, 1);
         dcd_ep_write(device->dcd, eps->ep_in, eps->ep_in->buffer,
@@ -388,8 +400,8 @@ static rt_err_t _ep_out_handler(udevice_t device, uclass_t cls, rt_size_t size)
         switch(cbw->cb[0])
         {
         case SCSI_TEST_UNIT_READY:
-            dcd_ep_write(device->dcd, eps->ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
-            dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
+            csw.status = _removed;
+            _send_status(device, eps, &csw);
             break;
         case SCSI_REQUEST_SENSE:
             _request_sense(device, eps->ep_in);
@@ -404,8 +416,7 @@ static rt_err_t _ep_out_handler(udevice_t device, uclass_t cls, rt_size_t size)
             status = STATUS_CSW;
             break;
         case SCSI_ALLOW_MEDIUM_REMOVAL:
-            dcd_ep_write(device->dcd, eps->ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
-            dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
+            _send_status(device, eps, &csw);
             break;
         case SCSI_READ_CAPACITIES:
             _read_capacities(device, eps->ep_in);
@@ -425,6 +436,10 @@ static rt_err_t _ep_out_handler(udevice_t device, uclass_t cls, rt_size_t size)
         case SCSI_VERIFY_10:
             _verify_10(device);
             break;
+        case SCSI_START_STOP:
+            _start_stop(cbw);
+            _send_status(device, eps, &csw);
+            break;
         }
     }
     else if(status == STATUS_RECEIVE)
@@ -439,9 +454,7 @@ static rt_err_t _ep_out_handler(udevice_t device, uclass_t cls, rt_size_t size)
         _block ++;
         if(_size == 0)
         {
-            dcd_ep_write(device->dcd, eps->ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
-            dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
-            status = STATUS_CBW;
+            _send_status(device, eps, &csw);
         }
         else
         {

+ 56 - 4
components/drivers/usb/usbdevice/core/core.c

@@ -667,13 +667,13 @@ rt_err_t _sof_notify(udevice_t device)
 }
 
 /**
- * This function will reset all class.
+ * This function will stop all class.
  *
  * @param device the usb device object.
  *
  * @return RT_EOK.
  */
-rt_err_t _reset_notify(udevice_t device)
+rt_err_t _stop_notify(udevice_t device)
 {
     struct rt_list_node *i;
     uclass_t cls;
@@ -681,13 +681,38 @@ rt_err_t _reset_notify(udevice_t device)
     RT_ASSERT(device != RT_NULL);
 
     /* to notity every class that sof event comes */
-    for (i=device->curr_cfg->cls_list.next;
-            i!=&device->curr_cfg->cls_list; i=i->next)
+    for (i  = device->curr_cfg->cls_list.next;
+         i != &device->curr_cfg->cls_list;
+         i  = i->next)
     {
         cls = (uclass_t)rt_list_entry(i, struct uclass, list);
         if(cls->ops->stop != RT_NULL)
             cls->ops->stop(device, cls);
+    }
+
+    return RT_EOK;
+}
+
+/**
+ * This function will run all class.
+ *
+ * @param device the usb device object.
+ *
+ * @return RT_EOK.
+ */
+rt_err_t _run_notify(udevice_t device)
+{
+    struct rt_list_node *i;
+    uclass_t cls;
+
+    RT_ASSERT(device != RT_NULL);
 
+    /* to notity every class that sof event comes */
+    for (i  = device->curr_cfg->cls_list.next;
+         i != &device->curr_cfg->cls_list;
+         i  = i->next)
+    {
+        cls = (uclass_t)rt_list_entry(i, struct uclass, list);
         if(cls->ops->run != RT_NULL)
             cls->ops->run(device, cls);
     }
@@ -695,6 +720,26 @@ rt_err_t _reset_notify(udevice_t device)
     return RT_EOK;
 }
 
+/**
+ * This function will reset all class.
+ *
+ * @param device the usb device object.
+ *
+ * @return RT_EOK.
+ */
+rt_err_t _reset_notify(udevice_t device)
+{
+    struct rt_list_node *i;
+    uclass_t cls;
+
+    RT_ASSERT(device != RT_NULL);
+
+    _stop_notify(device);
+    _run_notify(device);
+
+    return RT_EOK;
+}
+
 /**
  * This function will create an usb device object.
  *
@@ -1402,6 +1447,10 @@ static void rt_usbd_thread_entry(void* parameter)
             _sof_notify(device);
             break;
         case USB_MSG_DATA_NOTIFY:
+            /* some buggy drivers will have USB_MSG_DATA_NOTIFY before the core
+             * got configured. */
+            if (device->state != USB_STATE_CONFIGURED)
+                break;
             ep = rt_usbd_find_endpoint(device, &cls, msg.content.ep_msg.ep_addr);
             if(ep != RT_NULL)
                 ep->handler(device, cls, msg.content.ep_msg.size);
@@ -1415,6 +1464,9 @@ static void rt_usbd_thread_entry(void* parameter)
             if (device->state == USB_STATE_ADDRESS)
                 _reset_notify(device);
             break;
+        case USB_MSG_PLUG_OUT:
+            _stop_notify(device);
+            break;
         default:
             rt_kprintf("unknown msg type\n");
             break;

+ 11 - 0
include/rtdef.h

@@ -147,6 +147,17 @@ typedef rt_base_t                       rt_off_t;       /**< Type for offset */
     #define ALIGN(n)                    __declspec(align(n))
     #define rt_inline                   static __inline
     #define RTT_API
+#elif defined (__TI_COMPILER_VERSION__)
+    /* The way that TI compiler set section is different from other(at least
+     * GCC and MDK) compilers. See ARM Optimizing C/C++ Compiler 5.9.3 for more
+     * details. */
+    #define SECTION(x)
+    #define UNUSED
+    #define ALIGN(n)
+    #define rt_inline                   static inline
+    #define RTT_API
+#else
+    #error not supported tool chain
 #endif
 
 /* initialization export */

+ 9 - 0
libcpu/arm/cortex-m0/context_gcc.S

@@ -13,6 +13,7 @@
  * 2012-06-01   aozima       set pendsv priority to 0xFF.
  * 2012-08-17   aozima       fixed bug: store r8 - r11.
  * 2013-02-20   aozima       port to gcc.
+ * 2013-06-18   aozima       add restore MSP feature.
  */
  
 	.cpu 	cortex-m3
@@ -21,6 +22,7 @@
 	.thumb
 	.text
 
+    .equ    SCB_VTOR, 0xE000ED04            /* Vector Table Offset Register */
 	.equ	ICSR, 0xE000ED04 				/* interrupt control state register */
 	.equ	PENDSVSET_BIT, 0x10000000 		/* value to trigger PendSV exception */
 	
@@ -152,6 +154,13 @@ rt_hw_context_switch_to:
 	LDR		R1, =PENDSVSET_BIT
 	STR		R1, [R0]
 
+    /* restore MSP */
+    LDR     r0, =SCB_VTOR
+    LDR     r0, [r0]
+    LDR     r0, [r0]
+    NOP
+    MSR     msp, r0
+
 	CPSIE	I						/* enable interrupts at processor level */
 
 	/* never reach here! */

+ 9 - 0
libcpu/arm/cortex-m0/context_iar.S

@@ -12,6 +12,7 @@
 ; * 2010-01-25     Bernard      first version
 ; * 2012-06-01     aozima       set pendsv priority to 0xFF.
 ; * 2012-08-17     aozima       fixed bug: store r8 - r11.
+; * 2013-06-18     aozima       add restore MSP feature.
 ; */
 
 ;/**
@@ -19,6 +20,7 @@
 ; */
 ;/*@{*/
 
+SCB_VTOR        EQU     0xE000ED08               ; Vector Table Offset Register
 NVIC_INT_CTRL   EQU     0xE000ED04               ; interrupt control state register
 NVIC_SHPR3      EQU     0xE000ED20               ; system priority register (2)
 NVIC_PENDSV_PRI EQU     0x00FF0000               ; PendSV priority value (lowest)
@@ -178,6 +180,13 @@ rt_hw_context_switch_to:
     STR     r1, [r0]
     NOP
 
+    ; restore MSP
+    LDR     r0, =SCB_VTOR
+    LDR     r0, [r0]
+    LDR     r0, [r0]
+    NOP
+    MSR     msp, r0
+
     ; enable interrupts at processor level
     CPSIE   I
 

+ 9 - 0
libcpu/arm/cortex-m0/context_rvds.S

@@ -12,6 +12,7 @@
 ; * 2010-01-25     Bernard      first version
 ; * 2012-06-01     aozima       set pendsv priority to 0xFF.
 ; * 2012-08-17     aozima       fixed bug: store r8 - r11.
+; * 2013-06-18     aozima       add restore MSP feature.
 ; */
 
 ;/**
@@ -19,6 +20,7 @@
 ; */
 ;/*@{*/
 
+SCB_VTOR        EQU     0xE000ED08               ; Vector Table Offset Register
 NVIC_INT_CTRL   EQU     0xE000ED04               ; interrupt control state register
 NVIC_SHPR3      EQU     0xE000ED20               ; system priority register (2)
 NVIC_PENDSV_PRI EQU     0x00FF0000               ; PendSV priority value (lowest)
@@ -183,6 +185,13 @@ rt_hw_context_switch_to    PROC
     STR     r1, [r0]
     NOP
 
+    ; restore MSP
+    LDR     r0, =SCB_VTOR
+    LDR     r0, [r0]
+    LDR     r0, [r0]
+    NOP
+    MSR     msp, r0
+
     ; enable interrupts at processor level
     CPSIE   I
 

+ 112 - 103
libcpu/arm/cortex-m3/context_gcc.S

@@ -10,161 +10,170 @@
  * Change Logs:
  * Date         Author    Notes
  * 2009-10-11   Bernard   First version
- * 2010-12-29	onelife	  Modify for EFM32
- * 2011-06-17	onelife	  Merge all of the assembly source code into context_gcc.S
- * 2011-07-12	onelife	  Add interrupt context check function
+ * 2010-12-29   onelife   Modify for EFM32
+ * 2011-06-17   onelife   Merge all of the assembly source code into context_gcc.S
+ * 2011-07-12   onelife   Add interrupt context check function
+ * 2013-06-18   aozima    add restore MSP feature.
  */
  
-	.cpu 	cortex-m3
-	.fpu 	softvfp
-	.syntax	unified
-	.thumb
-	.text
-
-	.equ	ICSR, 0xE000ED04 				/* interrupt control state register */
-	.equ	PENDSVSET_BIT, 0x10000000 		/* value to trigger PendSV exception */
-	
-	.equ	SHPR3, 0xE000ED20 				/* system priority register (3) */
-	.equ	PENDSV_PRI_LOWEST, 0x00FF0000 	/* PendSV priority value (lowest) */
+    .cpu    cortex-m3
+    .fpu    softvfp
+    .syntax unified
+    .thumb
+    .text
+
+    .equ    SCB_VTOR, 0xE000ED04            /* Vector Table Offset Register */
+    .equ    ICSR, 0xE000ED04                /* interrupt control state register */
+    .equ    PENDSVSET_BIT, 0x10000000       /* value to trigger PendSV exception */
+    
+    .equ    SHPR3, 0xE000ED20               /* system priority register (3) */
+    .equ    PENDSV_PRI_LOWEST, 0x00FF0000   /* PendSV priority value (lowest) */
 
 /*
  * rt_base_t rt_hw_interrupt_disable();
  */
-	.global rt_hw_interrupt_disable
-	.type rt_hw_interrupt_disable, %function
+    .global rt_hw_interrupt_disable
+    .type rt_hw_interrupt_disable, %function
 rt_hw_interrupt_disable:
-	MRS		R0, PRIMASK
-	CPSID	I
-	BX		LR
+    MRS     R0, PRIMASK
+    CPSID   I
+    BX      LR
 
 /*
  * void rt_hw_interrupt_enable(rt_base_t level);
  */
-	.global rt_hw_interrupt_enable
-	.type rt_hw_interrupt_enable, %function
+    .global rt_hw_interrupt_enable
+    .type rt_hw_interrupt_enable, %function
 rt_hw_interrupt_enable:
-	MSR		PRIMASK, R0
-	BX		LR
+    MSR     PRIMASK, R0
+    BX      LR
 
 /*
  * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
  * R0 --> from
  * R1 --> to
  */
-	.global rt_hw_context_switch_interrupt
-	.type rt_hw_context_switch_interrupt, %function
-	.global rt_hw_context_switch
-	.type rt_hw_context_switch, %function
+    .global rt_hw_context_switch_interrupt
+    .type rt_hw_context_switch_interrupt, %function
+    .global rt_hw_context_switch
+    .type rt_hw_context_switch, %function
 rt_hw_context_switch_interrupt:
 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]
+    /* 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]
+    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     R2, =rt_interrupt_to_thread     /* set rt_interrupt_to_thread */
+    STR     R1, [R2]
 
-	LDR		R0, =ICSR      		/* trigger the PendSV exception (causes context switch) */
-	LDR		R1, =PENDSVSET_BIT
-	STR		R1, [R0]
-	BX		LR
+    LDR     R0, =ICSR           /* trigger the PendSV exception (causes context switch) */
+    LDR     R1, =PENDSVSET_BIT
+    STR     R1, [R0]
+    BX      LR
 
 /* R0 --> swith from thread stack
  * R1 --> swith to thread stack
  * psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack
  */
-	.global PendSV_Handler
-	.type PendSV_Handler, %function
+    .global PendSV_Handler
+    .type PendSV_Handler, %function
 PendSV_Handler:
-	/* disable interrupt to protect context switch */
-	MRS		R2, PRIMASK
-	CPSID	I
+    /* 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 */
+    /* 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, #0
-	STR		R1, [R0]
+    /* clear rt_thread_switch_interrupt_flag to 0 */
+    MOV     R1, #0
+    STR     R1, [R0]
 
-	LDR		R0, =rt_interrupt_from_thread
-	LDR		R1, [R0]
-	CBZ		R1, swtich_to_thread    /* skip register save at the first time */
+    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 */
+    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 */
+    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 */
+    LDMFD   R1!, {R4 - R11}         /* pop R4 - R11 register */
+    MSR     PSP, R1                 /* update stack pointer */
 
 pendsv_exit:
-	/* restore interrupt */
-	MSR		PRIMASK, R2
+    /* restore interrupt */
+    MSR     PRIMASK, R2
 
-	ORR		LR, LR, #0x04
-	BX		LR
+    ORR     LR, LR, #0x04
+    BX      LR
 
 /*
  * void rt_hw_context_switch_to(rt_uint32 to);
  * R0 --> to
  */
-	.global rt_hw_context_switch_to
-	.type rt_hw_context_switch_to, %function
+    .global rt_hw_context_switch_to
+    .type rt_hw_context_switch_to, %function
 rt_hw_context_switch_to:
-	LDR		R1, =rt_interrupt_to_thread
-	STR		R0, [R1]
+    LDR     R1, =rt_interrupt_to_thread
+    STR     R0, [R1]
+
+    /* set from thread to 0 */
+    LDR     R1, =rt_interrupt_from_thread
+    MOV     R0, #0
+    STR     R0, [R1]
 
-	/* set from thread to 0 */
-	LDR		R1, =rt_interrupt_from_thread
-	MOV		R0, #0
-	STR		R0, [R1]
+    /* set interrupt flag to 1 */
+    LDR     R1, =rt_thread_switch_interrupt_flag
+    MOV     R0, #1
+    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, =SHPR3
+    LDR     R1, =PENDSV_PRI_LOWEST
+    LDR.W   R2, [R0,#0]             /* read */
+    ORR     R1, R1, R2              /* modify */
+    STR     R1, [R0]                /* write-back */
 
-	/* set the PendSV exception priority */
-	LDR		R0, =SHPR3
-	LDR		R1, =PENDSV_PRI_LOWEST
-	LDR.W   R2, [R0,#0]				/* read */
-	ORR     R1, R1, R2				/* modify */
-	STR     R1, [R0]				/* write-back */
+    LDR     R0, =ICSR               /* trigger the PendSV exception (causes context switch) */
+    LDR     R1, =PENDSVSET_BIT
+    STR     R1, [R0]
 
-	LDR		R0, =ICSR				/* trigger the PendSV exception (causes context switch) */
-	LDR		R1, =PENDSVSET_BIT
-	STR		R1, [R0]
+    /* restore MSP */
+    LDR     r0, =SCB_VTOR
+    LDR     r0, [r0]
+    LDR     r0, [r0]
+    NOP
+    MSR     msp, r0
 
-	CPSIE	I						/* enable interrupts at processor level */
+    CPSIE   I                       /* enable interrupts at processor level */
 
-	/* never reach here! */
+    /* never reach here! */
 
 /* compatible with old version */
-	.global rt_hw_interrupt_thread_switch
-	.type rt_hw_interrupt_thread_switch, %function
+    .global rt_hw_interrupt_thread_switch
+    .type rt_hw_interrupt_thread_switch, %function
 rt_hw_interrupt_thread_switch:
-	BX		LR
-	NOP
+    BX      LR
+    NOP
 
-	.global HardFault_Handler
-	.type HardFault_Handler, %function
+    .global HardFault_Handler
+    .type HardFault_Handler, %function
 HardFault_Handler:
     /* get current context */
     MRS     R0, PSP                 /* get fault thread stack pointer */
@@ -179,8 +188,8 @@ HardFault_Handler:
  * rt_uint32_t rt_hw_interrupt_check(void);
  * R0 --> state
  */
-	.global rt_hw_interrupt_check
-	.type rt_hw_interrupt_check, %function
+    .global rt_hw_interrupt_check
+    .type rt_hw_interrupt_check, %function
 rt_hw_interrupt_check:
-	MRS     R0, IPSR
-	BX		LR
+    MRS     R0, IPSR
+    BX      LR

+ 9 - 0
libcpu/arm/cortex-m3/context_iar.S

@@ -11,6 +11,7 @@
 ; * Date           Author       Notes
 ; * 2009-01-17     Bernard      first version
 ; * 2009-09-27     Bernard      add protect when contex switch occurs
+; * 2013-06-18     aozima       add restore MSP feature.
 ; */
 
 ;/**
@@ -18,6 +19,7 @@
 ; */
 ;/*@{*/
 
+SCB_VTOR        EQU     0xE000ED08               ; Vector Table Offset Register
 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)
@@ -151,6 +153,13 @@ rt_hw_context_switch_to:
     LDR     r1, =NVIC_PENDSVSET
     STR     r1, [r0]
 
+    ; restore MSP
+    LDR     r0, =SCB_VTOR
+    LDR     r0, [r0]
+    LDR     r0, [r0]
+    NOP
+    MSR     msp, r0
+
     CPSIE   I                       ; enable interrupts at processor level
 
     ; never reach here!

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

@@ -10,6 +10,7 @@
 ; * Change Logs:
 ; * Date           Author       Notes
 ; * 2009-01-17     Bernard      first version
+; * 2013-06-18     aozima       add restore MSP feature.
 ; */
 
 ;/**
@@ -17,6 +18,7 @@
 ; */
 ;/*@{*/
 
+SCB_VTOR        EQU     0xE000ED08               ; Vector Table Offset Register
 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)
@@ -158,6 +160,13 @@ rt_hw_context_switch_to    PROC
     LDR     r1, =NVIC_PENDSVSET
     STR     r1, [r0]
 
+    ; restore MSP
+    LDR     r0, =SCB_VTOR
+    LDR     r0, [r0]
+    LDR     r0, [r0]
+    NOP
+    MSR     msp, r0
+
     ; enable interrupts at processor level
     CPSIE   I
 

+ 11 - 9
libcpu/arm/cortex-m3/cpuport.c

@@ -102,7 +102,7 @@ rt_uint8_t *rt_hw_stack_init(void       *tentry,
  */
 void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context))
 {
-	rt_exception_hook = exception_handle;
+    rt_exception_hook = exception_handle;
 }
 
 /*
@@ -110,15 +110,16 @@ void rt_hw_exception_install(rt_err_t (*exception_handle)(void* context))
  */
 void rt_hw_hard_fault_exception(struct exception_stack_frame* context)
 {
-	extern long list_thread(void);
+    extern long list_thread(void);
 
-	if (rt_exception_hook != RT_NULL)
-	{
-		rt_err_t result;
+    if (rt_exception_hook != RT_NULL)
+    {
+        rt_err_t result;
 
-		result = rt_exception_hook(context);
-		if (result == RT_EOK) return;
-	}
+        result = rt_exception_hook(context);
+        if (result == RT_EOK)
+            return;
+    }
 
     rt_kprintf("psr: 0x%08x\n", context->psr);
     rt_kprintf(" pc: 0x%08x\n", context->pc);
@@ -135,7 +136,8 @@ void rt_hw_hard_fault_exception(struct exception_stack_frame* context)
     list_thread();
 #endif
 
-    while (1);
+    while (1)
+        ;
 }
 
 /**

+ 15 - 6
libcpu/arm/cortex-m4/context_gcc.S

@@ -11,6 +11,7 @@
  * Date           Author       Notes
  * 2009-10-11     Bernard      first version
  * 2012-01-01     aozima       support context switch load/store FPU register.
+ * 2013-06-18     aozima       add restore MSP feature.
  */
 
 /**
@@ -23,10 +24,11 @@
 .thumb
 .text
 
-.equ    NVIC_INT_CTRL,       0xE000ED04               /* interrupt control state register */
-.equ    NVIC_SYSPRI2,        0xE000ED20               /* system priority register (2) */
-.equ    NVIC_PENDSV_PRI,     0x00FF0000               /* PendSV priority value (lowest) */
-.equ    NVIC_PENDSVSET,      0x10000000               /* value to trigger PendSV exception */
+.equ    SCB_VTOR,           0xE000ED04              /* Vector Table Offset Register */
+.equ    NVIC_INT_CTRL,      0xE000ED04              /* interrupt control state register */
+.equ    NVIC_SYSPRI2,       0xE000ED20              /* system priority register (2) */
+.equ    NVIC_PENDSV_PRI,    0x00FF0000              /* PendSV priority value (lowest) */
+.equ    NVIC_PENDSVSET,     0x10000000              /* value to trigger PendSV exception */
 
 /*
  * rt_base_t rt_hw_interrupt_disable();
@@ -106,9 +108,9 @@ PendSV_Handler:
     MRS r1, psp                 /* get from thread stack pointer */
     
 #if defined (__VFP_FP__) && !defined(__SOFTFP__)
-	VSTMDB  r1!, {d8 - d15}     /* push FPU register s16~s31 */
+    VSTMDB  r1!, {d8 - d15}     /* push FPU register s16~s31 */
 #endif
-	
+    
     STMFD   r1!, {r4 - r11}     /* push r4 - r11 register */
     LDR r0, [r0]
     STR r1, [r0]                /* update from thread stack pointer */
@@ -164,6 +166,13 @@ rt_hw_context_switch_to:
     LDR r1, =NVIC_PENDSVSET
     STR r1, [r0]
 
+    /* restore MSP */
+    LDR     r0, =SCB_VTOR
+    LDR     r0, [r0]
+    LDR     r0, [r0]
+    NOP
+    MSR     msp, r0
+
     CPSIE   I                       /* enable interrupts at processor level */
 
     /* never reach here! */

+ 9 - 0
libcpu/arm/cortex-m4/context_iar.S

@@ -12,6 +12,7 @@
 ; * 2009-01-17     Bernard      first version
 ; * 2009-09-27     Bernard      add protect when contex switch occurs
 ; * 2012-01-01     aozima       support context switch load/store FPU register.
+; * 2013-06-18     aozima       add restore MSP feature.
 ; */
 
 ;/**
@@ -19,6 +20,7 @@
 ; */
 ;/*@{*/
 
+SCB_VTOR        EQU     0xE000ED08               ; Vector Table Offset Register
 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)
@@ -162,6 +164,13 @@ rt_hw_context_switch_to:
     LDR     r1, =NVIC_PENDSVSET
     STR     r1, [r0]
 
+    ; restore MSP
+    LDR     r0, =SCB_VTOR
+    LDR     r0, [r0]
+    LDR     r0, [r0]
+    NOP
+    MSR     msp, r0
+
     CPSIE   I                       ; enable interrupts at processor level
 
     ; never reach here!

+ 11 - 2
libcpu/arm/cortex-m4/context_rvds.S

@@ -11,6 +11,7 @@
 ; * Date           Author       Notes
 ; * 2009-01-17     Bernard      first version.
 ; * 2012-01-01     aozima       support context switch load/store FPU register.
+; * 2013-06-18     aozima       add restore MSP feature.
 ; */
 
 ;/**
@@ -18,6 +19,7 @@
 ; */
 ;/*@{*/
 
+SCB_VTOR        EQU     0xE000ED08               ; Vector Table Offset Register
 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)
@@ -108,10 +110,10 @@ PendSV_Handler   PROC
     MRS     r1, psp                 ; get from thread stack pointer
 
     IF      {FPU} != "SoftVFP"
-	VSTMFD  r1!, {d8 - d15}         ; push FPU register s16~s31
+    VSTMFD  r1!, {d8 - d15}         ; push FPU register s16~s31
     ENDIF
 
-	STMFD   r1!, {r4 - r11}         ; push r4 - r11 register
+    STMFD   r1!, {r4 - r11}         ; push r4 - r11 register
     LDR     r0, [r0]
     STR     r1, [r0]                ; update from thread stack pointer
 
@@ -169,6 +171,13 @@ rt_hw_context_switch_to    PROC
     LDR     r1, =NVIC_PENDSVSET
     STR     r1, [r0]
 
+    ; restore MSP
+    LDR     r0, =SCB_VTOR
+    LDR     r0, [r0]
+    LDR     r0, [r0]
+    NOP
+    MSR     msp, r0
+
     ; enable interrupts at processor level
     CPSIE   I
 

+ 10 - 0
libcpu/arm/cortex-r4/context_ccs.asm

@@ -28,18 +28,22 @@
 ; * rt_base_t rt_hw_interrupt_disable();
 ; */
     .def rt_hw_interrupt_disable
+    .asmfunc
 rt_hw_interrupt_disable
     MRS r0, cpsr
     CPSID IF
     BX  lr
+    .endasmfunc
 
 ;/*
 ; * void rt_hw_interrupt_enable(rt_base_t level);
 ; */
     .def rt_hw_interrupt_enable
+    .asmfunc
 rt_hw_interrupt_enable
     MSR cpsr_c, r0
     BX  lr
+    .endasmfunc
 
 ;/*
 ; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
@@ -47,6 +51,7 @@ rt_hw_interrupt_enable
 ; * r1 --> to
 ; */
     .def rt_hw_context_switch
+    .asmfunc
 rt_hw_context_switch
     STMDB   sp!, {lr}           ; push pc (lr should be pushed in place of PC)
     STMDB   sp!, {r0-r12, lr}   ; push lr & register file
@@ -88,12 +93,14 @@ __no_vfp_frame2
     MSR     spsr_cxsf, r4
 
     LDMIA   sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc, copy spsr to cpsr
+    .endasmfunc
 
 ;/*
 ; * void rt_hw_context_switch_to(rt_uint32 to);
 ; * r0 --> to
 ; */
     .def rt_hw_context_switch_to
+    .asmfunc
 rt_hw_context_switch_to
     LDR     sp, [r0]            ; get new task stack pointer
 
@@ -112,12 +119,14 @@ __no_vfp_frame_to
     MSR     spsr_cxsf, r4
 
     LDMIA   sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc, copy spsr to cpsr
+    .endasmfunc
 
 ;/*
 ; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
 ; */
 
     .def rt_hw_context_switch_interrupt
+    .asmfunc
 rt_hw_context_switch_interrupt
     LDR r2, pintflag
     LDR r3, [r2]
@@ -131,6 +140,7 @@ _reswitch
     LDR r2, ptothread       ; set rt_interrupt_to_thread
     STR r1, [r2]
     BX  lr
+    .endasmfunc
 
     .def IRQ_Handler
 IRQ_Handler

+ 52 - 0
libcpu/arm/cortex-r4/cpu.c

@@ -39,4 +39,56 @@ void rt_hw_cpu_shutdown()
 	while (1);
 }
 
+#ifdef RT_USING_CPU_FFS
+int __rt_ffs(int value)
+{
+	if (value == 0)
+		return value;
+
+	__asm("    rsb r1, r0, #0");
+	__asm("    and r1, r1, r0");
+	__asm("    clz r1, r1");
+	__asm("    rsb r0, r1, #32");
+}
+#endif
+
+#ifdef __TI_COMPILER_VERSION__
+void rt_hw_cpu_icache_enable()
+{
+    __asm("   MRC p15, #0, r1, c1, c0, #0 ; Read SCTLR configuration data");
+    __asm("   ORR r1,  r1, #0x1 <<12 ; instruction cache enable");
+    __asm("   MCR p15, #0, r0, c7, c5, #0 ; Invalidate entire instruction cache, r0 is ignored");
+    __asm("   MCR p15, #0, r1, c1, c0, #0 ; enabled instruction cache");
+    __asm("   ISB");
+}
+
+void rt_hw_cpu_icache_disable()
+{
+    __asm("    MRC p15, #0, r1, c1, c0, #0  ; Read SCTLR configuration data");
+    __asm("    BIC r1,  r1, #0x1 <<12  ; instruction cache enable");
+    __asm("    MCR p15, #0, r1, c1, c0, #0 ; disabled instruction cache");
+    __asm("    ISB");
+}
+
+void rt_hw_cpu_dcache_enable()
+{
+    __asm("    MRC p15, #0, R1, c1, c0, #0 ; Read SCTLR configuration data");
+    __asm("    ORR R1, R1, #0x1 <<2");
+    __asm("    DSB");
+    __asm("    MCR p15, #0, r0, c15, c5, #0 ; Invalidate entire data cache");
+    __asm("    MCR p15, #0, R1, c1, c0, #0 ; enabled data cache");
+}
+
+void rt_hw_cpu_dcache_disable()
+{
+    /* FIXME: Clean entire data cache. This routine depends on the data cache
+     * size.  It can be omitted if it is known that the data cache has no dirty
+     * data. */
+    __asm("    MRC p15, #0, r1, c1, c0, #0 ; Read SCTLR configuration data");
+    __asm("    BIC r1, r1, #0x1 <<2");
+    __asm("    DSB");
+    __asm("    MCR p15, #0, r1, c1, c0, #0 ; disabled data cache");
+}
+
+#endif
 /*@}*/

+ 1 - 1
libcpu/arm/cortex-r4/interrupt.c

@@ -22,7 +22,7 @@
 /* exception and interrupt handler table */
 struct rt_irq_desc irq_desc[MAX_HANDLERS];
 
-extern rt_uint32_t rt_interrupt_nest;
+extern volatile rt_uint8_t rt_interrupt_nest;
 
 /* exception and interrupt handler table */
 rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;

+ 2 - 2
libcpu/arm/s3c24x0/context_gcc.S

@@ -52,8 +52,8 @@ rt_hw_context_switch:
 	mrs	r4, spsr
 	stmfd	sp!, {r4}		@ push spsr
 
-	str	sp, [r0]			@ store sp in preempted tasks TCB
-	ldr	sp, [r1]			@ get new task stack pointer
+	str	sp, [r0]		@ store sp in preempted tasks TCB
+	ldr	sp, [r1]		@ get new task stack pointer
 
 	ldmfd	sp!, {r4}		@ pop new task spsr
 	msr	spsr_cxsf, r4

+ 232 - 220
libcpu/arm/s3c24x0/serial.c

@@ -10,7 +10,7 @@
  * Change Logs:
  * Date           Author       Notes
  * 2006-03-13     Bernard      first version
- * 2009-04-20     yi.qiu      modified according bernard's stm32 version      	  	
+ * 2009-04-20     yi.qiu      modified according bernard's stm32 version
  */
 
 #include <rtthread.h>
@@ -26,208 +26,220 @@
 /**
  * This function initializes serial
  */
-static rt_err_t rt_serial_init (rt_device_t dev)
+static rt_err_t rt_serial_init(rt_device_t dev)
 {
-	struct serial_device* uart = (struct serial_device*) dev->user_data;
-
-	if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
-	{
-
-		if (dev->flag & RT_DEVICE_FLAG_INT_RX)
-		{
-			rt_memset(uart->int_rx->rx_buffer, 0, 
-				sizeof(uart->int_rx->rx_buffer));
-			uart->int_rx->read_index = uart->int_rx->save_index = 0;
-		}
-		
-		if (dev->flag & RT_DEVICE_FLAG_INT_TX)
-		{
-			rt_memset(uart->int_tx->tx_buffer, 0, 
-				sizeof(uart->int_tx->tx_buffer));
-			uart->int_tx->write_index = uart->int_tx->save_index = 0;
-		}
-
-		dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
-	}
-
-	return RT_EOK;
+    struct serial_device* uart = (struct serial_device*) dev->user_data;
+
+    if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
+    {
+
+        if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+        {
+            rt_memset(uart->int_rx->rx_buffer, 0,
+                      sizeof(uart->int_rx->rx_buffer));
+            uart->int_rx->read_index = uart->int_rx->save_index = 0;
+        }
+
+        if (dev->flag & RT_DEVICE_FLAG_INT_TX)
+        {
+            rt_memset(uart->int_tx->tx_buffer, 0,
+                      sizeof(uart->int_tx->tx_buffer));
+            uart->int_tx->write_index = uart->int_tx->save_index = 0;
+        }
+
+        dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
+    }
+
+    return RT_EOK;
 }
 
 /* save a char to serial buffer */
 static void rt_serial_savechar(struct serial_device* uart, char ch)
 {
-	rt_base_t level;
-	
-	/* disable interrupt */
-	level = rt_hw_interrupt_disable();
-
-	uart->int_rx->rx_buffer[uart->int_rx->save_index] = ch;
-	uart->int_rx->save_index ++;
-	if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE)
-		uart->int_rx->save_index = 0;
-	
-	/* if the next position is read index, discard this 'read char' */
-	if (uart->int_rx->save_index == uart->int_rx->read_index)
-	{
-		uart->int_rx->read_index ++;
-		if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
-			uart->int_rx->read_index = 0;
-	}
-
-	/* enable interrupt */
-	rt_hw_interrupt_enable(level);
+    rt_base_t level;
+
+    /* disable interrupt */
+    level = rt_hw_interrupt_disable();
+
+    uart->int_rx->rx_buffer[uart->int_rx->save_index] = ch;
+    uart->int_rx->save_index ++;
+    if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE)
+        uart->int_rx->save_index = 0;
+
+    /* if the next position is read index, discard this 'read char' */
+    if (uart->int_rx->save_index == uart->int_rx->read_index)
+    {
+        uart->int_rx->read_index ++;
+        if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
+            uart->int_rx->read_index = 0;
+    }
+
+    /* enable interrupt */
+    rt_hw_interrupt_enable(level);
 }
 
 static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
-{	
-	RT_ASSERT(dev != RT_NULL);
-	
-	return RT_EOK;
+{
+    RT_ASSERT(dev != RT_NULL);
+
+    return RT_EOK;
 }
 
 static rt_err_t rt_serial_close(rt_device_t dev)
-{	
-	RT_ASSERT(dev != RT_NULL);
+{
+    RT_ASSERT(dev != RT_NULL);
 
-	return RT_EOK;
+    return RT_EOK;
 }
 
-static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
 {
-	rt_uint8_t* ptr;
-	rt_err_t err_code;
-	struct serial_device* uart;
-	
-	ptr = buffer;
-	err_code = RT_EOK;
-	uart = (struct serial_device*)dev->user_data;
-
-	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
-	{
-		rt_base_t level;
-
-		/* interrupt mode Rx */
-		while (size)
-		{
-			if (uart->int_rx->read_index != uart->int_rx->save_index)
-			{
-				*ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
-				size --;
-
-				/* disable interrupt */
-				level = rt_hw_interrupt_disable();
-
-				uart->int_rx->read_index ++;
-				if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
-					uart->int_rx->read_index = 0;
-
-				/* enable interrupt */
-				rt_hw_interrupt_enable(level);
-			}
-			else
-			{
-				/* set error code */
-				err_code = -RT_EEMPTY;
-				break;
-			}
-		}
-	}
-	else
-	{
-		/* polling mode */
-		while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
-		{
-			while (uart->uart_device->ustat & USTAT_RCV_READY)
-			{
-				*ptr = uart->uart_device->urxh & 0xff;
-				ptr ++;
-			}
-		}
-	}
-
-	/* set error code */
-	rt_set_errno(err_code);
-	return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+    rt_uint8_t* ptr;
+    rt_err_t err_code;
+    struct serial_device* uart;
+
+    ptr = buffer;
+    err_code = RT_EOK;
+    uart = (struct serial_device*)dev->user_data;
+
+    if (ptr == RT_NULL)
+    {
+        err_code = -RT_ENOMEM;
+        rt_set_errno(err_code);
+        return -RT_ENOMEM;
+    }
+    if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+    {
+        rt_base_t level;
+
+        /* interrupt mode Rx */
+        while (size)
+        {
+            if (uart->int_rx->read_index != uart->int_rx->save_index)
+            {
+                *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
+                size --;
+
+                /* disable interrupt */
+                level = rt_hw_interrupt_disable();
+
+                uart->int_rx->read_index ++;
+                if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
+                    uart->int_rx->read_index = 0;
+
+                /* enable interrupt */
+                rt_hw_interrupt_enable(level);
+            }
+            else
+            {
+                /* set error code */
+                err_code = -RT_EEMPTY;
+                break;
+            }
+        }
+    }
+    else
+    {
+        /* polling mode */
+        while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
+        {
+            while (uart->uart_device->ustat & USTAT_RCV_READY)
+            {
+                *ptr = uart->uart_device->urxh & 0xff;
+                ptr ++;
+            }
+        }
+    }
+
+    /* set error code */
+    rt_set_errno(err_code);
+    return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
 }
 
-static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
 {
-	rt_uint8_t* ptr;
-	rt_err_t err_code;
-	struct serial_device* uart;
-	
-	err_code = RT_EOK;
-	ptr = (rt_uint8_t*)buffer;
-	uart = (struct serial_device*)dev->user_data;
-
-	if (dev->flag & RT_DEVICE_FLAG_INT_TX)
-	{
-		/* interrupt mode Tx */
-		while (uart->int_tx->save_index != uart->int_tx->write_index)
-		{
-			/* save on tx buffer */
-			uart->int_tx->tx_buffer[uart->int_tx->save_index] = *ptr++;
-			
-			-- size;
-
-			/* move to next position */
-			uart->int_tx->save_index ++;
-			
-			/* wrap save index */
-			if (uart->int_tx->save_index >= UART_TX_BUFFER_SIZE)
-				uart->int_tx->save_index = 0;
-		}
-		
-		/* set error code */
-		if (size > 0)
-			err_code = -RT_EFULL;
-	}
-	else
-	{
-		/* polling mode */
-		while (size)
-		{
-			/*
-			 * to be polite with serial console add a line feed
-			 * to the carriage return character
-			 */
-			if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM))
-			{
-				while (!(uart->uart_device->ustat & USTAT_TXB_EMPTY));
-				uart->uart_device->utxh = '\r';
-			}
-
-			while (!(uart->uart_device->ustat & USTAT_TXB_EMPTY));
-			uart->uart_device->utxh = (*ptr & 0xFF);
-
-			++ptr; --size;
-		}
-	}	
-
-	/* set error code */
-	rt_set_errno(err_code);
-	
-	return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+    rt_uint8_t* ptr;
+    rt_err_t err_code;
+    struct serial_device* uart;
+
+    err_code = RT_EOK;
+    ptr = (rt_uint8_t*)buffer;
+    uart = (struct serial_device*)dev->user_data;
+
+    if (ptr == RT_NULL)
+    {
+        err_code = -RT_ENOMEM;
+        rt_set_errno(err_code);
+        return -RT_ENOMEM;
+    }
+    if (dev->flag & RT_DEVICE_FLAG_INT_TX)
+    {
+        /* interrupt mode Tx */
+        while (uart->int_tx->save_index != uart->int_tx->write_index)
+        {
+            /* save on tx buffer */
+            uart->int_tx->tx_buffer[uart->int_tx->save_index] = *ptr++;
+
+            -- size;
+
+            /* move to next position */
+            uart->int_tx->save_index ++;
+
+            /* wrap save index */
+            if (uart->int_tx->save_index >= UART_TX_BUFFER_SIZE)
+                uart->int_tx->save_index = 0;
+        }
+
+        /* set error code */
+        if (size > 0)
+            err_code = -RT_EFULL;
+    }
+    else
+    {
+        /* polling mode */
+        while (size)
+        {
+            /*
+             * to be polite with serial console add a line feed
+             * to the carriage return character
+             */
+            if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM))
+            {
+                while (!(uart->uart_device->ustat & USTAT_TXB_EMPTY));
+                uart->uart_device->utxh = '\r';
+            }
+
+            while (!(uart->uart_device->ustat & USTAT_TXB_EMPTY));
+            uart->uart_device->utxh = (*ptr & 0xFF);
+
+            ++ptr;
+            --size;
+        }
+    }
+
+    /* set error code */
+    rt_set_errno(err_code);
+    return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
 }
 
-static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
+static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
 {
-	RT_ASSERT(dev != RT_NULL);
-
-	switch (cmd)
-	{
-	case RT_DEVICE_CTRL_SUSPEND:
-		/* suspend device */
-		dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
-		break;
-	
-	case RT_DEVICE_CTRL_RESUME:
-		/* resume device */
-		dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
-		break;
-	}
-	
-	return RT_EOK;
+    RT_ASSERT(dev != RT_NULL);
+
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_SUSPEND:
+        /* suspend device */
+        dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
+        break;
+
+    case RT_DEVICE_CTRL_RESUME:
+        /* resume device */
+        dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
+        break;
+    }
+
+    return RT_EOK;
 }
 
 /*
@@ -235,49 +247,49 @@ static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
  */
 rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial)
 {
-	RT_ASSERT(device != RT_NULL);
-
-	device->type 		= RT_Device_Class_Char;
-	device->rx_indicate = RT_NULL;
-	device->tx_complete = RT_NULL;
-	device->init 		= rt_serial_init;
-	device->open		= rt_serial_open;
-	device->close		= rt_serial_close;
-	device->read 		= rt_serial_read;
-	device->write 		= rt_serial_write;
-	device->control 	= rt_serial_control;
-	device->user_data   = serial;
-
-	/* register a character device */
-	return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
+    RT_ASSERT(device != RT_NULL);
+
+    device->type        = RT_Device_Class_Char;
+    device->rx_indicate = RT_NULL;
+    device->tx_complete = RT_NULL;
+    device->init        = rt_serial_init;
+    device->open        = rt_serial_open;
+    device->close       = rt_serial_close;
+    device->read        = rt_serial_read;
+    device->write       = rt_serial_write;
+    device->control     = rt_serial_control;
+    device->user_data   = serial;
+
+    /* register a character device */
+    return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
 }
-	
+
 /* ISR for serial interrupt */
 void rt_hw_serial_isr(rt_device_t device)
 {
-	struct serial_device* uart = (struct serial_device*) device->user_data;
-	
-	/* interrupt mode receive */	
-	RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);
-
-	/* save on rx buffer */
-	while (uart->uart_device->ustat & USTAT_RCV_READY)
-	{
-		rt_serial_savechar(uart, uart->uart_device->urxh & 0xff);
-	}
-
-	/* invoke callback */
-	if (device->rx_indicate != RT_NULL)
-	{
-		rt_size_t rx_length;
-		
-		/* get rx length */
-		rx_length = uart->int_rx->read_index > uart->int_rx->save_index ?
-			UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index :
-			uart->int_rx->save_index - uart->int_rx->read_index;
-
-		device->rx_indicate(device, rx_length);
-	}	
+    struct serial_device* uart = (struct serial_device*) device->user_data;
+
+    /* interrupt mode receive */
+    RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);
+
+    /* save on rx buffer */
+    while (uart->uart_device->ustat & USTAT_RCV_READY)
+    {
+        rt_serial_savechar(uart, uart->uart_device->urxh & 0xff);
+    }
+
+    /* invoke callback */
+    if (device->rx_indicate != RT_NULL)
+    {
+        rt_size_t rx_length;
+
+        /* get rx length */
+        rx_length = uart->int_rx->read_index > uart->int_rx->save_index ?
+                    UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index :
+                    uart->int_rx->save_index - uart->int_rx->read_index;
+
+        device->rx_indicate(device, rx_length);
+    }
 }
 
 /*@}*/

+ 3 - 3
libcpu/arm/s3c24x0/start_gcc.S

@@ -10,8 +10,8 @@
  * Change Logs:
  * Date           Author       Notes
  * 2006-03-13     Bernard      first version
- * 2006-10-05     Alsor.Z       for s3c2440 initialize
- * 2008-01-29     Yi.Qiu         for QEMU emulator
+ * 2006-10-05     Alsor.Z      for s3c2440 initialize
+ * 2008-01-29     Yi.Qiu       for QEMU emulator
  */
 
 #define CONFIG_STACKSIZE 	512
@@ -23,7 +23,7 @@
 #define S_LR  				56
 #define S_SP  				52
 
-#define S_IP  					48
+#define S_IP  				48
 #define S_FP  				44
 #define S_R10  				40
 #define S_R9  				36

+ 9 - 0
tools/building.py

@@ -83,6 +83,11 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
                       action='store_true',
                       default=False,
                       help='copy header of rt-thread directory to local.')
+    AddOption('--cscope',
+                      dest='cscope',
+                      action='store_true',
+                      default=False,
+                      help='Build Cscope cross reference database. Requires cscope installed.')
 
     # add build library option
     AddOption('--buildlib', 
@@ -341,6 +346,10 @@ def EndBuilding(target, program = None):
     if GetOption('copy-header') and program != None:
         MakeCopyHeader(program)
 
+    if GetOption('cscope'):
+        from cscope import CscopeDatabase
+        CscopeDatabase(Projects)
+
 def SrcRemove(src, remove):
     if type(src[0]) == type('str'):
         for item in src:

+ 6 - 2
tools/codeblocks.py

@@ -38,8 +38,12 @@ def CB_AddCFiles(ProjectFiles, parent, gname, files, project_path):
 
 def CBProject(target, script, program):
     project_path = os.path.dirname(os.path.abspath(target))
+
+    if os.path.isfile('template.cbp'):
+        tree = etree.parse('template.cbp')
+    else:
+        tree = etree.parse(os.path.join(os.path.dirname(__file__), 'template.cbp'))
     
-    tree = etree.parse('template.cbp')
     root = tree.getroot()
     
     out = file(target, 'wb')
@@ -75,7 +79,7 @@ def CBProject(target, script, program):
             Add = SubElement(elem, 'Add')
             Add.set('directory', path)
 
-        for macro in building.Env['CPPDEFINES']:
+        for macro in building.Env.get('CPPDEFINES', []):
             Add = SubElement(elem, 'Add')
             Add.set('option', "-D"+macro)
         

+ 37 - 0
tools/cscope.py

@@ -0,0 +1,37 @@
+import os
+
+def _get_src(project):
+    li = []
+    for group in project:
+        for f in group['src']:
+            li.append(os.path.normpath(f.rfile().abspath))
+    return li
+
+def _get_header_dir(dirp):
+    li = []
+    for root, dirs, files in os.walk(dirp):
+        for d in dirs:
+            fpath = os.path.join(root, d)
+            li.extend(_get_header_dir(fpath))
+
+        for f in files:
+            if f[-2:] == '.h':
+                fpath = os.path.join(root, f)
+                li.append(os.path.normpath(fpath))
+    return li
+
+def _get_header(project):
+    li = []
+    for g in project:
+        for d in g.get('CPPPATH', []):
+            li.extend(_get_header_dir(d))
+    return li
+
+def CscopeDatabase(project):
+    files = set(_get_src(project) + _get_header(project))
+    with open('cscope.files', 'w') as db:
+        db.write('-k\n-q\n')
+        db.write('\n'.join(files))
+        db.flush() # let cscope see the full content
+        os.system('cscope -b')
+

+ 9 - 2
tools/iar.py

@@ -37,7 +37,10 @@ def IARAddGroup(parent, name, files, project_path):
         
         file = SubElement(group, 'file')
         file_name = SubElement(file, 'name')
-        file_name.text = ('$PROJ_DIR$\\' + path).decode(fs_encoding)
+        if os.path.isabs(path):
+            file_name.text = path.decode(fs_encoding)
+        else:
+            file_name.text = ('$PROJ_DIR$\\' + path).decode(fs_encoding)
 
 def IARWorkspace(target):
     # make an workspace 
@@ -91,7 +94,11 @@ def IARProject(target, script):
         if name.text == 'CCIncludePath2' or name.text == 'newCCIncludePaths':
             for path in paths:
                 state = SubElement(option, 'state')
-                state.text = '$PROJ_DIR$\\' + path
+                if os.path.isabs(path):
+                    state.text = path
+                else:
+                    state.text = '$PROJ_DIR$\\' + path
+
         if name.text == 'CCDefines':
             for define in CPPDEFINES:
                 state = SubElement(option, 'state')

+ 41 - 0
tools/template.cbp

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+	<FileVersion major="1" minor="6" />
+	<Project>
+		<Option title="project" />
+		<Option pch_mode="2" />
+		<Option compiler="gcc" />
+		<Build>
+			<Target title="Debug">
+				<Option output="build/bin/Debug/project" prefix_auto="1" extension_auto="1" />
+				<Option object_output="build/obj/Debug/" />
+				<Option type="1" />
+				<Option compiler="gcc" />
+				<Compiler>
+					<Add option="-g" />
+				</Compiler>
+			</Target>
+			<Target title="Release">
+				<Option output="build/bin/Release/project" prefix_auto="1" extension_auto="1" />
+				<Option object_output="build/obj/Release/" />
+				<Option type="1" />
+				<Option compiler="gcc" />
+				<Compiler>
+					<Add option="-O2" />
+				</Compiler>
+				<Linker>
+					<Add option="-s" />
+				</Linker>
+			</Target>
+		</Build>
+		<Compiler>
+			<Add option="-Wall" />
+		</Compiler>
+		<Extensions>
+			<code_completion />
+			<envvars />
+			<debugger />
+			<lib_finder disable_auto="1" />
+		</Extensions>
+	</Project>
+</CodeBlocks_project_file>