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

📄 bootloader.s

📁 NUCLEUS PLUS操作系统在STR710 arm上的移植代码
💻 S
📖 第 1 页 / 共 3 页
字号:
;** 函数名称: ChipRemapInterRam ChipRemapExtRam 
;** 功能描述: 向量复制到指定的存储区
;** 
;** 参    数: None
;**
;** 返 回 值: None
;**         
;** 作   者: 罗辉联
;** 日   期: 2006年6月10日
;**-------------------------------------------------------------------------------------------------------
;** 修 改 人: 
;** 日   期: 
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/  
	EXPORT	REMAP_InterRam	
REMAP_InterRam
		MOV     R10, LR							;//函数返回地址保存在R10中
		
  		MOV     R8,  #REMAP_INTER_RAM_BASE      ;//映射后内部RAM的地址0x0
    	ADD     R9,  PC,#-(8+.-InitVectors)     ;//读值处(相对)
    	LDMIA   R9!, {R0-R7}                    ;//读8个异常向量
    	STMIA   R8!, {R0-R7}                    ;//写到目标地址
    
    	LDMIA   R9!, {R0-R7}                    ;//读8个异常处理函数地址
    	STMIA   R8!, {R0-R7}                    ;//函数地址写到目标地址
    	
    	MOV     PC,  R10						;//程序返回
    	

	EXPORT	REMAP_ExtRam  
REMAP_ExtRam
		MOV     R10, LR							;//函数返回地址保存在R10中
		
  		MOV     R8,  #REMAP_EXT_RAM_BASE        ;//映射后内部RAM的地址0x0
    	ADD     R9,  PC,#-(8+.-InitVectors)     ;//读值处(相对)
    	LDMIA   R9!, {R0-R7}                    ;//读8个异常向量
    	STMIA   R8!, {R0-R7}                    ;//写到目标地址
    
    	LDMIA   R9!, {R0-R7}                    ;//读8个异常处理函数地址
    	STMIA   R8!, {R0-R7}                    ;//函数地址写到目标地址
    	
    	MOV     PC,  R10						;//程序返回
      

;//*******************************************************************************************************   
;//   
;//                            REMAP 选项定义 
;//
;//   根据STARM的映射规则,定义不同的映射编译开关
;//                    
;//         
;//*******************************************************************************************************        

;            GBLL  remapping			;//如果进入MAIN前需要映射存储器,定义此逻辑变量

;             GBLL  remap_ram			;//如果需要将内部RAM映射到0x0000,定义此逻辑变量

;            GBLL  remap_flash			;//如果需要将内部FLASH映射到0x0000,定义此逻辑变量

;            GBLL  remap_ext			;//如果需要将外部存储器映射到0x0000,定义此逻辑变量
;/*********************************************************************************************************
;** 函数名称: INT_Initialize
;** 功能描述: 复位入口
;** 
;** 参    数: 无
;**
;** 返 回 值: 无
;**         
;** 作   者: 罗辉联
;** 日   期: 2006年5月30日
;**-------------------------------------------------------------------------------------------------------
;** 修 改 人: 
;** 日   期: 
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
    EXPORT  INT_Initialize        
INT_Initialize
    ENTRY				;//程序入口点
;{		 
		LDR     PC, =NextInst
NextInst
		NOP		         ;//等待OSC稳定,此时使用XTAL的频率
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		 
; 保证处理器处于管理模式
		MRS     a1,CPSR                         ;//获得当前的CPSR
		BIC     a1,a1,#MODE_MASK                ;//清除当前的工作模式位
		ORR     a1,a1,#SVC_MODE                 ;//设置管理模式位
		ORR     a1,a1,#NoInt                    ;//保证IRQ/FIQ处于禁止状态
		MSR     CPSR_cxsf,a1                    ;//设置新的CPSR 
        
        BL		 ChipResetInit					;//ARM芯片复位初始化,在ChipReset.s中定义
        
  IF :DEF: remapping							;//重映射选择						   
    IF :DEF: remap_flash
        MOV     r0, #REMAP_INTER_FLASH
    ENDIF
    IF :DEF: remap_ram
        MOV     r0, #REMAP_INTER_RAM
    ENDIF
    IF :DEF: remap_ext
        MOV     r0, #REMAP_EXT_MEMORY
    ENDIF
        LDR     r1, =CPM_BASE_ADDR
        LDRH    r2, [r1, #BOOTCR_OFF_ADDR]		;//读取BOOTCR值
        BIC     r2, r2, #0x03             		;//复位BOOTCR的低两位
        ORR     r2, r2, r0                		
        STRH    r2, [r1, #BOOTCR_OFF_ADDR]		;//写映射类型值
  ENDIF 

;初始化各种数据(主要是全局变量),把已初始化的数据从ROM中复制到RAM中,并在RAM中建立ZI数据段,包含那些未初始化的数据
    	LDR     a1, =|Image$$RO$$Limit|         ;//引入RO数据段的起始地址
    	LDR     a2, =|Image$$RW$$Base|           ;//引入RW数据段的起始地址
    	LDR     a4, =|Image$$ZI$$Base|          ;//引入ZI数据段的起始地址
    	CMP     a1, a2                          ;//需要从ROM复数据制到RAM吗
    	BEQ     BSS_Clear                       ;//处理ZI数据段还是复制数据

;将初始化的数据从ROM复制到RAM中    
ROM_copy_loop
    	CMP     a2, a4                          ;//需要需要复制数据吗
    	LDRCC   a3, [a1], #4                    ;//从ROM获得需要复制的数据
    	STRCC   a3, [a2], #4                    ;//将复制的数据存储在RAM区
    	BCC     ROM_copy_loop                   ;//继续复制数据

;初始化ZI数据段    
BSS_Clear
    	LDR     a2, =|Image$$ZI$$Limit|         ;//引入ZI数据段的结束地址
    	MOV     a3, #0                          ;//设置清除初始值
BSS_RAM_Clear_Loop
    	CMP     a4, a2                          ;//比较ZI数据段(BBS)的开始地址和结束地址是否相等?
    	STRCC   a3, [a4], #4                    ;//清除一个字
    	BCC     BSS_RAM_Clear_Loop              ;//判断是否清除完毕
    	

;建立各种数据栈,其起始地址紧接在ZI数据段(BBS)的尾部,所以在建立各种数据栈之前,应该初始化好ZI数据段(BBS
BSS_End_Ptr
		DCD     |Image$$ZI$$Limit|
                                                   

;建立系统模式下的数据栈-------堆栈的首地址来自于ZI(初始化为零的数据段)段的结束地址之后
 		LDR     a1,[pc, #BSS_End_Ptr-.-8]      ;// 获得ZI数据段(BSS)结束的地址 
		MOV     a2,#SYS_STACK_SIZE              ;// 获得系统堆栈大小(1024byte)
		SUB     a2,a2,#4                        ;// Subtract one word for first addr
		ADD     a3,a1,a2                        ;// 设置系统堆栈区间
		BIC     a3,a3,#3                        ;// 保证堆栈字对齐	
	
;确定系统堆栈的界限	
		MOV     v7,a1                           ;// Setup initial stack limit	
		LDR     a4,[pc, #System_Limit-.-8]      ;//获得系统堆栈最高地址
		STR     v7,[a4, #0]                     ;// Save stack limit
	
		MOV     sp,a3                           ;// Setup initial stack pointer      
		LDR     a4,[pc, #System_Stack-.-8]      ;// 获得系统堆栈地址
		STR     sp,[a4, #0]                     ;// 保存System_Stack堆栈指针
	
;建立IRQ模式下的数据栈	
		MOV     a2,#IRQ_STACK_SIZE              ;// 获得 IRQ 堆栈大小(512byte)
		ADD     a3,a3,a2                        ;// 分配 IRQ 堆栈区域
		BIC     a3,a3,#3                        ;// 保证字对齐
		MRS     a1,CPSR                         ;// 获得当前 CPSR 的值
		BIC     a1,a1,#MODE_MASK                ;// 清除当前的工作模式位
		ORR     a1,a1,#IRQ_MODE                 ;// 设置中断模式位
		MSR     CPSR_cxsf,a1                    ;// 写入 IRQ 模式位值
		MOV     sp,a3                           ;// 设置中断模式堆栈	
;建立FIQ模式下的数据栈	
		MOV     a2,#FIQ_STACK_SIZE              ;// 获得 FIQ 堆栈大小(512byte)
		ADD     a3,a3,a2                        ;// 分配 FIQ 堆栈区域
		BIC     a3,a3,#3                        ;// 保证字对齐
		MRS     a1,CPSR                         ;// 获得当前 CPSR 的值
		BIC     a1,a1,#MODE_MASK                ;// 清除当前的工作模式位
		ORR     a1,a1,#FIQ_MODE                 ;// 设置快速中断模式位
		MSR     CPSR_cxsf,a1                    ;// 写入 FIQ 模式位值 	
		MOV     sp,a3                           ;// 设置快速中断模式堆栈	
;建立ABORT模式下的数据栈	    	 
      	MRS     a1,CPSR                 		;//获得当前 CPSR 的值
        BIC     a1,a1,#MODE_MASK              	;//获得当前 CPSR 的值
        ORR     a1,a1,#ABT_MODE             	;//设置 Abort 模式位
        MSR     CPSR_cxsf,a1                  	;//写入 Abort 模式位值
        LDR     sp,Exception_Stack			   	;//设置 Abort 模式堆栈	
;建立UNDEF模式下的数据栈	  
        MRS     a1,CPSR                     
        BIC     a1,a1,#MODE_MASK              
        ORR     a1,a1,#UNF_MODE             
        MSR     CPSR_cxsf,a1                       
        LDR     sp,Exception_Stack		
;返回到管理模式	
		MRS     a1,CPSR                         ;// 获得当前 CPSR 的值
		BIC     a1,a1,#MODE_MASK                ;// 清除当前的工作模式位
		ORR     a1,a1,#SVC_MODE                 ;// 设置管理模式位
		MSR     CPSR_cxsf,a1                    ;// 所有中断堆栈设置完成,返回到管理模式 
	   
;/*-------------------------------------------------------------------------------------------------------
;**                        建立定时器高级中断服务所需的数据栈                                       
;**         初始化定时器高级中断服务中需要用到的变量----方便管理定时器高级中断服务程序              
;**------------------------------------------------------------------------------------------------------*/ 
;    TMD_HISR_Stack_Ptr = (VOID *) a3;
;    TMD_HISR_Stack_Size = TIMER_SIZE;
;    TMD_HISR_Priority = TIMER_PRIORITY;

;设置定时器高级中断服务(HISR)堆栈指针  TMD_HISR_Stack_Ptr = (VOID *) a3;
    	LDR     a4,[pc,#HISR_Stack_Ptr-.-8]     ;//获得定时器高级中断服务(HISR)的堆栈指针
		ADD     a3,a3,#4                        ;//向后移动一个字的空间
		STR     a3,[a4, #0]                     
	                    
;设置定时器高级中断服务(HISR)堆栈大小  TMD_HISR_Stack_Size = TIMER_SIZE;
		MOV     a2,#TIMER_SIZE                  ;//获得定时器高级中断服务(HISR)的stack size
		BIC     a2,a2,#3                        ;//保证字对齐
		ADD     a3,a3,a2                        ;//从可获取的内存中为定时器高级中断服务程序分配堆栈空间
		LDR     a4,[pc,#HISR_Stack_Size-.-8]
		STR     a2,[a4, #0]                     ;//保存堆栈指针                   
		
;设置定时器高级中断服务的优先级(初始化时设为最低)  TMD_HISR_Priority = TIMER_PRIORITY;

⌨️ 快捷键说明

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