⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.s

📁 ucos2 in lpc2104 的源码
💻 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 + -