ARM启动代码分析.docx

上传人:b****2 文档编号:2555216 上传时间:2023-05-04 格式:DOCX 页数:11 大小:18.15KB
下载 相关 举报
ARM启动代码分析.docx_第1页
第1页 / 共11页
ARM启动代码分析.docx_第2页
第2页 / 共11页
ARM启动代码分析.docx_第3页
第3页 / 共11页
ARM启动代码分析.docx_第4页
第4页 / 共11页
ARM启动代码分析.docx_第5页
第5页 / 共11页
ARM启动代码分析.docx_第6页
第6页 / 共11页
ARM启动代码分析.docx_第7页
第7页 / 共11页
ARM启动代码分析.docx_第8页
第8页 / 共11页
ARM启动代码分析.docx_第9页
第9页 / 共11页
ARM启动代码分析.docx_第10页
第10页 / 共11页
ARM启动代码分析.docx_第11页
第11页 / 共11页
亲,该文档总共11页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

ARM启动代码分析.docx

《ARM启动代码分析.docx》由会员分享,可在线阅读,更多相关《ARM启动代码分析.docx(11页珍藏版)》请在冰点文库上搜索。

ARM启动代码分析.docx

ARM启动代码分析

ARM启动代码分析

ARM启动代码分析-philips的LPC2xxx系列

/**********************************************************************************

*File:

startup.s

*Author:

Embestw.h.xie2005.02.21

*Desc:

lpc22xx\lpc212x\lpc211x\lpc210xstartupcode

*History:

*notemodify:

cuijianjie2006-4-25

*comment:

**********************************************************************************/

#处理器的七种工作方式的常量定义

.EQUMode_USR,0x10#用户模式

.EQUMode_FIQ,0x11#FIQ模式

.EQUMode_IRQ,0x12#IRQ模式

.EQUMode_SVC,0x13#超级用户模式

.EQUMode_ABT,0x17#终止模式

.EQUMode_UND,0x1B#未定义模式

.EQUMode_SYS,0x1F#系统模式

#中断屏蔽位

.EQUI_Bit,0x80//IRQ中断控制位,当被置位时,IRQ中断被禁止

.EQUF_Bit,0x40//FIQ中断控制位,当被置位时,FIQ中断被禁止

#状态屏蔽位

.EQUT_bit,0x20//T位,置位时在Thumb模式下运行,清零时在ARM下运行

#定义程序入口点

.globl_start

.code32

.TEXT

_start:

#中断向量表

Vectors:

LDRPC,Reset_Addr//把Reset_Addr地址处的内容放入PC中

LDRPC,Undef_Addr

LDRPC,SWI_Addr

LDRPC,PAbt_Addr

LDRPC,DAbt_Addr

.long0xb9205f80@keepinterruptvectorssumis0

LDRPC,[PC,#-0xff0]//当前PC值减去0xFF0等于IRQ中断入口地址

LDRPC,FIQ_Addr

#地址表:

Reset_Addr:

#该地址标号存放Reset_Handler程序段的入口地址

.longReset_Handler

Undef_Addr:

#该地址标号存放Undef_Handler程序段的入口地址

.longUndef_Handler

SWI_Addr:

#该地址标号存放SWI_Handler程序段的入口地址

.longSWI_Handler

PAbt_Addr:

#该地址标号存放PAbt_Handler程序段的入口地址

.longPAbt_Handler

DAbt_Addr:

.longDAbt_Handler

.long0

IRQ_Addr:

#地址标号处存放一个无效的数据

.long0

FIQ_Addr:

#该地址标号存放FIQ_Handler程序段的入口地址

.longFIQ_Handler

Undef_Handler:

BUndef_Handler

PAbt_Handler:

BPAbt_Handler

DAbt_Handler:

BDAbt_Handler

#软中断的中断服务子程序入口地址

SWI_Handler:

STMFDsp!

{r0-r3,r12,lr}//入栈,现场数据保护

MOVr1,sp//把堆栈指针SP存入R1中

MRSr0,spsr//把SPSR值存入R0,SPSR值为产生软中断时的CPSR

TSTr0,#T_bit//判断R0(SPSR)的T位是否为0

#SPSR的T位不为0,工作在Thumb模式下

LDRNEHr0,[lr,#-2]//SPSR的T位不为0,则[lr-2]-〉r0

BICNEr0,r0,#0xFF00//SPSR的T位不为0,清除r0的Bit8~Bit15位

#SPSR的T位为0,工作在ARM模式下

LDREQr0,[lr,#-4]//SPSR的T位为0,则[lr-4]-〉r0

BICEQr0,r0,#0xFF000000//SPSR的T位为0,清除r0的Bit24~Bit131位

#R0isinterruptnumber//R0是中断号

#R1isstackpoint//R1是堆栈指针

BLSWI_Exception//进入软中断处理程序

LDMFDsp!

{r0-r3,r12,pc}^//出栈,现场数据恢复

#快速响应中断的中断服务自程序的入口地址

FIQ_Handler:

STMFDSP!

{R0-R3,LR}//入栈的现场保护

#BLFIQ_Exception//进入FIQ的中断处理程序

LDMFDSP!

{R0-R3,LR}//出栈,恢复现场

SUBSPC,LR,#4//返回到主程序

#复位后程序处理的入口地址

Reset_Handler:

BLRemapSRAM//进行存储器映射的操作

#下面几行代码用来判断当前的工作模式

MRSR0,CPSR//读CPSR到寄存器R0

ANDR0,R0,#0x1F//R0=R0AND0x1F

CMPR0,#Mode_USR//比较R0和#Mode_USR,二者相减

//如果相等则说明当前处在用户模式下,需要通过产生11号软中断进入系统模式。

因为下面的初始化堆栈

//需要在不同的工作模式下切换,而在用户模式下不能直接切换,只有系统模式可以,所以要通过产生11

//号软中断切换到用户模式。

SWIEQ#11

BLInitStack//进行堆栈初始化工作

ARM启动代码分析-philips的LPC2xxx系列32006-7-2414:

33:

00

#------------------------------------------------------------------------------

#-初始化C变量

#------------------------

#-下表由连接器自动产生

#-RO:

只读=代码区。

#-RW:

可读可写=预先初始化的数据(初始化的全局变量)和预先被清零的数据(未初始化的全局变量)。

.

#-ZI:

预先被清零的数据区(未初始化的全局变量)

#-预先被初始化的数据区定位在代码区之后。

#-预先被清零的数据区定位在预先被初始化的数据区之后。

#-注意数据区的位置:

#-I如果用ARMSDT,当链接器选择no-rw-base时,数据区被映射在代码区之后

#-你可以把数据区房子内部的SRAM(-rw-base=0x40or0x34)中

#-或者放在外部的SRAM(-rw-base=0x2000000)中。

#-注意:

为了提高代码的密度,预先被初始化的数据必须尽可能的少。

#------------------------------------------------------------------------------

#该部分程序功能:

先判断当前是在RAM中运行还是在FLASH中运行,如果在FLASH中运行,先把FLASH

#中的预先赋值的RW段数据和未赋值的ZI段数据都搬移到RAM区中,再把ZI段数据全部清零;如果程#序就是在RAM中运行,则直接把ZI段数据清零。

.externImage_RO_Limit/*ROM区中数据段的起始地址*/

.externImage_RW_Base/*RW段起始地址*/

.externImage_ZI_Base/*ZI段的起始地址*/

.externImage_ZI_Limit/*ZI段的结束地址加1*/

ldrr0,=Image_RO_Limit/*取ROM区中数据段的首地址*/

ldrr1,=Image_RW_Base/*取RAM区中RW段的目标首地址*/

ldrr3,=Image_ZI_Base/*取RAM区中ZI段的首地址*/

cmpr0,r1/*比较ROM区中数据段首地址和RAM区中RW段目标首地址*/

beqNoRW/*相等代表当前是在RAM中运行*/

LoopRw:

cmpr1,r3/*不相等则和RAM区中ZI段的目标地址比较*/

ldrccr2,[r0],#4/*如果r1

strccr2,[r1],#4/*如果r1

bccLoopRw/*如果r1

NoRW:

ldrr1,=Image_ZI_Limit/*取ZI段的结束地址*/

movr2,#0/*将r2赋0*/

LoopZI:

cmpr3,r1/*将ZI段清零*/

strccr2,[r3],#4/*如果r3

bccLoopZI/*如果r3

.externMain/*声明外部变量*/

BMain/*t跳转到用户的主程序入口*/

#为每一种模式建立堆栈,ARM堆栈指针向下生长

InitStack:

MOVR1,LR//把该子程序返回地址保留在R1中

LDRR0,=Top_Stack//取栈定地址到R0中

#进入未定义模式,并禁止FIQ中断和IRQ中断

MSRCPSR_c,#Mode_UND|I_Bit|F_Bit

#设置未定义模式下堆栈的栈顶指针

MOVSP,R0

SUBR0,R0,#UND_Stack_Size#未定义模式下堆栈深度

#进入终止模式,并禁止禁止FIQ中断和IRQ中断

MSRCPSR_c,#Mode_ABT|I_Bit|F_Bit

#紧接着未定义模式下的堆栈,设置终止模式下栈顶指针

MOVSP,R0

SUBR0,R0,#ABT_Stack_Size#终止模式下堆栈深度

#进入FIQ模式,并禁止FIQ中断和IRQ中断

MSRCPSR_c,#Mode_FIQ|I_Bit|F_Bit

#紧接着终止模式下的堆栈,设置下FIQ模式下栈顶指针

MOVSP,R0

SUBR0,R0,#FIQ_Stack_Size#FIQ模式下的堆栈深度

#进入IRQ模式,并禁止FIQ中断和IRQ中断

MSRCPSR_c,#Mode_IRQ|I_Bit|F_Bit

#紧接着FIQ模式下的堆栈,设置IRQ模式下的栈顶指针

MOVSP,R0

SUBR0,R0,#IRQ_Stack_Size#IRQ模式下的堆栈深度

#进入超级用户模式,并禁止FIQ中断和IRQ中断

MSRCPSR_c,#Mode_SVC|I_Bit|F_Bit

#紧接着IRQ模式下的堆栈,设置超级用户下的栈顶指针

MOVSP,R0

SUBR0,R0,#SVC_Stack_Size#超级用户下的堆栈深度

#设置进入用户模式

MSRCPSR_c,#Mode_USR

#紧接着超级用户模式下的堆栈,设置用户模式下的栈顶指针,剩余的空间都开辟为堆栈

MOVSP,R0

MOVPC,R1#堆栈初始化子程序返回

#重映射SRAM区

RemapSRAM:

MOVR0,#0x40000000//RAM区首地址

LDRR1,=Vectors//向量表首地址

#下面一段程序是把从0x00000000开始的64个字节(FLASH中的中断向量表和地址表)搬移到以

#0x40000000为首地址的RAM区中

LDMIAR1!

{R2-R9}//把以[R1]为首地址的32个字节数据装载到R2-R9中

STMIAR0!

{R2-R9}//把R2-R9中的数据存入以[R0]为首地址的单元中

LDMIAR1!

{R2-R9}//把以[R1]为首地址的32个字节数据装载到R2-R9中

STMIAR0!

{R2-R9}////把R2-R9中的数据存入以[R0]为首地址的单元中

#下面几行代码设置存储器映射控制寄存器

LDRR0,=MEMMAP//取MEMMAP地址到R0

MOVR1,#0x02

STRR1,[R0]//给MEMMAP赋值为0x02,设置中断向量从RAM区从新映射

movpc,lr//跳转到主程序

#下面一段程序代码是进入软中断来切换系统的工作模式,当希望从一种模式切换入另一种模式时,可以通

#过调用下面对应标号的程序段进入软中断。

在软中断处理程序中会根据所给定的中断号处理,执行SWI#num后软中断号被存入R0中。

.globldisable_IRQ

.globlrestore_IRQ

.globlToSys

.globlToUser

#禁止IRQ

disable_IRQ:

STMFDSP!

{LR}//把LR值压入堆栈

swi#0//产生0号软中断,0-〉R0

LDMFDSP!

{pc}//恢复PC值,返回

#恢复IRQ

restore_IRQ:

STMFDSP!

{LR}//把LR值压入堆栈

swi#1//产生1号软中断,1–〉R0

LDMFDSP!

{pc}//恢复PC值,返回

#进入系统工作模式

ToSys:

STMFDSP!

{LR}//把LR值压入堆栈

swi#11//产生11号软中断,11–〉R0

LDMFDSP!

{pc}//恢复PC值,返回

#进入用户工作模式

ToUser:

STMFDSP!

{LR}//把LR值压入堆栈

swi#12//产生12号软中断,11–〉R0

LDMFDSP!

{pc}//恢复PC值,返回

本文来自CSDN博客,转载请标明出处:

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2