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

📄 int.s

📁 test file nucleus source
💻 S
📖 第 1 页 / 共 5 页
字号:
;*  REGISTERS MODIFIED
;*
;*      None
;*
;*  HISTORY
;*
;*      NAME            DATE            REMARKS
;*
;*      C. March     07/15/2003      Released Version 1.14.9
;************************************************************************
;static VOID   INT_Clear_BSS(VOID)

INT_Clear_BSS

    ; Get BSS start and end addresses

    LDR     r0,INT_bss_start
    LDR     r1,INT_bss_end

    ; Get a value to clear BSS

    MOV     r2,#0

    ; Clear the entire memory range

INT_BSS_Clear_Loop

    CMP     r0,r1                           ; Are the start and end equal?
    STRNE   r2,[r0],#4                      ; Clear 4-bytes and move to next 4-bytes
    BNE     INT_BSS_Clear_Loop              ; Continue clearing until done

    ; Return to caller

    BX      lr


;************************************************************************
;*
;*  FUNCTION
;*
;*      INT_System_Initialize
;*
;*  DESCRIPTION
;*
;*      This function initializes Nucleus Plus system variables.  This
;*      includes global variables for: the RTOS System stack, the start
;*      address for the timer HISR stack, the timer HISR stack size,
;*      and the timer HISR priority.
;*
;*  CALLED BY
;*
;*      INT_Initialize
;*
;*  CALLS
;*
;*      None
;*
;*  INPUTS
;*
;*      None
;*
;*  OUTPUTS
;*
;*      None
;*
;*  REGISTERS MODIFIED
;*
;*      None
;*
;*  HISTORY
;*
;*      NAME            DATE            REMARKS
;*
;*      C. March     07/15/2003      Released Version 1.14.9
;************************************************************************
;static VOID   INT_Sytem_Initialize(VOID)

INT_System_Initialize

    MOV     r4,lr                           ; Save lr in r4

    ; Set-up INT_Loaded_Flag (1 vectors loaded, 0 vectors not loaded)

    MOV     r0,#1                           ; All vectors are assumed loaded
    LDR     r1,INT_Loaded_Flag1             ; Build address of loaded flag
    STR     r0,[r1]                         ; Initialize loaded flag

    ; Set-up the system stack

    LDR     r2,INT_System_Stack             ; Get address of global variable for system stack
    STR     sp,[r2]                         ; Save system stack pointer

    ; Set-up the system stack limit (used for stack checking by ARM tools)

    SUB     r1,sp,#SYSTEM_STACK_SIZE        ; Adjust stack pointer to get stack limit
    BIC     r1,r1,#0x03                     ; Align on 4-byte boundry
    MOV     r10,r1                          ; Put stack limit in stack limit register
    LDR     r2,INT_System_Limit             ; Get address of global variable for system stack limit
    STR     r1,[r2]                         ; Save system stack limit

    ; Switch to IRQ mode

    MRS     r0,CPSR                         ; Pickup current CPSR
    BIC     r0,r0,#MODE_MASK                ; Clear the mode bits
    ORR     r1,r0,#IRQ_MODE                 ; Set the IRQ mode bits
    MSR     CPSR_cxsf,r1                    ; Switch to IRQ mode

    ; Set-up IRQ stack

    LDR     sp,=INT_Irq_SP                  ; Get address of IRQ stack pointer

    ; Switch to FIQ mode

    ORR     r1,r0,#FIQ_MODE                 ; Set the FIQ mode bits
    MSR     CPSR_cxsf,r1                    ; Switch to FIQ mode

    ; Set-up FIQ stack

    LDR     sp,=INT_Fiq_SP                  ; Get address of FIQ stack pointer

    ; Switch to Abort mode

    ORR     r1,r0,#ABT_MODE                 ; Set the ABT mode bits
    MSR     CPSR_cxsf,r1                    ; Switch to ABT mode

    ; Set-up Abort stack

    LDR     sp,=INT_Abort_SP                ; Get address of Abort stack pointer

    ; Switch to Undefined mode

    ORR     r1,r0,#UNDEF_MODE               ; Set the UNDEF mode bits
    MSR     CPSR_cxsf,r1                    ; Switch to UNDEF mode

    ; Set-up UNDEF stack

    LDR     sp,=INT_Undefined_SP            ; Get address of Undefined stack pointer

    ; Switch to Undefined mode

    ORR     r1,r0,#SYS_MODE                 ; Set the System mode bits
    MSR     CPSR_cxsf,r1                    ; Switch to System mode

    ; Set-up System/User stack

    LDR     sp,=INT_System_User_SP          ; Get address of System/User stack pointer

    ; Switch back to supervisor mode

    IF NU_SUPERV_USER_MODE
    ORR     r1,r0,#SYS_MODE                 ; Set the Supervisor mode bits
    ELSE
    ORR     r1,r0,#SUP_MODE                 ; Set the Supervisor mode bits
    ENDIF

    MSR     CPSR_cxsf,r1                    ; Switch to Supervisor mode

    ; Get address of HISR stack memory

    LDR     r0,=INT_HISR_Stack_Start        ; Get start address of HISR stack
    LDR     r1,INT_HISR_Stack_Ptr           ; Pickup global variable's address
    STR     r0,[r1]                         ; Setup timer HISR stack pointer variable

    ; Get size of HISR stack

    MOV     r0,#HISR_STACK_SIZE             ; Get size of HISR stack
    LDR     r1,INT_HISR_Stack_Size          ; Get address of HISR stack size variable
    STR     r0,[r1]                         ; Store HISR stack size

    ; Get priority of HISR

    MOV     r0,#HISR_PRIORITY               ; Pickup timer HISR priority (0-2)
    LDR     r1,INT_HISR_Priority            ; Get address of HISR priority variable
    STR     r0,[r1]                         ; Store HISR priority

    ; Return to caller

    BX      r4

;************************************************************************
;*
;*  FUNCTION
;*
;*      __user_initial_stackheap
;*
;*  DESCRIPTION
;*
;*      This assembly function returns the start address of the heap.
;*      This function is needed by applications utilizing certain
;*      ARM Developer Suite Tools library calls.
;*
;*  CALLED BY
;*
;*      Applications
;*
;*  CALLS
;*
;*      None
;*
;*  INPUTS
;*
;*      None
;*
;*  OUTPUTS
;*
;*      r0 - start address of heap
;*
;*  REGISTERS MODIFIED
;*
;*      r0
;*
;*  HISTORY
;*
;*      NAME            DATE            REMARKS
;*
;*      C. March      07/15/2003      Released Version 1.14.9
;************************************************************************
;VOID    *__user_initial_stackheap(void)
    
    EXPORT __user_initial_stackheap
__user_initial_stackheap

    ; Get address of bottom of heap in return register

    LDR     r0, =bottom_of_heap
    
    ; Return to caller

    BX      lr


;*****************************
;* TARGET SPECIFIC FUNCTIONS *
;*****************************

;************************************************************************
;*
;*  FUNCTION
;*
;*      INT_IRQ
;*
;*  DESCRIPTION
;*
;*      This assembly function is responsible for handling all IRQ
;*      interrupts produced on the ARM architecture
;*
;*  CALLED BY
;*
;*      IRQ Interrupt
;*
;*  CALLS
;*
;*      Interrupt Handler
;*
;*  INPUTS
;*
;*      None
;*
;*  OUTPUTS
;*
;*      r0  -   vector number
;*
;*  REGISTERS MODIFIED
;*
;*      r1, r2, r3, r4, r5 (saved on stack before modification)
;*      IRQ SP  - IRQ stack pointer
;*      lr      - link register adjusted for return
;*
;*  HISTORY
;*
;*      NAME            DATE            REMARKS
;*
;*      C. March     07/15/2003      Released Version 1.14.9
;************************************************************************
;static VOID    INT_IRQ(VOID)

INT_IRQ

    ; This Code is used to correctly handle interrupts and
    ; is necessary due to the nature of the ARM7 architecture 

    STMDB   sp!, {r1}
    MRS     r1, SPSR
    TST     r1, #IRQ_BIT
    LDMIA   sp!, {r1}
    SUBNES  pc,lr,#4

    ; Disable MMU if running with MMU Module Support

    IF NU_MMU_MODE

    MMU_DISABLE

    ENDIF

    ; Save space on stack for interrupt mask / interrupt mask register addresses

    SUB     sp,sp,#MASK_REG_SPACE

    ; Save working registers on IRQ stack

    STMDB   sp!,{r0-r5}

    ; Adjust link register to interrupt return address

    SUB     lr,lr,#4

    ; Begin Board Specific Section

    ; Get base address of IRQ registers

    LDR     r3, =INT_Module_IRQ_Base
    LDR     r3, [r3]

    ; Get IRQ enable register value and save it on the bottom of the stack.

    LDR     r4, [r3,#INT_ENABLE_OFFSET] 
    STR     r4, [sp,#MASK1_STACK_OFFSET]
    STR     r3, [sp,#INT_BASE_STACK_OFFSET]

    ; Get the value of the IRQ status register

    LDR     r2, [r3,#INT_STATUS_OFFSET]

    ; Compare value to 0 to make sure that an interrupt actually fired.  If not
    ; branch to a spurrious interrupt handler.

    CMP     r2, #0
    BEQ     INT_Spurious_Interrupt

    ; Get the priority table address.

    LDR     r3, =INT_Interrupt_Priority

    ; Loop until the correct vector from the priority table matches the 
    ; Interrupt pending bit.

IRQ_Vector_Loop

    ; Load first vector to be checked from priority table

    LDR     r0, [r3,#0]

    ; Build mask based on vector number

    MOV     r1, #1
    MOV     r1, r1, LSL r0

    ; Test if this interrupt is pending

    TST     r1, r2
    BNE     IRQ_Vector_Found

    ; Clear enable bit so higher priority interrupts remain active

    BIC     r4,r4,r1

    ; Move to next entry in table

    ADD     r3, r3, #4

    ; Keep looping until vector found

    B       IRQ_Vector_Loop

IRQ_Vector_Found

    ; Get base address of IRQ registers

    LDR     r3, =INT_Module_IRQ_Base
    LDR     r3,[r3]
    
    ; Disable lower priority interrupts

    STR     r4,[r3,#INT_CLEAR_OFFSET]       ; Disable all lower priority 
                                            ; interrupts

    ; End Board Specific Section

    ; Load the branch address from the vector table

    LDR     r3,=INT_IRQ_Vectors             ; Get IRQ vector table address
    MOV     r2, r0, LSL #2                  ; Multiply vector by 4 to get 
                                            ; offset into table
    ADD     r3, r3, r2                      ; Adjust vector table address to 
                                            ; correct offset
    LDR     r2, [r3,#0]                     ; Load branch address from vector 
                                            ; table
    MOV     PC, r2                          ; Jump to correct branch location 
                                            ; based on vector table


;************************************************************************
;*
;*  FUNCTION
;*
;*      INT_FIQ
;*
;*  DESCRIPTION
;*
;*      This assembly function is responsible for handling all FIQ
;*      interrupts produced on the ARM architecture
;*
;*  CALLED BY
;*
;*      FIQ Interrupt
;*
;*  CALLS
;*
;*      Interrupt Handler
;*
;*  INPUTS
;*
;*      None
;*
;*  OUTPUTS
;*
;*      r0  -   vector number
;*
;*  REGISTERS MODIFIED
;*
;*      FIQ SP  - FIQ stack pointer
;*      lr      - link register adjusted for return
;*
;*  HISTORY
;*
;*      NAME            DATE            REMARKS
;*
;*      C. March     07/15/2003      Released Version 1.14.9
;************************************************************************
;static VOID    INT_FIQ(VOID)

INT_FIQ

    IF      NU_FIQ_SUPPORT

    ; This Code is used to correctly handle interrupts and
    ; is necessary due to the nature of the ARM7 architecture 

    STMDB   sp!, {r1}
    MRS     r1, SPSR
    TST     r1, #FIQ_BIT
    LDMIA   sp!, {r1}
    SUBNES  pc,lr,#4

    IF NU_MMU_MODE

    MMU_DISABLE
    
    ENDIF

    SUB     sp,sp,#4                        ; Save a space for the interrupt 
                                            ; enable register

    STMDB   sp!,{r0-r5}                     ; Save r0-r5 on temporary IRQ stack
    SUB     lr,lr,#4                        ; Adjust FIQ return address

    ; Start Board Specific Section

    ; Get FIQ enable register value and save it on the bottom of the stack.

    LDR     r3, Module_FIQ_Base
    LDR     r4, [r3,#INT_ENABLE_OFFSET]
    STR     r4, [sp,#24]                

    ; Get the value of the FIQ status register

    LDR     r2, [r3,#INT_STATUS_OFFSET] 

    ; Compare value to 0 to make sure that an interrupt actually fired.  If not
    ; branch to a spurrious interrupt handler.

    CMP     r2, #0
    BEQ     INT_Spurrious_Interrupt

    ; Get the priority table address.

    LDR     r3,=INT_FIQ_Priority

    ; Loop until the correct vector from the priority table matches the 
    ; Interrupt pending bit.

FIQ_Vector_Loop

    ; Load first vector to be checked from priority table

    LDR     r0, [r3,#0]

    ; Build mask based on vector number

    MOV     r1, #1
    MOV     r1, r1, LSL r0

    ; Test if this interrupt is pending

    TST     r1, r2
    BNE     FIQ_Vector_Found

    ; Clear enable bit so higher priority interrupts remain active

    BIC     r4,r4,r1

    ; Move to next entry in table

    ADD     r3, r3, #4

    ; Keep looping until vector found

    B       FIQ_Vector_Loop

FIQ_Vector_Found
   
    ; Disable lower priority interrupts

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -