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

📄 start.s

📁 S3C2410启 动代码
💻 S
字号:
;********************************************************************************
;* 文 件 名:START.S
;* 作    者:张人柏
;* 开发日期:2007-8-12
;* 功能描述:S3C2410的启动程序
;* 修改日期:
;* 技术支持:zhangrenbai@163.com
;********************************************************************************


;********************************************************************************	
;引入的外部标号在这声明	
;********************************************************************************
	IMPORT  |Image$$RO$$Base|				; 只读代码的开始地址
	IMPORT  |Image$$RO$$Limit|  			; 只读区域大小
	IMPORT  |Image$$RW$$Base|   			; 可读写存储区域起始地址
	IMPORT  |Image$$ZI$$Base|   			; 清零区域起始地址 
	IMPORT  |Image$$ZI$$Limit|  			; 清零区域大小	
	IMPORT  Main    						;引入外部函数Main,进入C程序。
;********************************************************************************
;给外部使用的标号在这声明
;********************************************************************************
	EXPORT	ResetEntry
		
;********************************************************************************
;内部常量定义	
;********************************************************************************
;工程实际存储空间定义	
SDRAM_END			EQU	0x34000000			;64M SDRAM存储空间

;开始堆栈地址空间
_STACK_BASEADDRESS	EQU (SDRAM_END-0x8000)	;0x33ff8000堆栈基地址
_MMUTT_STARTADDRESS	EQU (SDRAM_END-0x8000)	;0x33ff8000定义MMU 表基地址
_ISR_STARTADDRESS	EQU (SDRAM_END-0x100)	;0x33ffff00堆栈服务程序开始地址

;ARM  异常模式的定义
USERMODE    EQU 0x10   						;0b10000 用户模式
FIQMODE     EQU 0x11   						;0b10001 FIQ模式
IRQMODE     EQU 0x12  						;0b10010 IRQ模式
SVCMODE     EQU 0x13   						;0b10011 管理模式
ABORTMODE   EQU 0x17   						;0b10111 中止模式
UNDEFMODE   EQU 0x1b   						;0b11011 未定义
MODEMASK    EQU 0x1f						;0b11111 系统模式
NOINT       EQU 0xc0						;屏蔽中断位

;ARM时钟定义
FCLK		EQU	50000000
M_MDIV		EQU	0x5c						;Fin=12.0MHz Fout=50.0MHz
M_PDIV		EQU	0x4
M_SDIV		EQU	0x2

;控制寄存器的地址定义
WTCON     	EQU  0x53000000       			;看门狗定时器模式寄存器		
INTMSK      EQU  0x4a000008    				;中断屏蔽控制寄存器			
INTSUBMSK   EQU  0x4a00001c    				;次级中断屏蔽寄存器	
LOCKTIME    EQU  0x4c000000     			;PLL 锁定时间控制寄存器	
MPLLCON     EQU  0x4c000004     			;MPLL 控制寄存器	
BWSCON      EQU  0x48000000     			;总线宽度和等待控制寄存器
INTOFFSET   EQU  0x4a000014    				;中断请求源偏移寄存器		

;ARM个异常模式堆栈
UserStack	EQU	(_STACK_BASEADDRESS-0x3800)	;0x33ff4800 ~ 用户模式下的堆栈地址
SVCStack	EQU	(_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~ 管理模式模式下的堆栈地址
UndefStack	EQU	(_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~ 未定义模式下的堆栈地址
AbortStack	EQU	(_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~ 异常中止模式下的堆栈地址
IRQStack	EQU	(_STACK_BASEADDRESS-0x1000)	;0x33ff7000 ~ 外部中断模式下的堆栈地址
FIQStack	EQU	(_STACK_BASEADDRESS-0x0)	;0x33ff8000 ~ 快速中断模式下的堆栈地址

;********************************************************************************
;内部宏定义	
;********************************************************************************	
;宏定义-进入异常流程
;HANDLER-宏的名称
;$HandleLabel-宏的参数
;这个宏的作用是把各个中断程序的地址装入当前的PC,2410有两种装断模式 一种是没有中断向量表,一种是使用中断向量表的
;使用中断向量表只能是IRQ方式,当使用中断向量表的时候,中断发生时由2410的中断控制器自动跳转到相应的位置

    MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
    sub	    sp, sp, #4	    				; 栈空间递减保存跳转地址							
    stmfd   sp!,{r0}	    				; 保存工作寄存器r0到栈
    ldr	    r0, =$HandleLabel				; 载入中断入口地址所在位置到r0
    ldr	    r0, [r0]	    				; 载入中断入口地址到r0
    str	    r0, [sp,#4]	    				; 保存中断入口地址到栈
    ldmfd   sp!,{r0,pc}	    				; 恢复工作寄存器并跳转到中断ISR函数
	MEND
	
;********************************************************************************
;ARM汇编程序段,段名为SelfBoot,程序段为只读的代码段。
;********************************************************************************	
	CODE32
	AREA    SelfBoot, CODE, READONLY
	ENTRY	
;程序入口地址
ResetEntry									;程序段执行的第一跳指令,为8个异常中断处理向量,要按顺序放置。
	b	ResetHandler  						;复位跳到复位程序去执行
 	b	HandlerUndef						;跳到Und复位程序去执行
	b	HandlerSWI							;跳到SWI复位程序去执行
	b	HandlerPabort						;跳到Abt复位程序去执行
	b	HandlerDabort						;跳到Dbt复位程序去执行
	b	.									;保留
	b	HandlerIRQ							;跳到IRQ复位程序去执行
	b	HandlerFIQ							;跳到FIQ复位程序去执行
	b	.									;保留电源管理入口

	LTORG 									;声明一个数据缓冲池的开始   
HandlerFIQ      HANDLER HandleFIQ			;用宏汇编程在这里生成快速中断处理的程序,以下同理
HandlerIRQ      HANDLER HandleIRQ
HandlerUndef    HANDLER HandleUndef
HandlerSWI      HANDLER HandleSWI
HandlerDabort   HANDLER HandleDabort
HandlerPabort   HANDLER HandlePabort


;采用INTOFFSET寄存器判定IRQ中断源
IsrIRQ  
	sub	sp,sp,#4       						;reserved for PC,中断分发例程入口地址预留栈空间
	stmfd	sp!,{r8-r9} 					;将r8、r9内容保存到堆栈
	ldr	r9,=INTOFFSET						;INTOFFSET寄存器各位表明发生了应该调用那个中断子程序。
	ldr	r9,[r9]								;r9中存放INTOFFSET的内容
	ldr	r8,=HandleEINT0						;取EINT0的地址
	add	r8,r8,r9,lsl #2						;r8=r8+r9*4
	ldr	r8,[r8]								;加载中断服务函数地址到r8
	str	r8,[sp,#8]							;保存到sp,作为新的PC
	ldmfd	sp!,{r8-r9,pc}					;跳转到新的PC运行


;======================================================
; 复位程序 
;======================================================
;初始化程序入口指令
ResetHandler	
	ldr	r0,=WTCON      						;看门狗禁止
	ldr	r1,=0x0         
	str	r1,[r0]

	ldr	r0,=INTMSK
	ldr	r1,=0xffffffff  					;全局中断用高优先级中断禁止
	str	r1,[r0]
	
	ldr r0,=INTSUBMSK 						;子中断也一样屏蔽
	ldr r1,=0x3ff
	str r1,[r0] 

	ldr	r0,=LOCKTIME						;设置时钟控制器 
	ldr	r1,=0xffffff
	str	r1,[r0]
        
	ldr	r0,=MPLLCON							;设置时钟,所有模块的时钟开启          
	ldr	r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)  ;Fin=12MHz,Fout=50MHz
	str	r1,[r0]

	adr	r0, SMRDATA							;设置存储器控制寄存器。
	ldr	r1,=BWSCON							;BWSCON Address
	add	r2, r0, #52							;End address of SMRDATA一共13个寄存器
0       
	ldr	r3, [r0], #4    
	str	r3, [r1], #4    
	cmp	r2, r0		
	bne	%B0

	bl	InitStacks							;初始化堆栈
	
	
	ldr	r0,=HandleIRQ       				;建立IRQ中断
	ldr	r1,=IsrIRQ          				
	str	r1,[r0]
	
;将RO区域的代码copy到RW域中并且将ZI区域初始化为0,提供C语言运行环境。
	adr	r0, ResetEntry
	ldr	r2, |Image$$RO$$Base|
	cmp	r0, r2
	ldreq	r0, |Image$$RO$$Limit|
	beq		InitRam	
	ldr r3, |Image$$RO$$Limit|

0	
	ldmia	r0!, {r4-r7}
	stmia	r2!, {r4-r7}
	cmp	r2, r3
	bcc	%B0
	
	sub	r2, r2, r3
	sub	r0, r0, r2				
		
InitRam	
	ldr	r2, |Image$$RW$$Base|
	ldr	r3, |Image$$ZI$$Base|	
0
	cmp	r2, r3								;copy 初始化代码
	ldrcc	r1, [r0], #4
	strcc	r1, [r2], #4
	bcc	%B0	

	mov	r0,	#0  							;初始化ZI区域为0
	ldr	r3,	|Image$$ZI$$Limit|
1	
	cmp	r2,	r3
	strcc	r0, [r2], #4
	bcc	%B1	
			

		;跳入Main函数,进入C程序。
		bl	Main							;bl	Main
    	b	.                       




;堆栈初始化子程序
InitStacks
	;UndefMode堆栈
	mrs	r0,cpsr
	bic	r0,r0,#MODEMASK
	orr	r1,r0,#UNDEFMODE|NOINT
	msr	cpsr_cxsf,r1						;进入UndefMode模式
	ldr	sp,=UndefStack						;设置UndefMode堆栈
	
	;AbortMode堆栈
	orr	r1,r0,#ABORTMODE|NOINT
	msr	cpsr_cxsf,r1						;AbortMode
	ldr	sp,=AbortStack
	
	;IRQMode堆栈
	orr	r1,r0,#IRQMODE|NOINT
	msr	cpsr_cxsf,r1						;IRQMode
	ldr	sp,=IRQStack	
    
    ;FIQMode堆栈
	orr	r1,r0,#FIQMODE|NOINT
	msr	cpsr_cxsf,r1						;FIQMode
	ldr	sp,=FIQStack
	
	;SVCMode堆栈
	bic	r0,r0,#MODEMASK|NOINT
	orr	r1,r0,#SVCMODE
	msr	cpsr_cxsf,r1						;返回超级用户模式并设置超级用户栈空间
	ldr	sp,=SVCStack
	
	mov	pc,lr 								;子程序返回

	

	LTORG 									;声明一个数据缓冲池的开始   
;存储器控制的参数	
SMRDATA 	DATA
        	DCD 0x2211D110
    		DCD 0x0700
    		DCD 0x7FFC
    		DCD 0x0700
    		DCD 0x0700
    		DCD 0x0700
    		DCD 0x0700
    		DCD 0x18005
    		DCD 0x18005
    		DCD 0x008E0459   
			DCD 0x32        
    		DCD 0x30          
    		DCD 0x30       

;********************************************************************************
;ARM汇编可读写数据段,段名为RamData
;********************************************************************************	

    ALIGN 									;通过添加补丁字节使当前位置满足一定的对齐方式
	AREA RamData, DATA, READWRITE

;定义一个结构化的内存表(storage map)的首地址,地址为0x33ff8000
    MAP  _ISR_STARTADDRESS 					;0x33ff8000
HandleReset 	#   4  						;#--Field:定义一个结构化内存表中的数据域,该域为4个字节
HandleUndef 	#   4
HandleSWI   	#   4
HandlePabort    #   4
HandleDabort    #   4
HandleReserved  #   4
HandleIRQ   	#   4
HandleFIQ   	#   4

HandleEINT0   	#   4
HandleEINT1   	#   4
HandleEINT2   	#   4
HandleEINT3   	#   4
HandleEINT4_7	#   4
HandleEINT8_23	#   4
HandleRSV6		#   4
HandleBATFLT   	#   4
HandleTICK   	#   4
HandleWDT		#   4
HandleTIMER0 	#   4
HandleTIMER1 	#   4
HandleTIMER2 	#   4
HandleTIMER3 	#   4
HandleTIMER4 	#   4
HandleUART2  	#   4
HandleLCD 		#   4
HandleDMA0		#   4
HandleDMA1		#   4
HandleDMA2		#   4
HandleDMA3		#   4
HandleMMC		#   4
HandleSPI0		#   4
HandleUART1		#   4
HandleRSV24		#   4
HandleUSBD		#   4
HandleUSBH		#   4
HandleIIC   	#   4
HandleUART0 	#   4
HandleSPI1 		#   4
HandleRTC 		#   4
HandleADC 		#   4
	END

⌨️ 快捷键说明

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