Merge branch 'master' of https://github.com/RT-Thread/rt-thread
This commit is contained in:
commit
c5927f51b3
|
@ -12,14 +12,14 @@ TextBase = '0x30000000'
|
||||||
CROSS_TOOL = 'gcc'
|
CROSS_TOOL = 'gcc'
|
||||||
|
|
||||||
if os.getenv('RTT_CC'):
|
if os.getenv('RTT_CC'):
|
||||||
CROSS_TOOL = os.getenv('RTT_CC')
|
CROSS_TOOL = os.getenv('RTT_CC')
|
||||||
|
|
||||||
if CROSS_TOOL == 'gcc':
|
if CROSS_TOOL == 'gcc':
|
||||||
PLATFORM = 'gcc'
|
PLATFORM = 'gcc'
|
||||||
EXEC_PATH = 'C:/Program Files/CodeSourcery/Sourcery G++ Lite/bin'
|
EXEC_PATH = 'C:/Program Files/CodeSourcery/Sourcery G++ Lite/bin'
|
||||||
elif CROSS_TOOL == 'keil':
|
elif CROSS_TOOL == 'keil':
|
||||||
PLATFORM = 'armcc'
|
PLATFORM = 'armcc'
|
||||||
EXEC_PATH = 'C:/Keil'
|
EXEC_PATH = 'C:/Keil'
|
||||||
elif CROSS_TOOL == 'iar':
|
elif CROSS_TOOL == 'iar':
|
||||||
print '================ERROR============================'
|
print '================ERROR============================'
|
||||||
print 'Not support iar yet!'
|
print 'Not support iar yet!'
|
||||||
|
|
|
@ -17,9 +17,6 @@
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "het.h"
|
#include "het.h"
|
||||||
|
|
||||||
int ulRegTest1Counter;
|
|
||||||
int ulRegTest2Counter;
|
|
||||||
|
|
||||||
static rt_uint8_t user_thread_stack[512];
|
static rt_uint8_t user_thread_stack[512];
|
||||||
static struct rt_thread user_thread;
|
static struct rt_thread user_thread;
|
||||||
static void user_thread_entry(void *p)
|
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()
|
int rt_application_init()
|
||||||
{
|
{
|
||||||
rt_thread_init(&user_thread, "user1", user_thread_entry, RT_NULL,
|
rt_thread_init(&user_thread, "user1", user_thread_entry, RT_NULL,
|
||||||
user_thread_stack, sizeof(user_thread_stack), 21, 20);
|
user_thread_stack, sizeof(user_thread_stack), 21, 20);
|
||||||
rt_thread_startup(&user_thread);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
||||||
;-------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,11 @@ extern unsigned char * const system_data_end;
|
||||||
*/
|
*/
|
||||||
void rtthread_startup(void)
|
void rtthread_startup(void)
|
||||||
{
|
{
|
||||||
|
/*// RM48 does not have cache implemented
|
||||||
|
*rt_hw_cpu_icache_enable();
|
||||||
|
*rt_hw_cpu_dcache_enable();
|
||||||
|
*/
|
||||||
|
|
||||||
/* init hardware interrupt */
|
/* init hardware interrupt */
|
||||||
rt_hw_interrupt_init();
|
rt_hw_interrupt_init();
|
||||||
|
|
||||||
|
|
|
@ -212,6 +212,7 @@
|
||||||
// </section>
|
// </section>
|
||||||
|
|
||||||
#define RT_VFP_LAZY_STACKING
|
#define RT_VFP_LAZY_STACKING
|
||||||
|
#define RT_USING_CPU_FFS
|
||||||
// </RDTConfigurator>
|
// </RDTConfigurator>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,9 +33,6 @@ objs = PrepareBuilding(env, RTT_ROOT)
|
||||||
# STM32 firemare library building script
|
# STM32 firemare library building script
|
||||||
objs = objs + SConscript( GetCurrentDir() + '/Libraries/SConscript', variant_dir='build/bsp/Libraries', duplicate=0)
|
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
|
# build program
|
||||||
env.Program(TARGET, objs)
|
env.Program(TARGET, objs)
|
||||||
|
|
||||||
|
|
|
@ -368,6 +368,7 @@ typedef struct ureqest* ureq_t;
|
||||||
#define SCSI_INQUIRY_CMD 0x12
|
#define SCSI_INQUIRY_CMD 0x12
|
||||||
#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e
|
#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e
|
||||||
#define SCSI_MODE_SENSE_6 0x1a
|
#define SCSI_MODE_SENSE_6 0x1a
|
||||||
|
#define SCSI_START_STOP 0x1b
|
||||||
#define SCSI_READ_CAPACITIES 0x23
|
#define SCSI_READ_CAPACITIES 0x23
|
||||||
#define SCSI_READ_CAPACITY 0x25
|
#define SCSI_READ_CAPACITY 0x25
|
||||||
#define SCSI_READ_10 0x28
|
#define SCSI_READ_10 0x28
|
||||||
|
|
|
@ -146,6 +146,11 @@ enum udev_msg_type
|
||||||
USB_MSG_DATA_NOTIFY,
|
USB_MSG_DATA_NOTIFY,
|
||||||
USB_MSG_SOF,
|
USB_MSG_SOF,
|
||||||
USB_MSG_RESET,
|
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;
|
typedef enum udev_msg_type udev_msg_type;
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ static rt_device_t disk;
|
||||||
static rt_uint32_t _block;
|
static rt_uint32_t _block;
|
||||||
static rt_uint32_t _count, _size;
|
static rt_uint32_t _count, _size;
|
||||||
static struct rt_device_blk_geometry geometry;
|
static struct rt_device_blk_geometry geometry;
|
||||||
|
static rt_uint32_t _removed = 0;
|
||||||
|
|
||||||
static struct udevice_descriptor dev_desc =
|
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.ErrorCode = 0x70;
|
||||||
data.Valid = 0;
|
data.Valid = 0;
|
||||||
data.SenseKey = 5;
|
data.SenseKey = 2; //TODO
|
||||||
data.Information[0] = 0;
|
data.Information[0] = 0;
|
||||||
data.Information[1] = 0;
|
data.Information[1] = 0;
|
||||||
data.Information[2] = 0;
|
data.Information[2] = 0;
|
||||||
data.Information[3] = 0;
|
data.Information[3] = 0;
|
||||||
data.AdditionalSenseLength = 0x0b;
|
data.AdditionalSenseLength = 0x0a;
|
||||||
data.AdditionalSenseCode = 0x20;
|
data.AdditionalSenseCode = 0x3a; //TODO
|
||||||
data.AdditionalSenseCodeQualifier =0;
|
data.AdditionalSenseCodeQualifier =0;
|
||||||
|
|
||||||
dcd_ep_write(device->dcd, ep_in, (rt_uint8_t*)&data, sizeof(struct request_sense_data));
|
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;
|
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.
|
* 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);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
eps = cls->eps;
|
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);
|
_send_status(device, eps, &csw);
|
||||||
status = STATUS_CBW;
|
|
||||||
dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
|
|
||||||
}
|
}
|
||||||
if(status == STATUS_SEND)
|
else if (status == STATUS_SEND)
|
||||||
{
|
{
|
||||||
rt_device_read(disk, _block, eps->ep_in->buffer, 1);
|
rt_device_read(disk, _block, eps->ep_in->buffer, 1);
|
||||||
dcd_ep_write(device->dcd, eps->ep_in, eps->ep_in->buffer,
|
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])
|
switch(cbw->cb[0])
|
||||||
{
|
{
|
||||||
case SCSI_TEST_UNIT_READY:
|
case SCSI_TEST_UNIT_READY:
|
||||||
dcd_ep_write(device->dcd, eps->ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
|
csw.status = _removed;
|
||||||
dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
|
_send_status(device, eps, &csw);
|
||||||
break;
|
break;
|
||||||
case SCSI_REQUEST_SENSE:
|
case SCSI_REQUEST_SENSE:
|
||||||
_request_sense(device, eps->ep_in);
|
_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;
|
status = STATUS_CSW;
|
||||||
break;
|
break;
|
||||||
case SCSI_ALLOW_MEDIUM_REMOVAL:
|
case SCSI_ALLOW_MEDIUM_REMOVAL:
|
||||||
dcd_ep_write(device->dcd, eps->ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
|
_send_status(device, eps, &csw);
|
||||||
dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
|
|
||||||
break;
|
break;
|
||||||
case SCSI_READ_CAPACITIES:
|
case SCSI_READ_CAPACITIES:
|
||||||
_read_capacities(device, eps->ep_in);
|
_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:
|
case SCSI_VERIFY_10:
|
||||||
_verify_10(device);
|
_verify_10(device);
|
||||||
break;
|
break;
|
||||||
|
case SCSI_START_STOP:
|
||||||
|
_start_stop(cbw);
|
||||||
|
_send_status(device, eps, &csw);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(status == STATUS_RECEIVE)
|
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 ++;
|
_block ++;
|
||||||
if(_size == 0)
|
if(_size == 0)
|
||||||
{
|
{
|
||||||
dcd_ep_write(device->dcd, eps->ep_in, (rt_uint8_t*)&csw, SIZEOF_CSW);
|
_send_status(device, eps, &csw);
|
||||||
dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW);
|
|
||||||
status = STATUS_CBW;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -666,6 +666,60 @@ rt_err_t _sof_notify(udevice_t device)
|
||||||
return RT_EOK;
|
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.
|
* This function will reset all class.
|
||||||
*
|
*
|
||||||
|
@ -680,17 +734,8 @@ rt_err_t _reset_notify(udevice_t device)
|
||||||
|
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
/* to notity every class that sof event comes */
|
_stop_notify(device);
|
||||||
for (i=device->curr_cfg->cls_list.next;
|
_run_notify(device);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
@ -1402,6 +1447,10 @@ static void rt_usbd_thread_entry(void* parameter)
|
||||||
_sof_notify(device);
|
_sof_notify(device);
|
||||||
break;
|
break;
|
||||||
case USB_MSG_DATA_NOTIFY:
|
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);
|
ep = rt_usbd_find_endpoint(device, &cls, msg.content.ep_msg.ep_addr);
|
||||||
if(ep != RT_NULL)
|
if(ep != RT_NULL)
|
||||||
ep->handler(device, cls, msg.content.ep_msg.size);
|
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)
|
if (device->state == USB_STATE_ADDRESS)
|
||||||
_reset_notify(device);
|
_reset_notify(device);
|
||||||
break;
|
break;
|
||||||
|
case USB_MSG_PLUG_OUT:
|
||||||
|
_stop_notify(device);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
rt_kprintf("unknown msg type\n");
|
rt_kprintf("unknown msg type\n");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -147,6 +147,17 @@ typedef rt_base_t rt_off_t; /**< Type for offset */
|
||||||
#define ALIGN(n) __declspec(align(n))
|
#define ALIGN(n) __declspec(align(n))
|
||||||
#define rt_inline static __inline
|
#define rt_inline static __inline
|
||||||
#define RTT_API
|
#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
|
#endif
|
||||||
|
|
||||||
/* initialization export */
|
/* initialization export */
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* 2012-06-01 aozima set pendsv priority to 0xFF.
|
* 2012-06-01 aozima set pendsv priority to 0xFF.
|
||||||
* 2012-08-17 aozima fixed bug: store r8 - r11.
|
* 2012-08-17 aozima fixed bug: store r8 - r11.
|
||||||
* 2013-02-20 aozima port to gcc.
|
* 2013-02-20 aozima port to gcc.
|
||||||
|
* 2013-06-18 aozima add restore MSP feature.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.cpu cortex-m3
|
.cpu cortex-m3
|
||||||
|
@ -21,6 +22,7 @@
|
||||||
.thumb
|
.thumb
|
||||||
.text
|
.text
|
||||||
|
|
||||||
|
.equ SCB_VTOR, 0xE000ED04 /* Vector Table Offset Register */
|
||||||
.equ ICSR, 0xE000ED04 /* interrupt control state register */
|
.equ ICSR, 0xE000ED04 /* interrupt control state register */
|
||||||
.equ PENDSVSET_BIT, 0x10000000 /* value to trigger PendSV exception */
|
.equ PENDSVSET_BIT, 0x10000000 /* value to trigger PendSV exception */
|
||||||
|
|
||||||
|
@ -152,6 +154,13 @@ rt_hw_context_switch_to:
|
||||||
LDR R1, =PENDSVSET_BIT
|
LDR R1, =PENDSVSET_BIT
|
||||||
STR R1, [R0]
|
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! */
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
; * 2010-01-25 Bernard first version
|
; * 2010-01-25 Bernard first version
|
||||||
; * 2012-06-01 aozima set pendsv priority to 0xFF.
|
; * 2012-06-01 aozima set pendsv priority to 0xFF.
|
||||||
; * 2012-08-17 aozima fixed bug: store r8 - r11.
|
; * 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_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
|
||||||
NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
|
NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
|
||||||
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
|
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
|
||||||
|
@ -178,6 +180,13 @@ rt_hw_context_switch_to:
|
||||||
STR r1, [r0]
|
STR r1, [r0]
|
||||||
NOP
|
NOP
|
||||||
|
|
||||||
|
; restore MSP
|
||||||
|
LDR r0, =SCB_VTOR
|
||||||
|
LDR r0, [r0]
|
||||||
|
LDR r0, [r0]
|
||||||
|
NOP
|
||||||
|
MSR msp, r0
|
||||||
|
|
||||||
; enable interrupts at processor level
|
; enable interrupts at processor level
|
||||||
CPSIE I
|
CPSIE I
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
; * 2010-01-25 Bernard first version
|
; * 2010-01-25 Bernard first version
|
||||||
; * 2012-06-01 aozima set pendsv priority to 0xFF.
|
; * 2012-06-01 aozima set pendsv priority to 0xFF.
|
||||||
; * 2012-08-17 aozima fixed bug: store r8 - r11.
|
; * 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_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
|
||||||
NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
|
NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
|
||||||
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
|
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
|
||||||
|
@ -183,6 +185,13 @@ rt_hw_context_switch_to PROC
|
||||||
STR r1, [r0]
|
STR r1, [r0]
|
||||||
NOP
|
NOP
|
||||||
|
|
||||||
|
; restore MSP
|
||||||
|
LDR r0, =SCB_VTOR
|
||||||
|
LDR r0, [r0]
|
||||||
|
LDR r0, [r0]
|
||||||
|
NOP
|
||||||
|
MSR msp, r0
|
||||||
|
|
||||||
; enable interrupts at processor level
|
; enable interrupts at processor level
|
||||||
CPSIE I
|
CPSIE I
|
||||||
|
|
||||||
|
|
|
@ -10,161 +10,170 @@
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2009-10-11 Bernard First version
|
* 2009-10-11 Bernard First version
|
||||||
* 2010-12-29 onelife Modify for EFM32
|
* 2010-12-29 onelife Modify for EFM32
|
||||||
* 2011-06-17 onelife Merge all of the assembly source code into context_gcc.S
|
* 2011-06-17 onelife Merge all of the assembly source code into context_gcc.S
|
||||||
* 2011-07-12 onelife Add interrupt context check function
|
* 2011-07-12 onelife Add interrupt context check function
|
||||||
|
* 2013-06-18 aozima add restore MSP feature.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.cpu cortex-m3
|
.cpu cortex-m3
|
||||||
.fpu softvfp
|
.fpu softvfp
|
||||||
.syntax unified
|
.syntax unified
|
||||||
.thumb
|
.thumb
|
||||||
.text
|
.text
|
||||||
|
|
||||||
.equ ICSR, 0xE000ED04 /* interrupt control state register */
|
.equ SCB_VTOR, 0xE000ED04 /* Vector Table Offset Register */
|
||||||
.equ PENDSVSET_BIT, 0x10000000 /* value to trigger PendSV exception */
|
.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 SHPR3, 0xE000ED20 /* system priority register (3) */
|
||||||
|
.equ PENDSV_PRI_LOWEST, 0x00FF0000 /* PendSV priority value (lowest) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rt_base_t rt_hw_interrupt_disable();
|
* rt_base_t rt_hw_interrupt_disable();
|
||||||
*/
|
*/
|
||||||
.global rt_hw_interrupt_disable
|
.global rt_hw_interrupt_disable
|
||||||
.type rt_hw_interrupt_disable, %function
|
.type rt_hw_interrupt_disable, %function
|
||||||
rt_hw_interrupt_disable:
|
rt_hw_interrupt_disable:
|
||||||
MRS R0, PRIMASK
|
MRS R0, PRIMASK
|
||||||
CPSID I
|
CPSID I
|
||||||
BX LR
|
BX LR
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void rt_hw_interrupt_enable(rt_base_t level);
|
* void rt_hw_interrupt_enable(rt_base_t level);
|
||||||
*/
|
*/
|
||||||
.global rt_hw_interrupt_enable
|
.global rt_hw_interrupt_enable
|
||||||
.type rt_hw_interrupt_enable, %function
|
.type rt_hw_interrupt_enable, %function
|
||||||
rt_hw_interrupt_enable:
|
rt_hw_interrupt_enable:
|
||||||
MSR PRIMASK, R0
|
MSR PRIMASK, R0
|
||||||
BX LR
|
BX LR
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
|
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
|
||||||
* R0 --> from
|
* R0 --> from
|
||||||
* R1 --> to
|
* R1 --> to
|
||||||
*/
|
*/
|
||||||
.global rt_hw_context_switch_interrupt
|
.global rt_hw_context_switch_interrupt
|
||||||
.type rt_hw_context_switch_interrupt, %function
|
.type rt_hw_context_switch_interrupt, %function
|
||||||
.global rt_hw_context_switch
|
.global rt_hw_context_switch
|
||||||
.type rt_hw_context_switch, %function
|
.type rt_hw_context_switch, %function
|
||||||
rt_hw_context_switch_interrupt:
|
rt_hw_context_switch_interrupt:
|
||||||
rt_hw_context_switch:
|
rt_hw_context_switch:
|
||||||
/* set rt_thread_switch_interrupt_flag to 1 */
|
/* set rt_thread_switch_interrupt_flag to 1 */
|
||||||
LDR R2, =rt_thread_switch_interrupt_flag
|
LDR R2, =rt_thread_switch_interrupt_flag
|
||||||
LDR R3, [R2]
|
LDR R3, [R2]
|
||||||
CMP R3, #1
|
CMP R3, #1
|
||||||
BEQ _reswitch
|
BEQ _reswitch
|
||||||
MOV R3, #1
|
MOV R3, #1
|
||||||
STR R3, [R2]
|
STR R3, [R2]
|
||||||
|
|
||||||
LDR R2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */
|
LDR R2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */
|
||||||
STR R0, [R2]
|
STR R0, [R2]
|
||||||
|
|
||||||
_reswitch:
|
_reswitch:
|
||||||
LDR R2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */
|
LDR R2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */
|
||||||
STR R1, [R2]
|
STR R1, [R2]
|
||||||
|
|
||||||
LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */
|
LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */
|
||||||
LDR R1, =PENDSVSET_BIT
|
LDR R1, =PENDSVSET_BIT
|
||||||
STR R1, [R0]
|
STR R1, [R0]
|
||||||
BX LR
|
BX LR
|
||||||
|
|
||||||
/* R0 --> swith from thread stack
|
/* R0 --> swith from thread stack
|
||||||
* R1 --> swith to thread stack
|
* R1 --> swith to thread stack
|
||||||
* psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack
|
* psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack
|
||||||
*/
|
*/
|
||||||
.global PendSV_Handler
|
.global PendSV_Handler
|
||||||
.type PendSV_Handler, %function
|
.type PendSV_Handler, %function
|
||||||
PendSV_Handler:
|
PendSV_Handler:
|
||||||
/* disable interrupt to protect context switch */
|
/* disable interrupt to protect context switch */
|
||||||
MRS R2, PRIMASK
|
MRS R2, PRIMASK
|
||||||
CPSID I
|
CPSID I
|
||||||
|
|
||||||
/* get rt_thread_switch_interrupt_flag */
|
/* get rt_thread_switch_interrupt_flag */
|
||||||
LDR R0, =rt_thread_switch_interrupt_flag
|
LDR R0, =rt_thread_switch_interrupt_flag
|
||||||
LDR R1, [R0]
|
LDR R1, [R0]
|
||||||
CBZ R1, pendsv_exit /* pendsv aLReady handled */
|
CBZ R1, pendsv_exit /* pendsv aLReady handled */
|
||||||
|
|
||||||
/* clear rt_thread_switch_interrupt_flag to 0 */
|
/* clear rt_thread_switch_interrupt_flag to 0 */
|
||||||
MOV R1, #0
|
MOV R1, #0
|
||||||
STR R1, [R0]
|
STR R1, [R0]
|
||||||
|
|
||||||
LDR R0, =rt_interrupt_from_thread
|
LDR R0, =rt_interrupt_from_thread
|
||||||
LDR R1, [R0]
|
LDR R1, [R0]
|
||||||
CBZ R1, swtich_to_thread /* skip register save at the first time */
|
CBZ R1, swtich_to_thread /* skip register save at the first time */
|
||||||
|
|
||||||
MRS R1, PSP /* get from thread stack pointer */
|
MRS R1, PSP /* get from thread stack pointer */
|
||||||
STMFD R1!, {R4 - R11} /* push R4 - R11 register */
|
STMFD R1!, {R4 - R11} /* push R4 - R11 register */
|
||||||
LDR R0, [R0]
|
LDR R0, [R0]
|
||||||
STR R1, [R0] /* update from thread stack pointer */
|
STR R1, [R0] /* update from thread stack pointer */
|
||||||
|
|
||||||
swtich_to_thread:
|
swtich_to_thread:
|
||||||
LDR R1, =rt_interrupt_to_thread
|
LDR R1, =rt_interrupt_to_thread
|
||||||
LDR R1, [R1]
|
LDR R1, [R1]
|
||||||
LDR R1, [R1] /* load thread stack pointer */
|
LDR R1, [R1] /* load thread stack pointer */
|
||||||
|
|
||||||
LDMFD R1!, {R4 - R11} /* pop R4 - R11 register */
|
LDMFD R1!, {R4 - R11} /* pop R4 - R11 register */
|
||||||
MSR PSP, R1 /* update stack pointer */
|
MSR PSP, R1 /* update stack pointer */
|
||||||
|
|
||||||
pendsv_exit:
|
pendsv_exit:
|
||||||
/* restore interrupt */
|
/* restore interrupt */
|
||||||
MSR PRIMASK, R2
|
MSR PRIMASK, R2
|
||||||
|
|
||||||
ORR LR, LR, #0x04
|
ORR LR, LR, #0x04
|
||||||
BX LR
|
BX LR
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void rt_hw_context_switch_to(rt_uint32 to);
|
* void rt_hw_context_switch_to(rt_uint32 to);
|
||||||
* R0 --> to
|
* R0 --> to
|
||||||
*/
|
*/
|
||||||
.global rt_hw_context_switch_to
|
.global rt_hw_context_switch_to
|
||||||
.type rt_hw_context_switch_to, %function
|
.type rt_hw_context_switch_to, %function
|
||||||
rt_hw_context_switch_to:
|
rt_hw_context_switch_to:
|
||||||
LDR R1, =rt_interrupt_to_thread
|
LDR R1, =rt_interrupt_to_thread
|
||||||
STR R0, [R1]
|
STR R0, [R1]
|
||||||
|
|
||||||
/* set from thread to 0 */
|
/* set from thread to 0 */
|
||||||
LDR R1, =rt_interrupt_from_thread
|
LDR R1, =rt_interrupt_from_thread
|
||||||
MOV R0, #0
|
MOV R0, #0
|
||||||
STR R0, [R1]
|
STR R0, [R1]
|
||||||
|
|
||||||
/* set interrupt flag to 1 */
|
/* set interrupt flag to 1 */
|
||||||
LDR R1, =rt_thread_switch_interrupt_flag
|
LDR R1, =rt_thread_switch_interrupt_flag
|
||||||
MOV R0, #1
|
MOV R0, #1
|
||||||
STR R0, [R1]
|
STR R0, [R1]
|
||||||
|
|
||||||
/* set the PendSV exception priority */
|
/* set the PendSV exception priority */
|
||||||
LDR R0, =SHPR3
|
LDR R0, =SHPR3
|
||||||
LDR R1, =PENDSV_PRI_LOWEST
|
LDR R1, =PENDSV_PRI_LOWEST
|
||||||
LDR.W R2, [R0,#0] /* read */
|
LDR.W R2, [R0,#0] /* read */
|
||||||
ORR R1, R1, R2 /* modify */
|
ORR R1, R1, R2 /* modify */
|
||||||
STR R1, [R0] /* write-back */
|
STR R1, [R0] /* write-back */
|
||||||
|
|
||||||
LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */
|
LDR R0, =ICSR /* trigger the PendSV exception (causes context switch) */
|
||||||
LDR R1, =PENDSVSET_BIT
|
LDR R1, =PENDSVSET_BIT
|
||||||
STR R1, [R0]
|
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 */
|
/* compatible with old version */
|
||||||
.global rt_hw_interrupt_thread_switch
|
.global rt_hw_interrupt_thread_switch
|
||||||
.type rt_hw_interrupt_thread_switch, %function
|
.type rt_hw_interrupt_thread_switch, %function
|
||||||
rt_hw_interrupt_thread_switch:
|
rt_hw_interrupt_thread_switch:
|
||||||
BX LR
|
BX LR
|
||||||
NOP
|
NOP
|
||||||
|
|
||||||
.global HardFault_Handler
|
.global HardFault_Handler
|
||||||
.type HardFault_Handler, %function
|
.type HardFault_Handler, %function
|
||||||
HardFault_Handler:
|
HardFault_Handler:
|
||||||
/* get current context */
|
/* get current context */
|
||||||
MRS R0, PSP /* get fault thread stack pointer */
|
MRS R0, PSP /* get fault thread stack pointer */
|
||||||
|
@ -179,8 +188,8 @@ HardFault_Handler:
|
||||||
* rt_uint32_t rt_hw_interrupt_check(void);
|
* rt_uint32_t rt_hw_interrupt_check(void);
|
||||||
* R0 --> state
|
* R0 --> state
|
||||||
*/
|
*/
|
||||||
.global rt_hw_interrupt_check
|
.global rt_hw_interrupt_check
|
||||||
.type rt_hw_interrupt_check, %function
|
.type rt_hw_interrupt_check, %function
|
||||||
rt_hw_interrupt_check:
|
rt_hw_interrupt_check:
|
||||||
MRS R0, IPSR
|
MRS R0, IPSR
|
||||||
BX LR
|
BX LR
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
; * Date Author Notes
|
; * Date Author Notes
|
||||||
; * 2009-01-17 Bernard first version
|
; * 2009-01-17 Bernard first version
|
||||||
; * 2009-09-27 Bernard add protect when contex switch occurs
|
; * 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_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
|
||||||
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
|
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
|
||||||
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
|
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
|
||||||
|
@ -151,6 +153,13 @@ rt_hw_context_switch_to:
|
||||||
LDR r1, =NVIC_PENDSVSET
|
LDR r1, =NVIC_PENDSVSET
|
||||||
STR r1, [r0]
|
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!
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
; * Change Logs:
|
; * Change Logs:
|
||||||
; * Date Author Notes
|
; * Date Author Notes
|
||||||
; * 2009-01-17 Bernard first version
|
; * 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_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
|
||||||
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
|
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
|
||||||
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
|
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
|
||||||
|
@ -158,6 +160,13 @@ rt_hw_context_switch_to PROC
|
||||||
LDR r1, =NVIC_PENDSVSET
|
LDR r1, =NVIC_PENDSVSET
|
||||||
STR r1, [r0]
|
STR r1, [r0]
|
||||||
|
|
||||||
|
; restore MSP
|
||||||
|
LDR r0, =SCB_VTOR
|
||||||
|
LDR r0, [r0]
|
||||||
|
LDR r0, [r0]
|
||||||
|
NOP
|
||||||
|
MSR msp, r0
|
||||||
|
|
||||||
; enable interrupts at processor level
|
; enable interrupts at processor level
|
||||||
CPSIE I
|
CPSIE I
|
||||||
|
|
||||||
|
|
|
@ -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))
|
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)
|
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)
|
if (rt_exception_hook != RT_NULL)
|
||||||
{
|
{
|
||||||
rt_err_t result;
|
rt_err_t result;
|
||||||
|
|
||||||
result = rt_exception_hook(context);
|
result = rt_exception_hook(context);
|
||||||
if (result == RT_EOK) return;
|
if (result == RT_EOK)
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rt_kprintf("psr: 0x%08x\n", context->psr);
|
rt_kprintf("psr: 0x%08x\n", context->psr);
|
||||||
rt_kprintf(" pc: 0x%08x\n", context->pc);
|
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();
|
list_thread();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (1);
|
while (1)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2009-10-11 Bernard first version
|
* 2009-10-11 Bernard first version
|
||||||
* 2012-01-01 aozima support context switch load/store FPU register.
|
* 2012-01-01 aozima support context switch load/store FPU register.
|
||||||
|
* 2013-06-18 aozima add restore MSP feature.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,10 +24,11 @@
|
||||||
.thumb
|
.thumb
|
||||||
.text
|
.text
|
||||||
|
|
||||||
.equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */
|
.equ SCB_VTOR, 0xE000ED04 /* Vector Table Offset Register */
|
||||||
.equ NVIC_SYSPRI2, 0xE000ED20 /* system priority register (2) */
|
.equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */
|
||||||
.equ NVIC_PENDSV_PRI, 0x00FF0000 /* PendSV priority value (lowest) */
|
.equ NVIC_SYSPRI2, 0xE000ED20 /* system priority register (2) */
|
||||||
.equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */
|
.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();
|
* rt_base_t rt_hw_interrupt_disable();
|
||||||
|
@ -106,9 +108,9 @@ PendSV_Handler:
|
||||||
MRS r1, psp /* get from thread stack pointer */
|
MRS r1, psp /* get from thread stack pointer */
|
||||||
|
|
||||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
#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
|
#endif
|
||||||
|
|
||||||
STMFD r1!, {r4 - r11} /* push r4 - r11 register */
|
STMFD r1!, {r4 - r11} /* push r4 - r11 register */
|
||||||
LDR r0, [r0]
|
LDR r0, [r0]
|
||||||
STR r1, [r0] /* update from thread stack pointer */
|
STR r1, [r0] /* update from thread stack pointer */
|
||||||
|
@ -164,6 +166,13 @@ rt_hw_context_switch_to:
|
||||||
LDR r1, =NVIC_PENDSVSET
|
LDR r1, =NVIC_PENDSVSET
|
||||||
STR r1, [r0]
|
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! */
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
; * 2009-01-17 Bernard first version
|
; * 2009-01-17 Bernard first version
|
||||||
; * 2009-09-27 Bernard add protect when contex switch occurs
|
; * 2009-09-27 Bernard add protect when contex switch occurs
|
||||||
; * 2012-01-01 aozima support context switch load/store FPU register.
|
; * 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_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
|
||||||
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
|
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
|
||||||
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
|
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
|
||||||
|
@ -162,6 +164,13 @@ rt_hw_context_switch_to:
|
||||||
LDR r1, =NVIC_PENDSVSET
|
LDR r1, =NVIC_PENDSVSET
|
||||||
STR r1, [r0]
|
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!
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
; * Date Author Notes
|
; * Date Author Notes
|
||||||
; * 2009-01-17 Bernard first version.
|
; * 2009-01-17 Bernard first version.
|
||||||
; * 2012-01-01 aozima support context switch load/store FPU register.
|
; * 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_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
|
||||||
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
|
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
|
||||||
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
|
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
|
||||||
|
@ -108,10 +110,10 @@ PendSV_Handler PROC
|
||||||
MRS r1, psp ; get from thread stack pointer
|
MRS r1, psp ; get from thread stack pointer
|
||||||
|
|
||||||
IF {FPU} != "SoftVFP"
|
IF {FPU} != "SoftVFP"
|
||||||
VSTMFD r1!, {d8 - d15} ; push FPU register s16~s31
|
VSTMFD r1!, {d8 - d15} ; push FPU register s16~s31
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
STMFD r1!, {r4 - r11} ; push r4 - r11 register
|
STMFD r1!, {r4 - r11} ; push r4 - r11 register
|
||||||
LDR r0, [r0]
|
LDR r0, [r0]
|
||||||
STR r1, [r0] ; update from thread stack pointer
|
STR r1, [r0] ; update from thread stack pointer
|
||||||
|
|
||||||
|
@ -169,6 +171,13 @@ rt_hw_context_switch_to PROC
|
||||||
LDR r1, =NVIC_PENDSVSET
|
LDR r1, =NVIC_PENDSVSET
|
||||||
STR r1, [r0]
|
STR r1, [r0]
|
||||||
|
|
||||||
|
; restore MSP
|
||||||
|
LDR r0, =SCB_VTOR
|
||||||
|
LDR r0, [r0]
|
||||||
|
LDR r0, [r0]
|
||||||
|
NOP
|
||||||
|
MSR msp, r0
|
||||||
|
|
||||||
; enable interrupts at processor level
|
; enable interrupts at processor level
|
||||||
CPSIE I
|
CPSIE I
|
||||||
|
|
||||||
|
|
|
@ -28,18 +28,22 @@
|
||||||
; * rt_base_t rt_hw_interrupt_disable();
|
; * rt_base_t rt_hw_interrupt_disable();
|
||||||
; */
|
; */
|
||||||
.def rt_hw_interrupt_disable
|
.def rt_hw_interrupt_disable
|
||||||
|
.asmfunc
|
||||||
rt_hw_interrupt_disable
|
rt_hw_interrupt_disable
|
||||||
MRS r0, cpsr
|
MRS r0, cpsr
|
||||||
CPSID IF
|
CPSID IF
|
||||||
BX lr
|
BX lr
|
||||||
|
.endasmfunc
|
||||||
|
|
||||||
;/*
|
;/*
|
||||||
; * void rt_hw_interrupt_enable(rt_base_t level);
|
; * void rt_hw_interrupt_enable(rt_base_t level);
|
||||||
; */
|
; */
|
||||||
.def rt_hw_interrupt_enable
|
.def rt_hw_interrupt_enable
|
||||||
|
.asmfunc
|
||||||
rt_hw_interrupt_enable
|
rt_hw_interrupt_enable
|
||||||
MSR cpsr_c, r0
|
MSR cpsr_c, r0
|
||||||
BX lr
|
BX lr
|
||||||
|
.endasmfunc
|
||||||
|
|
||||||
;/*
|
;/*
|
||||||
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
|
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
|
||||||
|
@ -47,6 +51,7 @@ rt_hw_interrupt_enable
|
||||||
; * r1 --> to
|
; * r1 --> to
|
||||||
; */
|
; */
|
||||||
.def rt_hw_context_switch
|
.def rt_hw_context_switch
|
||||||
|
.asmfunc
|
||||||
rt_hw_context_switch
|
rt_hw_context_switch
|
||||||
STMDB sp!, {lr} ; push pc (lr should be pushed in place of PC)
|
STMDB sp!, {lr} ; push pc (lr should be pushed in place of PC)
|
||||||
STMDB sp!, {r0-r12, lr} ; push lr & register file
|
STMDB sp!, {r0-r12, lr} ; push lr & register file
|
||||||
|
@ -88,12 +93,14 @@ __no_vfp_frame2
|
||||||
MSR spsr_cxsf, r4
|
MSR spsr_cxsf, r4
|
||||||
|
|
||||||
LDMIA sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc, copy spsr to cpsr
|
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);
|
; * void rt_hw_context_switch_to(rt_uint32 to);
|
||||||
; * r0 --> to
|
; * r0 --> to
|
||||||
; */
|
; */
|
||||||
.def rt_hw_context_switch_to
|
.def rt_hw_context_switch_to
|
||||||
|
.asmfunc
|
||||||
rt_hw_context_switch_to
|
rt_hw_context_switch_to
|
||||||
LDR sp, [r0] ; get new task stack pointer
|
LDR sp, [r0] ; get new task stack pointer
|
||||||
|
|
||||||
|
@ -112,12 +119,14 @@ __no_vfp_frame_to
|
||||||
MSR spsr_cxsf, r4
|
MSR spsr_cxsf, r4
|
||||||
|
|
||||||
LDMIA sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc, copy spsr to cpsr
|
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);
|
; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
|
||||||
; */
|
; */
|
||||||
|
|
||||||
.def rt_hw_context_switch_interrupt
|
.def rt_hw_context_switch_interrupt
|
||||||
|
.asmfunc
|
||||||
rt_hw_context_switch_interrupt
|
rt_hw_context_switch_interrupt
|
||||||
LDR r2, pintflag
|
LDR r2, pintflag
|
||||||
LDR r3, [r2]
|
LDR r3, [r2]
|
||||||
|
@ -131,6 +140,7 @@ _reswitch
|
||||||
LDR r2, ptothread ; set rt_interrupt_to_thread
|
LDR r2, ptothread ; set rt_interrupt_to_thread
|
||||||
STR r1, [r2]
|
STR r1, [r2]
|
||||||
BX lr
|
BX lr
|
||||||
|
.endasmfunc
|
||||||
|
|
||||||
.def IRQ_Handler
|
.def IRQ_Handler
|
||||||
IRQ_Handler
|
IRQ_Handler
|
||||||
|
|
|
@ -39,4 +39,56 @@ void rt_hw_cpu_shutdown()
|
||||||
while (1);
|
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
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
/* exception and interrupt handler table */
|
/* exception and interrupt handler table */
|
||||||
struct rt_irq_desc irq_desc[MAX_HANDLERS];
|
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 */
|
/* exception and interrupt handler table */
|
||||||
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
|
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
|
||||||
|
|
|
@ -52,8 +52,8 @@ rt_hw_context_switch:
|
||||||
mrs r4, spsr
|
mrs r4, spsr
|
||||||
stmfd sp!, {r4} @ push spsr
|
stmfd sp!, {r4} @ push spsr
|
||||||
|
|
||||||
str sp, [r0] @ store sp in preempted tasks TCB
|
str sp, [r0] @ store sp in preempted tasks TCB
|
||||||
ldr sp, [r1] @ get new task stack pointer
|
ldr sp, [r1] @ get new task stack pointer
|
||||||
|
|
||||||
ldmfd sp!, {r4} @ pop new task spsr
|
ldmfd sp!, {r4} @ pop new task spsr
|
||||||
msr spsr_cxsf, r4
|
msr spsr_cxsf, r4
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2006-03-13 Bernard first version
|
* 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>
|
#include <rtthread.h>
|
||||||
|
@ -26,208 +26,220 @@
|
||||||
/**
|
/**
|
||||||
* This function initializes serial
|
* 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)
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
{
|
{
|
||||||
rt_memset(uart->int_rx->rx_buffer, 0,
|
rt_memset(uart->int_rx->rx_buffer, 0,
|
||||||
sizeof(uart->int_rx->rx_buffer));
|
sizeof(uart->int_rx->rx_buffer));
|
||||||
uart->int_rx->read_index = uart->int_rx->save_index = 0;
|
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;
|
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 */
|
/* save a char to serial buffer */
|
||||||
static void rt_serial_savechar(struct serial_device* uart, char ch)
|
static void rt_serial_savechar(struct serial_device* uart, char ch)
|
||||||
{
|
{
|
||||||
rt_base_t level;
|
rt_base_t level;
|
||||||
|
|
||||||
/* disable interrupt */
|
|
||||||
level = rt_hw_interrupt_disable();
|
|
||||||
|
|
||||||
uart->int_rx->rx_buffer[uart->int_rx->save_index] = ch;
|
/* disable interrupt */
|
||||||
uart->int_rx->save_index ++;
|
level = rt_hw_interrupt_disable();
|
||||||
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 */
|
uart->int_rx->rx_buffer[uart->int_rx->save_index] = ch;
|
||||||
rt_hw_interrupt_enable(level);
|
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)
|
static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
|
||||||
{
|
{
|
||||||
RT_ASSERT(dev != RT_NULL);
|
RT_ASSERT(dev != RT_NULL);
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rt_err_t rt_serial_close(rt_device_t dev)
|
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_uint8_t* ptr;
|
||||||
rt_err_t err_code;
|
rt_err_t err_code;
|
||||||
struct serial_device* uart;
|
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)
|
ptr = buffer;
|
||||||
{
|
err_code = RT_EOK;
|
||||||
rt_base_t level;
|
uart = (struct serial_device*)dev->user_data;
|
||||||
|
|
||||||
/* interrupt mode Rx */
|
if (ptr == RT_NULL)
|
||||||
while (size)
|
{
|
||||||
{
|
err_code = -RT_ENOMEM;
|
||||||
if (uart->int_rx->read_index != uart->int_rx->save_index)
|
rt_set_errno(err_code);
|
||||||
{
|
return -RT_ENOMEM;
|
||||||
*ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
|
}
|
||||||
size --;
|
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||||
|
{
|
||||||
|
rt_base_t level;
|
||||||
|
|
||||||
/* disable interrupt */
|
/* interrupt mode Rx */
|
||||||
level = rt_hw_interrupt_disable();
|
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 ++;
|
/* disable interrupt */
|
||||||
if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
|
level = rt_hw_interrupt_disable();
|
||||||
uart->int_rx->read_index = 0;
|
|
||||||
|
|
||||||
/* enable interrupt */
|
uart->int_rx->read_index ++;
|
||||||
rt_hw_interrupt_enable(level);
|
if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
|
||||||
}
|
uart->int_rx->read_index = 0;
|
||||||
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 */
|
/* enable interrupt */
|
||||||
rt_set_errno(err_code);
|
rt_hw_interrupt_enable(level);
|
||||||
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
|
}
|
||||||
|
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_uint8_t* ptr;
|
||||||
rt_err_t err_code;
|
rt_err_t err_code;
|
||||||
struct serial_device* uart;
|
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)
|
err_code = RT_EOK;
|
||||||
{
|
ptr = (rt_uint8_t*)buffer;
|
||||||
/* interrupt mode Tx */
|
uart = (struct serial_device*)dev->user_data;
|
||||||
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 */
|
if (ptr == RT_NULL)
|
||||||
uart->int_tx->save_index ++;
|
{
|
||||||
|
err_code = -RT_ENOMEM;
|
||||||
/* wrap save index */
|
rt_set_errno(err_code);
|
||||||
if (uart->int_tx->save_index >= UART_TX_BUFFER_SIZE)
|
return -RT_ENOMEM;
|
||||||
uart->int_tx->save_index = 0;
|
}
|
||||||
}
|
if (dev->flag & RT_DEVICE_FLAG_INT_TX)
|
||||||
|
{
|
||||||
/* set error code */
|
/* interrupt mode Tx */
|
||||||
if (size > 0)
|
while (uart->int_tx->save_index != uart->int_tx->write_index)
|
||||||
err_code = -RT_EFULL;
|
{
|
||||||
}
|
/* save on tx buffer */
|
||||||
else
|
uart->int_tx->tx_buffer[uart->int_tx->save_index] = *ptr++;
|
||||||
{
|
|
||||||
/* 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));
|
-- size;
|
||||||
uart->uart_device->utxh = (*ptr & 0xFF);
|
|
||||||
|
|
||||||
++ptr; --size;
|
/* move to next position */
|
||||||
}
|
uart->int_tx->save_index ++;
|
||||||
}
|
|
||||||
|
|
||||||
/* set error code */
|
/* wrap save index */
|
||||||
rt_set_errno(err_code);
|
if (uart->int_tx->save_index >= UART_TX_BUFFER_SIZE)
|
||||||
|
uart->int_tx->save_index = 0;
|
||||||
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
|
}
|
||||||
|
|
||||||
|
/* 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)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case RT_DEVICE_CTRL_SUSPEND:
|
case RT_DEVICE_CTRL_SUSPEND:
|
||||||
/* suspend device */
|
/* suspend device */
|
||||||
dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
|
dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RT_DEVICE_CTRL_RESUME:
|
case RT_DEVICE_CTRL_RESUME:
|
||||||
/* resume device */
|
/* resume device */
|
||||||
dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
|
dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RT_EOK;
|
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_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->type = RT_Device_Class_Char;
|
||||||
device->rx_indicate = RT_NULL;
|
device->rx_indicate = RT_NULL;
|
||||||
device->tx_complete = RT_NULL;
|
device->tx_complete = RT_NULL;
|
||||||
device->init = rt_serial_init;
|
device->init = rt_serial_init;
|
||||||
device->open = rt_serial_open;
|
device->open = rt_serial_open;
|
||||||
device->close = rt_serial_close;
|
device->close = rt_serial_close;
|
||||||
device->read = rt_serial_read;
|
device->read = rt_serial_read;
|
||||||
device->write = rt_serial_write;
|
device->write = rt_serial_write;
|
||||||
device->control = rt_serial_control;
|
device->control = rt_serial_control;
|
||||||
device->user_data = serial;
|
device->user_data = serial;
|
||||||
|
|
||||||
/* register a character device */
|
/* register a character device */
|
||||||
return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
|
return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ISR for serial interrupt */
|
/* ISR for serial interrupt */
|
||||||
void rt_hw_serial_isr(rt_device_t device)
|
void rt_hw_serial_isr(rt_device_t device)
|
||||||
{
|
{
|
||||||
struct serial_device* uart = (struct serial_device*) device->user_data;
|
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 */
|
/* interrupt mode receive */
|
||||||
while (uart->uart_device->ustat & USTAT_RCV_READY)
|
RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);
|
||||||
{
|
|
||||||
rt_serial_savechar(uart, uart->uart_device->urxh & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* invoke callback */
|
/* save on rx buffer */
|
||||||
if (device->rx_indicate != RT_NULL)
|
while (uart->uart_device->ustat & USTAT_RCV_READY)
|
||||||
{
|
{
|
||||||
rt_size_t rx_length;
|
rt_serial_savechar(uart, uart->uart_device->urxh & 0xff);
|
||||||
|
}
|
||||||
/* 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);
|
/* 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2006-03-13 Bernard first version
|
* 2006-03-13 Bernard first version
|
||||||
* 2006-10-05 Alsor.Z for s3c2440 initialize
|
* 2006-10-05 Alsor.Z for s3c2440 initialize
|
||||||
* 2008-01-29 Yi.Qiu for QEMU emulator
|
* 2008-01-29 Yi.Qiu for QEMU emulator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CONFIG_STACKSIZE 512
|
#define CONFIG_STACKSIZE 512
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
#define S_LR 56
|
#define S_LR 56
|
||||||
#define S_SP 52
|
#define S_SP 52
|
||||||
|
|
||||||
#define S_IP 48
|
#define S_IP 48
|
||||||
#define S_FP 44
|
#define S_FP 44
|
||||||
#define S_R10 40
|
#define S_R10 40
|
||||||
#define S_R9 36
|
#define S_R9 36
|
||||||
|
|
|
@ -83,6 +83,11 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
|
||||||
action='store_true',
|
action='store_true',
|
||||||
default=False,
|
default=False,
|
||||||
help='copy header of rt-thread directory to local.')
|
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
|
# add build library option
|
||||||
AddOption('--buildlib',
|
AddOption('--buildlib',
|
||||||
|
@ -341,6 +346,10 @@ def EndBuilding(target, program = None):
|
||||||
if GetOption('copy-header') and program != None:
|
if GetOption('copy-header') and program != None:
|
||||||
MakeCopyHeader(program)
|
MakeCopyHeader(program)
|
||||||
|
|
||||||
|
if GetOption('cscope'):
|
||||||
|
from cscope import CscopeDatabase
|
||||||
|
CscopeDatabase(Projects)
|
||||||
|
|
||||||
def SrcRemove(src, remove):
|
def SrcRemove(src, remove):
|
||||||
if type(src[0]) == type('str'):
|
if type(src[0]) == type('str'):
|
||||||
for item in src:
|
for item in src:
|
||||||
|
|
|
@ -38,8 +38,12 @@ def CB_AddCFiles(ProjectFiles, parent, gname, files, project_path):
|
||||||
|
|
||||||
def CBProject(target, script, program):
|
def CBProject(target, script, program):
|
||||||
project_path = os.path.dirname(os.path.abspath(target))
|
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()
|
root = tree.getroot()
|
||||||
|
|
||||||
out = file(target, 'wb')
|
out = file(target, 'wb')
|
||||||
|
@ -75,7 +79,7 @@ def CBProject(target, script, program):
|
||||||
Add = SubElement(elem, 'Add')
|
Add = SubElement(elem, 'Add')
|
||||||
Add.set('directory', path)
|
Add.set('directory', path)
|
||||||
|
|
||||||
for macro in building.Env['CPPDEFINES']:
|
for macro in building.Env.get('CPPDEFINES', []):
|
||||||
Add = SubElement(elem, 'Add')
|
Add = SubElement(elem, 'Add')
|
||||||
Add.set('option', "-D"+macro)
|
Add.set('option', "-D"+macro)
|
||||||
|
|
||||||
|
|
|
@ -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')
|
||||||
|
|
11
tools/iar.py
11
tools/iar.py
|
@ -37,7 +37,10 @@ def IARAddGroup(parent, name, files, project_path):
|
||||||
|
|
||||||
file = SubElement(group, 'file')
|
file = SubElement(group, 'file')
|
||||||
file_name = SubElement(file, 'name')
|
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):
|
def IARWorkspace(target):
|
||||||
# make an workspace
|
# make an workspace
|
||||||
|
@ -91,7 +94,11 @@ def IARProject(target, script):
|
||||||
if name.text == 'CCIncludePath2' or name.text == 'newCCIncludePaths':
|
if name.text == 'CCIncludePath2' or name.text == 'newCCIncludePaths':
|
||||||
for path in paths:
|
for path in paths:
|
||||||
state = SubElement(option, 'state')
|
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':
|
if name.text == 'CCDefines':
|
||||||
for define in CPPDEFINES:
|
for define in CPPDEFINES:
|
||||||
state = SubElement(option, 'state')
|
state = SubElement(option, 'state')
|
||||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue