From 85822f22b7d621deb448a83393f0c607032e392f Mon Sep 17 00:00:00 2001 From: Grissiom Date: Mon, 3 Jun 2013 22:23:17 +0800 Subject: [PATCH 01/21] rtdef.h: get back the codes that removed accidentally by d80a471 --- include/rtdef.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/rtdef.h b/include/rtdef.h index 7a983efb65..c55327b2d2 100644 --- a/include/rtdef.h +++ b/include/rtdef.h @@ -145,6 +145,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 /* event length */ From 480ac3444510fc7303f738a81f64314557366b8d Mon Sep 17 00:00:00 2001 From: Grissiom Date: Mon, 3 Jun 2013 22:25:25 +0800 Subject: [PATCH 02/21] rm48x50: remove useless reg_test code --- bsp/rm48x50/application/application.c | 20 -- bsp/rm48x50/application/reg_test.asm | 472 -------------------------- 2 files changed, 492 deletions(-) delete mode 100644 bsp/rm48x50/application/reg_test.asm diff --git a/bsp/rm48x50/application/application.c b/bsp/rm48x50/application/application.c index d9ffaf4754..a1c115c793 100644 --- a/bsp/rm48x50/application/application.c +++ b/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; } diff --git a/bsp/rm48x50/application/reg_test.asm b/bsp/rm48x50/application/reg_test.asm deleted file mode 100644 index 6b68164604..0000000000 --- a/bsp/rm48x50/application/reg_test.asm +++ /dev/null @@ -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 - -;------------------------------------------------- - - - From 228a6be077a2e2f40e9cbc6f23ed232a8371e7d0 Mon Sep 17 00:00:00 2001 From: Grissiom Date: Sat, 1 Jun 2013 02:16:10 +0800 Subject: [PATCH 03/21] cortex-r4: add __rt_ffs --- bsp/rm48x50/rtconfig.h | 1 + libcpu/arm/cortex-r4/cpu.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/bsp/rm48x50/rtconfig.h b/bsp/rm48x50/rtconfig.h index 86fc630c8c..d681ef736e 100644 --- a/bsp/rm48x50/rtconfig.h +++ b/bsp/rm48x50/rtconfig.h @@ -212,6 +212,7 @@ // #define RT_VFP_LAZY_STACKING +#define RT_USING_CPU_FFS // #endif diff --git a/libcpu/arm/cortex-r4/cpu.c b/libcpu/arm/cortex-r4/cpu.c index 569f7d0c29..3aa7cd35de 100644 --- a/libcpu/arm/cortex-r4/cpu.c +++ b/libcpu/arm/cortex-r4/cpu.c @@ -39,4 +39,17 @@ 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 + /*@}*/ From e8bbbe67886f28db5600e6e5029cd24a48925e50 Mon Sep 17 00:00:00 2001 From: Grissiom Date: Fri, 31 May 2013 22:43:53 +0800 Subject: [PATCH 04/21] cortex-r4: wrap asm functions with .asmfunc/.endasmfunc --- libcpu/arm/cortex-r4/context_ccs.asm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libcpu/arm/cortex-r4/context_ccs.asm b/libcpu/arm/cortex-r4/context_ccs.asm index dc4113f5e4..2b459f8238 100644 --- a/libcpu/arm/cortex-r4/context_ccs.asm +++ b/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 From ed19483cb4f026c40e7c6a6bc09583e054ef0c5e Mon Sep 17 00:00:00 2001 From: Grissiom Date: Thu, 6 Jun 2013 15:21:40 +0800 Subject: [PATCH 05/21] usb: add USB_MSG_PLUG_OUT event When the core received an USB_MSG_PLUG_OUT event, it will stop all the classes. This make a chance that the classes could get rid off doing useless stuff while the USB cable is plugged out. --- .../drivers/include/drivers/usb_device.h | 5 ++ components/drivers/usb/usbdevice/core/core.c | 70 ++++++++++++++++--- 2 files changed, 64 insertions(+), 11 deletions(-) diff --git a/components/drivers/include/drivers/usb_device.h b/components/drivers/include/drivers/usb_device.h index f0e0989ce5..2f464def3f 100644 --- a/components/drivers/include/drivers/usb_device.h +++ b/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; diff --git a/components/drivers/usb/usbdevice/core/core.c b/components/drivers/usb/usbdevice/core/core.c index 45264033a9..c2965d6bb2 100644 --- a/components/drivers/usb/usbdevice/core/core.c +++ b/components/drivers/usb/usbdevice/core/core.c @@ -666,6 +666,60 @@ rt_err_t _sof_notify(udevice_t device) return RT_EOK; } +/** + * This function will stop all class. + * + * @param device the usb device object. + * + * @return RT_EOK. + */ +rt_err_t _stop_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->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); + } + + return RT_EOK; +} + /** * This function will reset all class. * @@ -680,17 +734,8 @@ 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) - { - cls = (uclass_t)rt_list_entry(i, struct uclass, list); - if(cls->ops->stop != RT_NULL) - cls->ops->stop(device, cls); - - if(cls->ops->run != RT_NULL) - cls->ops->run(device, cls); - } + _stop_notify(); + _run_notify(); return RT_EOK; } @@ -1415,6 +1460,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; From 4807145a7138bf7f2509b4c197f6119a81b10b69 Mon Sep 17 00:00:00 2001 From: aozima Date: Sat, 8 Jun 2013 20:50:09 +0800 Subject: [PATCH 06/21] clean up code: remove the old file. --- bsp/stm32f10x/SConstruct | 3 --- 1 file changed, 3 deletions(-) diff --git a/bsp/stm32f10x/SConstruct b/bsp/stm32f10x/SConstruct index 920b24db27..37d86a7b5f 100644 --- a/bsp/stm32f10x/SConstruct +++ b/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) From b02993c9895d34e84f2dbf156ee274ad6abf84c0 Mon Sep 17 00:00:00 2001 From: Grissiom Date: Tue, 11 Jun 2013 11:50:05 +0800 Subject: [PATCH 07/21] usbdevice/core: cope with some buggy drivers on USB_MSG_DATA_NOTIFY Some driver will emit USB_MSG_DATA_NOTIFY before the USB get configured. Filter out those events. --- components/drivers/usb/usbdevice/core/core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/drivers/usb/usbdevice/core/core.c b/components/drivers/usb/usbdevice/core/core.c index c2965d6bb2..48fc69895c 100644 --- a/components/drivers/usb/usbdevice/core/core.c +++ b/components/drivers/usb/usbdevice/core/core.c @@ -1447,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); From 9b949c28b7267ab46cb43abb427309770e64bf84 Mon Sep 17 00:00:00 2001 From: Grissiom Date: Thu, 6 Jun 2013 15:14:34 +0800 Subject: [PATCH 08/21] rm48x50: add cache_{enable, disable} --- libcpu/arm/cortex-r4/cpu.c | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/libcpu/arm/cortex-r4/cpu.c b/libcpu/arm/cortex-r4/cpu.c index 3aa7cd35de..d1b5c9df54 100644 --- a/libcpu/arm/cortex-r4/cpu.c +++ b/libcpu/arm/cortex-r4/cpu.c @@ -52,4 +52,43 @@ int __rt_ffs(int value) } #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 /*@}*/ From 2df7fc310f29927d0184947c07deab0030bc880e Mon Sep 17 00:00:00 2001 From: Grissiom Date: Wed, 12 Jun 2013 23:48:29 +0800 Subject: [PATCH 09/21] RM48 does not have cache implemented --- bsp/rm48x50/application/startup.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bsp/rm48x50/application/startup.c b/bsp/rm48x50/application/startup.c index 72d4ed795b..4b68910259 100644 --- a/bsp/rm48x50/application/startup.c +++ b/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(); From 009239ceeddcdbd4ce5ad573784143df1f485ee8 Mon Sep 17 00:00:00 2001 From: Grissiom Date: Wed, 12 Jun 2013 23:56:10 +0800 Subject: [PATCH 10/21] rm48x50: rt_interrupt_nest should be `volatile rt_uint8_t` --- libcpu/arm/cortex-r4/interrupt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcpu/arm/cortex-r4/interrupt.c b/libcpu/arm/cortex-r4/interrupt.c index 8d0a977db9..d001b509ee 100644 --- a/libcpu/arm/cortex-r4/interrupt.c +++ b/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; From 02869d7e6758231ca05776cc49582910db87972e Mon Sep 17 00:00:00 2001 From: heyuanjie87 Date: Sat, 15 Jun 2013 23:02:50 +0800 Subject: [PATCH 11/21] udisk can be eject --- .../drivers/include/drivers/usb_common.h | 1 + .../drivers/usb/usbdevice/class/mstorage.c | 43 ++++++++++++------- components/drivers/usb/usbdevice/core/core.c | 4 +- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/components/drivers/include/drivers/usb_common.h b/components/drivers/include/drivers/usb_common.h index d8d32d8306..68944f43ef 100644 --- a/components/drivers/include/drivers/usb_common.h +++ b/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 diff --git a/components/drivers/usb/usbdevice/class/mstorage.c b/components/drivers/usb/usbdevice/class/mstorage.c index b97be204c2..f43a7525f9 100644 --- a/components/drivers/usb/usbdevice/class/mstorage.c +++ b/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 { diff --git a/components/drivers/usb/usbdevice/core/core.c b/components/drivers/usb/usbdevice/core/core.c index 48fc69895c..2be6bd76a9 100644 --- a/components/drivers/usb/usbdevice/core/core.c +++ b/components/drivers/usb/usbdevice/core/core.c @@ -734,8 +734,8 @@ rt_err_t _reset_notify(udevice_t device) RT_ASSERT(device != RT_NULL); - _stop_notify(); - _run_notify(); + _stop_notify(device); + _run_notify(device); return RT_EOK; } From c56fa7c9072dc70c4644681231ce9214b8e4347f Mon Sep 17 00:00:00 2001 From: visitor83 Date: Sun, 16 Jun 2013 10:00:34 +0800 Subject: [PATCH 12/21] ident format Signed-off-by: visitor83 --- libcpu/arm/cortex-m3/cpuport.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/libcpu/arm/cortex-m3/cpuport.c b/libcpu/arm/cortex-m3/cpuport.c index c96073a6a9..b4dcad2e16 100644 --- a/libcpu/arm/cortex-m3/cpuport.c +++ b/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) + ; } /** From 7eb4120a8577ac28fc8fedfec9d1eb1976c60db6 Mon Sep 17 00:00:00 2001 From: aozima Date: Sun, 16 Jun 2013 23:05:10 +0800 Subject: [PATCH 13/21] fixed bug: scons: don't throw excptions when CPPDEFINES is not defined. --- tools/codeblocks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/codeblocks.py b/tools/codeblocks.py index f46f0f1f93..9a25114e97 100644 --- a/tools/codeblocks.py +++ b/tools/codeblocks.py @@ -75,7 +75,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) From fd289ff34f7006e8d9932e83e6eef2afdc601f5f Mon Sep 17 00:00:00 2001 From: aozima Date: Sun, 16 Jun 2013 23:18:16 +0800 Subject: [PATCH 14/21] add a default codeblocks template. --- tools/codeblocks.py | 6 +++++- tools/template.cbp | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tools/template.cbp diff --git a/tools/codeblocks.py b/tools/codeblocks.py index 9a25114e97..78f9629cbb 100644 --- a/tools/codeblocks.py +++ b/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') diff --git a/tools/template.cbp b/tools/template.cbp new file mode 100644 index 0000000000..ac21c8b54d --- /dev/null +++ b/tools/template.cbp @@ -0,0 +1,41 @@ + + + + + + From c986754c49bd43ef6030b3f5b1215c904fc1d855 Mon Sep 17 00:00:00 2001 From: visitor83 Date: Tue, 18 Jun 2013 12:51:55 +0800 Subject: [PATCH 16/21] Signed-off-by: visitor83 format the s3c24x0 serial.c and mini2440 rtconfig.py --- bsp/mini2440/rtconfig.py | 10 +- libcpu/arm/s3c24x0/context_gcc.S | 4 +- libcpu/arm/s3c24x0/serial.c | 406 ++++++++++++++++--------------- libcpu/arm/s3c24x0/start_gcc.S | 6 +- 4 files changed, 219 insertions(+), 207 deletions(-) diff --git a/bsp/mini2440/rtconfig.py b/bsp/mini2440/rtconfig.py index 6303a8d7ef..964030a19d 100644 --- a/bsp/mini2440/rtconfig.py +++ b/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!' diff --git a/libcpu/arm/s3c24x0/context_gcc.S b/libcpu/arm/s3c24x0/context_gcc.S index b45053e4cc..06bbd4488f 100644 --- a/libcpu/arm/s3c24x0/context_gcc.S +++ b/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 diff --git a/libcpu/arm/s3c24x0/serial.c b/libcpu/arm/s3c24x0/serial.c index 1e851c1ec5..9229805d22 100644 --- a/libcpu/arm/s3c24x0/serial.c +++ b/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 @@ -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; + struct serial_device* uart = (struct serial_device*) dev->user_data; - if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED)) - { + 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; - } + 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; + } - dev->flag |= RT_DEVICE_FLAG_ACTIVATED; - } + 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; + } - return RT_EOK; + 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(); + rt_base_t level; - 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; - } + /* disable interrupt */ + level = rt_hw_interrupt_disable(); - /* enable interrupt */ - rt_hw_interrupt_enable(level); + 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; + rt_uint8_t* ptr; + rt_err_t err_code; + struct serial_device* uart; - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - rt_base_t level; + ptr = buffer; + err_code = RT_EOK; + uart = (struct serial_device*)dev->user_data; - /* 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 --; + 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; - /* disable interrupt */ - level = rt_hw_interrupt_disable(); + /* 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 --; - uart->int_rx->read_index ++; - if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE) - uart->int_rx->read_index = 0; + /* disable interrupt */ + level = rt_hw_interrupt_disable(); - /* 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 ++; - } - } - } + uart->int_rx->read_index ++; + if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE) + uart->int_rx->read_index = 0; - /* set error code */ - rt_set_errno(err_code); - return (rt_uint32_t)ptr - (rt_uint32_t)buffer; + /* 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; + rt_uint8_t* ptr; + rt_err_t err_code; + struct serial_device* uart; - 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; + err_code = RT_EOK; + ptr = (rt_uint8_t*)buffer; + uart = (struct serial_device*)dev->user_data; - /* 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'; - } + 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++; - while (!(uart->uart_device->ustat & USTAT_TXB_EMPTY)); - uart->uart_device->utxh = (*ptr & 0xFF); + -- size; - ++ptr; --size; - } - } + /* move to next position */ + uart->int_tx->save_index ++; - /* set error code */ - rt_set_errno(err_code); - - return (rt_uint32_t)ptr - (rt_uint32_t)buffer; + /* 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); + 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; + 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); + 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; + 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); + /* 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); + struct serial_device* uart = (struct serial_device*) device->user_data; - /* save on rx buffer */ - while (uart->uart_device->ustat & USTAT_RCV_READY) - { - rt_serial_savechar(uart, uart->uart_device->urxh & 0xff); - } + /* interrupt mode receive */ + RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX); - /* 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; + /* save on rx buffer */ + while (uart->uart_device->ustat & USTAT_RCV_READY) + { + rt_serial_savechar(uart, uart->uart_device->urxh & 0xff); + } - device->rx_indicate(device, rx_length); - } + /* 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); + } } /*@}*/ diff --git a/libcpu/arm/s3c24x0/start_gcc.S b/libcpu/arm/s3c24x0/start_gcc.S index 72f5164053..142d66e2f4 100644 --- a/libcpu/arm/s3c24x0/start_gcc.S +++ b/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 From 3ee4a1850635f7d36bbbc78eecbf15364ecb14e6 Mon Sep 17 00:00:00 2001 From: Grissiom Date: Wed, 19 Jun 2013 17:57:22 +0800 Subject: [PATCH 17/21] tools: add an option to generate cscope database When --cscope option is given to Scons, it will generate a cscope cross-reference database in current directory, which is useful in Vim(and other cscope-aware text editors). For example, `scons -s --cscope` will do nothing except generating the database. You can use this option with other options together. It is inspired by the `make cscope` of Linux. --- tools/building.py | 9 +++++++++ tools/cscope.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 tools/cscope.py diff --git a/tools/building.py b/tools/building.py index a90ad69c1d..6b752674b5 100644 --- a/tools/building.py +++ b/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: diff --git a/tools/cscope.py b/tools/cscope.py new file mode 100644 index 0000000000..18568b4c35 --- /dev/null +++ b/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') + From f9e673354ab3cdfb0dd30f44d5098d2bccf26965 Mon Sep 17 00:00:00 2001 From: aozima Date: Tue, 18 Jun 2013 11:10:42 +0800 Subject: [PATCH 18/21] update libcpu/arm/cortex-m4: restore MSP. --- libcpu/arm/cortex-m4/context_gcc.S | 21 +++++++++++++++------ libcpu/arm/cortex-m4/context_iar.S | 9 +++++++++ libcpu/arm/cortex-m4/context_rvds.S | 13 +++++++++++-- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/libcpu/arm/cortex-m4/context_gcc.S b/libcpu/arm/cortex-m4/context_gcc.S index 97c3f1b44e..2fe9747d6f 100644 --- a/libcpu/arm/cortex-m4/context_gcc.S +++ b/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! */ diff --git a/libcpu/arm/cortex-m4/context_iar.S b/libcpu/arm/cortex-m4/context_iar.S index db3f370473..7943a211b5 100644 --- a/libcpu/arm/cortex-m4/context_iar.S +++ b/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! diff --git a/libcpu/arm/cortex-m4/context_rvds.S b/libcpu/arm/cortex-m4/context_rvds.S index ee72c44d01..768c176810 100644 --- a/libcpu/arm/cortex-m4/context_rvds.S +++ b/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 From 4d421cad733dd4abaa4f335f10905643c8ff5737 Mon Sep 17 00:00:00 2001 From: aozima Date: Tue, 18 Jun 2013 11:25:56 +0800 Subject: [PATCH 19/21] update libcpu/arm/cortex-m3: restore MSP. --- libcpu/arm/cortex-m3/context_gcc.S | 213 +++++++++++++++------------- libcpu/arm/cortex-m3/context_iar.S | 9 ++ libcpu/arm/cortex-m3/context_rvds.S | 9 ++ 3 files changed, 129 insertions(+), 102 deletions(-) diff --git a/libcpu/arm/cortex-m3/context_gcc.S b/libcpu/arm/cortex-m3/context_gcc.S index c0cf140daf..fad274aea8 100644 --- a/libcpu/arm/cortex-m3/context_gcc.S +++ b/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 + .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) */ + .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] - CPSIE I /* enable interrupts at processor level */ + /* restore MSP */ + LDR r0, =SCB_VTOR + LDR r0, [r0] + LDR r0, [r0] + NOP + MSR msp, r0 - /* never reach here! */ + CPSIE I /* enable interrupts at processor level */ + + /* 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 diff --git a/libcpu/arm/cortex-m3/context_iar.S b/libcpu/arm/cortex-m3/context_iar.S index 8152e5f40d..c27f02b512 100644 --- a/libcpu/arm/cortex-m3/context_iar.S +++ b/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! diff --git a/libcpu/arm/cortex-m3/context_rvds.S b/libcpu/arm/cortex-m3/context_rvds.S index 7f2e8e67d1..8b40c7cc48 100644 --- a/libcpu/arm/cortex-m3/context_rvds.S +++ b/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 From a2ff85c03f813f24138f58244087ee53d161ab1a Mon Sep 17 00:00:00 2001 From: aozima Date: Tue, 18 Jun 2013 11:34:54 +0800 Subject: [PATCH 20/21] update libcpu/arm/cortex-m0: restore MSP. --- libcpu/arm/cortex-m0/context_gcc.S | 9 +++++++++ libcpu/arm/cortex-m0/context_iar.S | 9 +++++++++ libcpu/arm/cortex-m0/context_rvds.S | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/libcpu/arm/cortex-m0/context_gcc.S b/libcpu/arm/cortex-m0/context_gcc.S index bd59a01e53..f875a07fd8 100644 --- a/libcpu/arm/cortex-m0/context_gcc.S +++ b/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! */ diff --git a/libcpu/arm/cortex-m0/context_iar.S b/libcpu/arm/cortex-m0/context_iar.S index 9b8a7dddb1..f1318e552d 100644 --- a/libcpu/arm/cortex-m0/context_iar.S +++ b/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 diff --git a/libcpu/arm/cortex-m0/context_rvds.S b/libcpu/arm/cortex-m0/context_rvds.S index 1194d8f4ae..9c2f42ac83 100644 --- a/libcpu/arm/cortex-m0/context_rvds.S +++ b/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 From 0633e9853c6ce4713a28812a1200a2f77a366a40 Mon Sep 17 00:00:00 2001 From: aozima Date: Sat, 22 Jun 2013 23:22:30 +0800 Subject: [PATCH 21/21] update iar.py: fixed bug when path is absolute. --- tools/iar.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/iar.py b/tools/iar.py index 040020aa6c..40b8408971 100644 --- a/tools/iar.py +++ b/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')