📄 init.s
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; uC/OS-II Porting for LPC210x
; Compiler: ADS 1.2
; By Pary WU <parywu@mail2000.com.tw>
;
; History:
; 0406271325:parywu
; The first stable porting, Thumb mode is not considered yet.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IMPORT |Image$$RO$$Limit|
IMPORT |Image$$RW$$Base|
IMPORT |Image$$ZI$$Base|
IMPORT |Image$$ZI$$Limit|
IMPORT frame_init
IMPORT frame_main
IMPORT frame_swi_handler
;IRQ vector symbols
EXPORT IRQ_VECTOR_0
EXPORT IRQ_VECTOR_1
EXPORT IRQ_VECTOR_2
EXPORT IRQ_VECTOR_3
EXPORT IRQ_VECTOR_4
EXPORT IRQ_VECTOR_5
EXPORT IRQ_VECTOR_6
EXPORT IRQ_VECTOR_7
EXPORT IRQ_VECTOR_8
EXPORT IRQ_VECTOR_9
EXPORT IRQ_VECTOR_10
EXPORT IRQ_VECTOR_11
EXPORT IRQ_VECTOR_12
EXPORT IRQ_VECTOR_13
EXPORT IRQ_VECTOR_14
EXPORT IRQ_VECTOR_15
EXPORT IRQ_VECTOR_16
EXPORT frame_irq_flag
EXPORT frame_irq_enable
EXPORT frame_irq_disable
;; modes, with NOINT
MODE_NOINT_USR EQU 0xd0
MODE_NOINT_FIQ EQU 0xd1
MODE_NOINT_IRQ EQU 0xd2
MODE_NOINT_SVC EQU 0xd3
MODE_NOINT_ABT EQU 0xd7
MODE_NOINT_UND EQU 0xdb
MODE_NOINT_SYS EQU 0xdf
;; unit: byte
;; size should be the multiplier of 4, safe factor is recommended to 2
STACK_SIZE_SYS EQU 256 ;cannot be 0, at least 64*2 (two contexts)
STACK_SIZE_FIQ EQU 0
STACK_SIZE_IRQ EQU 256 ;cannot be 0, at least 4*2
STACK_SIZE_SVC EQU 64 ;cannot be 0, at least 4*2
STACK_SIZE_ABT EQU 0
STACK_SIZE_UND EQU 0
;; USR stack is as SYS
; configurations
; shall match as in config.h
;SRAM_SIZE EQU 64*1024 ;LPC2106, 64KB SRAM
;SRAM_SIZE EQU 32*1024 ;LPC2105, 32KB SRAM
SRAM_SIZE EQU 16*1024 ;LPC2104, 16KB SRAM
SRAM_BEG_ADDR EQU 0x40000000 ;SRAM begin address
IRQ_BEG_ADDR EQU SRAM_BEG_ADDR ;IRQ begin address
IRQ_NUM EQU 17
STACK_SIZE EQU STACK_SIZE_SYS+STACK_SIZE_FIQ+STACK_SIZE_IRQ+\
STACK_SIZE_SVC+STACK_SIZE_ABT+STACK_SIZE_UND
STACK_BEG_ADDR EQU SRAM_BEG_ADDR+SRAM_SIZE-STACK_SIZE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; startup section
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CODE32
AREA startup, CODE, READONLY
ENTRY
;; vector table
b handler_entry_RST
b handler_entry_UND
b handler_entry_SWI
b handler_entry_PAB
b handler_entry_DAB
b .
b handler_entry_IRQ
b handler_entry_FIQ
handler_entry_FIQ
b . ;halt
handler_entry_UND
b . ;halt
handler_entry_SWI
stmfd sp!, {lr}
;save context
msr cpsr_c, #MODE_NOINT_SYS
stmfd sp!, {r0-r1} ;dummy, for (cpsr, pc)
stmfd sp!, {r0-r12, lr}
msr cpsr_c, #MODE_NOINT_SVC
mov r2, lr ;lr = pc_sys
mrs r1, spsr ;spsr = cpsr_sys
ldr r0, [lr, #-4] ;calculate the 'x' of 'swi x'
bic r0, r0, #0xff000000 ;r0 = 'x'
msr cpsr_c, #MODE_NOINT_SYS
str r1, [sp, #60] ;cpsr
str r2, [sp, #56] ;pc
; c declaration:
; void frame_swi_handler(int num)
bl frame_swi_handler ;refer `frame_tick_handler'
; to write a proper handler
; (be careful to context switch)
ldr r0, [sp, #56]
ldr r1, [sp, #60]
msr cpsr_c, #MODE_NOINT_SVC
msr spsr_cf, r1
mov lr, r0
msr cpsr_c, #MODE_NOINT_SYS
ldmfd sp!, {r0-r12, lr}
add sp, sp, #8 ;drop 2 items (pc, cpsr)
msr cpsr_c, #MODE_NOINT_SVC
ldmfd sp!, {pc}^
handler_entry_PAB ;;PAB handler
b . ;;halt
handler_entry_DAB ;;DAB handler
b . ;;halt
;; IMPLEMENTATION NOTE
;; IRQ table without VIC, to ease porting
;; VIC should be used then, for better performance
handler_entry_IRQ
sub lr, lr, #4
stmfd sp!, {lr}
;save sys's context
; cpsr
; pc
; lr
; r12
; r11
; r10
; r9
; r8
; r7
; r6
; r5
; r4
; r3
; r2
; r1
; r0 <= sp (r13), saved in TCB
msr cpsr_c, #MODE_NOINT_SYS
stmfd sp!, {r0-r1} ;dummy, for (cpsr, pc)
stmfd sp!, {r0-r12, lr}
msr cpsr_c, #MODE_NOINT_IRQ
mov r0, lr ;lr = pc_sys
mrs r1, spsr ;spsr = cpsr_sys
msr cpsr_c, #MODE_NOINT_SYS
str r1, [sp, #60] ;cpsr
str r0, [sp, #56] ;pc
; enter irq_dispatch under sys mode
bl irq_dispatch
ldr r0, [sp, #56]
ldr r1, [sp, #60]
msr cpsr_c, #MODE_NOINT_IRQ
msr spsr_cf, r1
mov lr, r0
msr cpsr_c, #MODE_NOINT_SYS
ldmfd sp!, {r0-r12, lr}
add sp, sp, #8 ;drop 2 items (pc, cpsr)
msr cpsr_c, #MODE_NOINT_IRQ
ldmfd sp!, {pc}^
irq_dispatch
ldr r4, =0xfffff000 ;VICIRQStatus
ldr r4, [r4]
ldr r5, =IRQ_VECTOR_0
ldr r6, =IRQ_VECTOR_END
mov r8, lr
41
tst r4, #1
ldrne r7, [r5]
movne lr, pc
movne pc, r7
mov r4, r4, ror #1
add r5, r5, #4
bne %42 ;deal with only one IRQ
cmp r5, r6
bne %41
42
bx r8
;; RESET
handler_entry_RST
bl init_irq_handlers
bl init_stacks
ldr r0, =|Image$$RO$$Limit|
ldr r1, =|Image$$RW$$Base|
ldr r3, =|Image$$ZI$$Base|
cmp r0, r1
beq %F1
;; copy RW section if necessary
0
cmp r1, r3
ldrcc r2, [r0], #4
strcc r2, [r1], #4
bcc %B0
;; init ZI
1
ldr r1, =|Image$$ZI$$Limit|
mov r2, #0
2
cmp r3, r1
strcc r2, [r3], #4
bcc %B2
;; external initialization before main
bl frame_init
;; Main, should never return
;; do not use the name 'main'
;; if the name 'main' used, then ADS will compile the code with
;; the standard C library
ldr lr, =frame_main
bx lr
init_stacks
;; cpsr_c = MODE|NOINT;
;; sp = STACK_xxx
mov r0, lr
msr cpsr_c, #MODE_NOINT_UND
ldr sp, =STACK_UND
msr cpsr_c, #MODE_NOINT_ABT
ldr sp, =STACK_ABT
msr cpsr_c, #MODE_NOINT_IRQ
ldr sp, =STACK_IRQ
msr cpsr_c, #MODE_NOINT_FIQ
ldr sp, =STACK_FIQ
msr cpsr_c, #MODE_NOINT_SVC
ldr sp, =STACK_SVC
msr cpsr_c, #MODE_NOINT_SYS
ldr sp, =STACK_SYS
; c_main starts with SYS mode
; SVC mode is not suitable!
; if SVC mode is applied, then SWI cannot be used
; refer ARM developer guide page 5-45 for more details
mov pc, r0
init_irq_handlers
ldr r0, =IRQ_VECTOR_0
ldr r1, =IRQ_VECTOR_END
ldr r2, =irq_default_handler
12
stmia r0!, {r2}
cmp r0, r1
bne %12
;reset frame_irq_flag
ldr r0, =frame_irq_flag
mov r1, #0
str r1, [r0]
mov pc, lr
irq_default_handler
b .
frame_irq_enable
mrs r0, cpsr
bic r0, r0, #0x80
msr cpsr_c, r0
bx lr
frame_irq_disable
mrs r0, cpsr
orr r0, r0, #0x80
msr cpsr_c, r0
bx lr
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; section STACK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
AREA SYS_STACK, DATA, READWRITE, NOINIT
MAP STACK_BEG_ADDR
STACK_FIQ_TOP FIELD STACK_SIZE_FIQ
STACK_IRQ_TOP FIELD STACK_SIZE_IRQ
STACK_SVC_TOP FIELD STACK_SIZE_SVC
STACK_ABT_TOP FIELD STACK_SIZE_ABT
STACK_UND_TOP FIELD STACK_SIZE_UND
STACK_SYS_TOP FIELD STACK_SIZE_SYS
STACK_FIQ EQU STACK_FIQ_TOP+STACK_SIZE_FIQ-4
STACK_IRQ EQU STACK_IRQ_TOP+STACK_SIZE_IRQ-4
STACK_SVC EQU STACK_SVC_TOP+STACK_SIZE_SVC-4
STACK_ABT EQU STACK_ABT_TOP+STACK_SIZE_ABT-4
STACK_UND EQU STACK_UND_TOP+STACK_SIZE_UND-4
STACK_SYS EQU STACK_SYS_TOP+STACK_SIZE_SYS-4
AREA IRQ_VECTORS, DATA, READWRITE
MAP IRQ_BEG_ADDR
IRQ_VECTOR_0 FIELD 4
IRQ_VECTOR_1 FIELD 4
IRQ_VECTOR_2 FIELD 4
IRQ_VECTOR_3 FIELD 4
IRQ_VECTOR_4 FIELD 4
IRQ_VECTOR_5 FIELD 4
IRQ_VECTOR_6 FIELD 4
IRQ_VECTOR_7 FIELD 4
IRQ_VECTOR_8 FIELD 4
IRQ_VECTOR_9 FIELD 4
IRQ_VECTOR_10 FIELD 4
IRQ_VECTOR_11 FIELD 4
IRQ_VECTOR_12 FIELD 4
IRQ_VECTOR_13 FIELD 4
IRQ_VECTOR_14 FIELD 4
IRQ_VECTOR_15 FIELD 4
IRQ_VECTOR_16 FIELD 4
IRQ_VECTOR_END EQU IRQ_VECTOR_16+4
frame_irq_flag FIELD 4
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -