您的位置 首页 观点

S3C2410发动代码详解(1)

花了好几在的时间研究S3C2410r的启动代码,终于看完!在参考了一些资料后,加上自己的理解,留下点笔记。有些地方可能不正确,有待改…

花了好几在的时刻研讨S3C2410r的发动代码,总算看完!在参阅了一些材料后,加上自己的了解,留下点笔记。有些当地或许不正确,有待改正:

一般,发动代码是指CPU复位后到进入C言语的main函数之前需求履行的那段汇编代码.这是由于C言语程序的运转需求具有必定的条件,比方:分配好外部数据空闿仓库空间和中止进口等筿别的汇编代码能够更直接的对硬件进行操使功率更高. 一般发动代码是放圿410init.s汇编文件;特别功用寄存器界说在2410addr.s;Memory Bank 装备在mencfg.s;还有体系的选项等在option.s文件;2410init.s不只包括复位后履行的代码,还包括CPU进入掉电形式,发生中止等和处理器直接相关的,用汇编完成的代码.

;=========================================
; NAME: 2410INIT.S
; DESC: C start up codes
; Configure memory, ISR ,stacks
;Initialize C-variables
; HISTORY:
; 2002.02.25:kwtark: ver 0.0
; 2002.03.20:purnnamu: Add some functions for testing STOP,POWER_OFF mode
; 2003.05.19:jcs:Configure UPLL in init.s not usbmain.c
;=========================================

//首要,发动代码界说了一些常量,相当于C中的INCLUDE

GET option.inc
GET memcfg.inc
GET 2410addr.inc

BIT_SELFREFRESH EQU(1<<22)//自改写常量

//;;处理器形式常量
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f //体系形式
NOINT EQU 0xc0//屏蔽一切的中止,即置位I,F位

//;The location of stacks界说处理器各形式下仓库地址常量
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 ~

;check if tasm.exe is used.
;arm处理器有两种作业状况 1.arm:32位 这种作业状况下履行字对准的arm指令 2.Thumb:16位 这种作业状况履行半字对准的Thumb指令
;由于处理器分为16位 32位两种作业状况程序的编译器也是分16位和32两种编译办法 所以下面的程序用于依据处理器作业状况确认编译器编译办法
;code16伪指令指示汇编编译器后边的指令为16位的thumb指令
;code32伪指令指示汇编编译器后边的指令为32位的arm指令
;这段是为了一致现在的处理器作业状况和软件编译办法(16位编译环境运用tasm.exe编译)
GBLL THUMBCODE;设置一个大局逻辑变量
[ {CONFIG} = 16;if config==16 这儿表明你的现在处于抢先地16位编译办法,{CONFIG}为汇编器内置变量
THUMBCODE SETL {TRUE};设置THUMBCODE 为 true
CODE32;转入32位编译形式
|;else
THUMBCODE SETL {FALSE};设置THUMBCODE 为 false
]

[ THUMBCODE;if THUMBCODE==TRUE
CODE32;for start-up code for Thumb mode;转入32位编译办法
]

;留意下面这段程序是个宏界说很多人对这段程序不了解 我再次着重这是一个宏界说 所以我们要留意了下面包括的HandlerXXX HANDLER HandleXXX将都被下面这段程序打开。

;这段程序用于把中止服务程序的首地址装载到pc中,有人称之为“加载程序”。其大致作用是把宏的第一个参数$HandlerLabel 转变为一个标号,然后让程序跳转到第二个参数 $HandleLabel (第二个参数应该为一个地址)对应的值的地址去。能够分分出,sp和r0在履行前后都没有改变,程序就完成了跳转

;本初始化程序界说了一个数据区(在文件最终),34个字空间,寄存相应中止服务程序的首地址。每个字空间都有一个标号,以Handle***命名。

;在向量中止形式下运用“加载程序”来履行中止服务程序。

;这儿就必须讲一下向量中止形式和非向量中止形式的概念

;向量中止形式是当cpu读取坐落0x18处的IRQ中止指令的时分,体系主动读取对应于该中止源确认地址上的指令替代0x18处的指令,经过跳转指令体系就直接跳转到对应地址

;函数中 节省了中止处理时刻提高了中止处理速度标 例如 ADC中止的向量地址为0xC0,则在0xC0处放如下代码:ldr PC,=HandlerADC 当ADC中止发生的时分体系会

;主动跳转到HandlerADC函数中

;非向量中止形式处理办法是一种传统的中止处理办法,当体系发生中止的时分,体系将interrupt pending寄存器中对应标志方位位 然后跳转到坐落0x18处的一致中止

;函数中 该函数经过读取interrupt pending寄存器中对应标志位 来判别中止源 并依据优先级联系再跳到对应中止源的处理代码中

MACRO
$HandlerLabel HANDLER $HandleLabel //
$HandlerLabel
sub sp,sp,#4;削减sp(预留一个字,用于寄存转跳地址)
stmfd sp!,{r0};把作业寄存器压入栈(lr does not push because it return to original address)
ldr r0,=$HandleLabel ;将HandleXXX的址址放入r0
ldr r0,[r0];把HandleXXX所指向的内容(也便是中止程序的进口)放入r0
str r0,[sp,#4];把中止服务程序(ISR)压入栈,保存在高一个地址预留的空间中,但SP没变。
ldmfd sp!,{r0,pc} ;用出栈的办法康复r0的原值和为pc设定新值(也就完成了到ISR的转跳);

ADS仅支撑FD(满递减)型仓库,故只能用stmfd和ldmfd
MEND

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/guandian/274384.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部