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

📄 cstartup.s79

📁 at91sam7s64的IO控制
💻 S79
字号:
#include "AT91SAM7S64_inc.h"

;-----------------------------------------------------------------------------
; ?RESET
; 复位向量。通常INTVEC段被连接到0地址,为程序调试方便,也可以将其放在其它地址。
;-----------------------------------------------------------------------------
		PROGRAM	?RESET
		RSEG	INTRAMSTART_REMAP
		RSEG	INTRAMEND_REMAP

		RSEG	ICODE:CODE:ROOT(2)
		CODE32	; Always ARM mode after reset	
		org	0	
reset:		
;------------------------------------------------------------------------------
;异常向量。
;------------------------------------------------------------------------------
;这些向量可以从0地址或RAM地址读取,必须采用相对寻址方式以保证跳转指令的合法性。
;如果异常发生在重映射之前,将导致死循环。
;------------------------------------------------------------------------------
                B           InitReset           ; 0x00 复位句柄
undefvec:       B           undefvec            ; 0x04 未定义指令
swivec:         B           swivec              ; 0x08 软件中断
pabtvec:        B           pabtvec             ; 0x0C 预取中止
dabtvec:        B           dabtvec             ; 0x10 数据中止
rsvdvec:        B           rsvdvec             ; 0x14 保留
irqvec:         B           IRQ_Handler_Entry   ; 0x18 IRQ
fiqvec:               				; 0x1c FIQ
;------------------------------------------------------------------------------
;- 函数:FIQ_Handler_Entry
;- 说明:FIQ控制器中断句柄
;- 调用函数:AIC_FVR[interrupt]
;------------------------------------------------------------------------------
FIQ_Handler_Entry:
;由于FIQ还未被承认,故切换管理/用户模式,允许用户堆栈访问C代码。
            mov         r9,r0                  ;保存R0
	    ldr         r0 , [r8, #AIC_FVR]
            msr         CPSR_c,#I_BIT | F_BIT | ARM_MODE_SVC
            stmfd       sp!, { r1-r3, r12, lr} ;将暂存寄存器和链接寄存器LR保存在用户堆栈中
            mov         r14, pc                ;跳转到由AIC_FVR指向的子程序
            bx          r0
            ldmia       sp!, { r1-r3, r12, lr} ;从用户堆栈中恢复暂存寄存器和链接寄存器LR
            msr         CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ ;保持关中断,切换回FIQ模式
            mov         r0,r9                  ;恢复R0
            subs        pc,lr,#4               ;恢复程序计数器PC

InitReset:
;------------------------------------------------------------------------------
;由C函数AT91F_LowLevelInit完成的底层初始化(PMC, AIC, ? ....)
;------------------------------------------------------------------------------
            	EXTERN   AT91F_LowLevelInit
#define  __iramend 	SFB(INTRAMEND_REMAP)

;最小C初始化,调用 AT91F_LowLevelInit( void)
            ldr     r13,=__iramend              ;内部RAM中的临时堆栈
	    ldr	    r0,=AT91F_LowLevelInit      ;通过交互模式直接调用底层初始化函数
            mov     lr, pc
	    bx	    r0	
	
;-------------------------------------------------------------------------------------
;定义堆栈大小
;
;采用向量时,中断堆栈要求 2字 x 8 优先级 x 4 字节,假设为FIQ。
;中断堆栈必须根据中断句柄进行调整。FIQ中断不需要堆栈,如果用户程序需要的话,应在此定义。
;未定义系统堆栈,它取决于空余内部SRAM。
;-------------------------------------------------------------------------------------

;-------------------------------------------------------------------------------------
;定义栈顶
;
;为了提高异常处理和保存/恢复上下文的速度,中断和管理队战定位于内部存储器的顶部。
;ARM_MODE_SVC(C应用程序)堆栈定位于外部存储器的顶部。
;-------------------------------------------------------------------------------------
IRQ_STACK_SIZE          EQU     (3*8*4)     ;每个中断优先级3个字

ARM_MODE_FIQ            EQU     0x11
ARM_MODE_IRQ            EQU     0x12
ARM_MODE_SVC            EQU     0x13

I_BIT                   EQU     0x80
F_BIT                   EQU     0x40

;-------------------------------------------------------------------------------------
;为各种模式设置堆栈
;-------------------------------------------------------------------------------------
                ldr     r0, =__iramend
                msr     CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT ;设置FIQ模式及堆栈
            	ldr     r8, =AT91C_BASE_AIC                   ;初始化FIQ寄存器
                msr     CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT ;设置IRQ模式及堆栈
                mov     r13, r0                               ;初始化FIQ堆栈
                sub     r0, r0, #IRQ_STACK_SIZE
                msr     CPSR_c, #ARM_MODE_SVC                 ;允许中断,设置管理模式及堆栈
                mov     r13, r0

;---------------------------------------------------------------
; ?CSTARTUP
;---------------------------------------------------------------
		EXTERN	__segment_init
		EXTERN	main

		ldr	r0,=__segment_init                    ;段初始化。
                mov     lr, pc
		bx	r0

		PUBLIC	__main
?jump_to_main:
		ldr	lr,=?call_exit
		ldr	r0,=main
__main:
		bx	r0

;------------------------------------------------------------------------------
;无穷循环
;
;应用结束,通常不会发生。也可以跳转到复位地址( B 0x0 ).
;------------------------------------------------------------------------------
?call_exit:
End
            b       End


;------------------------------------------------------------------------------
;异常管理
;
;该模块中必须保证异常为ARM模式。
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;函数:IRQ_Handler_Entry
;说明:IRQ控制器中断句柄。
;调用函数:AIC_IVR[interrupt]
;------------------------------------------------------------------------------
IRQ_Handler_Entry:
            sub         lr, lr, #4              ;异常管理入口,调整并将LR_irq保存到IRQ堆栈
            stmfd       sp!, {lr}
            mrs         r14, SPSR               ;为嵌套中断保存SPSR
            stmfd       sp!, {r14}
            stmfd       sp!, {r0}               ;保存R0到IRQ堆栈
            ldr         r14, =AT91C_BASE_AIC
	    ldr         r0 , [r14, #AIC_IVR]
	    str         r14, [r14, #AIC_IVR]
            msr         CPSR_c, #ARM_MODE_SVC   ;开中断并切换到管理模式
            stmfd       sp!, { r1-r3, r12, r14} ;保存暂存寄存器和链接寄存器LR到用户堆栈
            mov         r14, pc                 ;跳转到由AIC_IVR指向的子程序
            bx          r0
            ldmia       sp!, { r1-r3, r12, r14} ;从用户堆栈恢复暂存寄存器和链接寄存器LR
            msr         CPSR_c, #I_BIT | ARM_MODE_IRQ ;关中断并切换到IRQ模式
            ldr         r14, =AT91C_BASE_AIC    ;在AIC中标志中断结束
            str         r14, [r14, #AIC_EOICR]
            ldmia       sp!, {r0}                ;恢复R0
            ldmia       sp!, {r14}               ;从IRQ堆栈恢复SPSR_irq和R0
            msr         SPSR_cxsf, r14
            ldmia       sp!, {pc}^               ;从IRQ堆栈中直接将调整过的LR_irq恢复到PC
	
;-----------------------------------------------------------------------------------------------
;?EXEPTION_VECTOR
;该模块仅在需要关闭文件时才被连接。
;-----------------------------------------------------------------------------------------------
		PUBLIC	AT91F_Default_FIQ_handler
		PUBLIC	AT91F_Default_IRQ_handler
		PUBLIC	AT91F_Spurious_handler

		CODE32	; Always ARM mode after exeption	

AT91F_Default_FIQ_handler
            b     AT91F_Default_FIQ_handler

AT91F_Default_IRQ_handler
            b     AT91F_Default_IRQ_handler

AT91F_Spurious_handler
            b     AT91F_Spurious_handler

	ENDMOD

	END

⌨️ 快捷键说明

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