S3C2410启动代码详解(2)

发布者:vettykatty最新更新时间:2016-08-14 来源: eefocus关键字:S3C2410  启动代码 手机看文章 扫描二维码
随时随地手机看文章
;========================================================================================

//在这里用IMPORT伪指令(和c语言的extren一样)引入|Image$$RO$$Base|,|Image$$RO$$Limit|...

//这些变量是通过ADS的工程设置里面设定的RO Base和RW Base设定的,最终由编译脚本和连接程序导入程序.

//那为什么要引入这玩意呢,最简单的用处是可以根据它们拷贝自已 ,从把RW和ZI变量从加载域中复制到运行域中

//一个arm由RO,RW,ZI三个断组成 其中RO为代码段,RW是已经初始化的全局变量,ZI是未初始化的全局变量(对于GNU工具 对应的概念是TEXT ,DATA,BSS)。

 

;========================================================================================
IMPORT  |Image$$RO$$Base|    ; ROM code(也就是代码)的开始地址 
IMPORT  |Image$$RO$$Limit|    ; ROM code的结束地址 (也就是RW在加载域中的起始地址) 
IMPORT  |Image$$RW$$Base|   ; 在运行域中要初始化的RAM的开始地址 
IMPORT  |Image$$ZI$$Base|      ; area(需要清零的RAM区域)的开始地址 
IMPORT  |Image$$ZI$$Limit|       ; area的结束地址 

;这里引入一些在其它文件中实现在函数,包括为我们所熟知的main函数
IMPORT  Main    ; The main entry of mon program

;从这里开始就是正真的代码入口了! 
AREA    Init,CODE,READONLY       ;这表明下面的是一个名为Init的代码段 
ENTRY                                            ;定义程序的入口(调试用) 其中关键字ENTRY是指定编译器保留这段代码,因为

                                                       编译器可能会认为这是一段亢余代码而加以优化。链接的时候要确保这段代码

                                                         被链接在0地址处,并且作为整个程序的入口 
;1)The code, which converts to Big-endian, should be in little endian code. 
;2)The following little endian code will be compiled in Big-Endian mode. 
;  The code byte order should be changed as the memory bus width. 
;3)The pseudo instruction,DCD can not be used here because the linker generates error. 
ASSERT :DEF:ENDIAN_CHANGE 
[ ENDIAN_CHANGE                         ;下面是大小端的一个判断,在Option.inc里已经设为FALSE 
     ASSERT  :DEF:ENTRY_BUS_WIDTH 
     [ ENTRY_BUS_WIDTH=32          //‘[’=IF
      b ChangeBigEndian                  ;DCD 0xea000007 
     ] 

     [ ENTRY_BUS_WIDTH=16            
      andeq r14,r7,r0,lsl #20              ;DCD 0x0007ea00 
     ] 

     [ ENTRY_BUS_WIDTH=8 
      streq r0,[r0,-r10,ror #1]             ;DCD 0x070000ea 
     ] 

     b ResetHandler ;因为设成FALSE,所以系统复位后就来到这了,转跳到复位程序入口 

 

    ]

//=====================================================================================

;ARM要求中断向量表必须放置在仿地址开始,连续8X4字节的空间内.每当一个中断发生以后,ARM处理器便强制把PC指针置为向量表中对应中断类型的地址值。因为每个中断只占据向量表中1个字的存储空间,只能放置一条ARM指令,使程序跳转到存储器的其他地方,再执行中断处理

//=====================================================================================
b HandlerUndef           ;转跳到Undefined mode程序入口 
b HandlerSWI              ;转跳到SWI 中断程序入口 
b HandlerPabort          ;转跳到PAbort(指令异常)程序入口 
b HandlerDabort          ;转跳到DAbort(数据异常)程序入口 
b .                                ;保留 
b HandlerIRQ              ;转跳到IRQ 中断程序入口 
b HandlerFIQ              ;转跳到FIQ 中断程序入口

;@0x20 不知道是什么意思,地址?
b EnterPWDN ; Must be @0x20.

;================================================================================== 
;下面是改变大小端的程序,这里采用直接定义机器码的方式,至说为什么这么做就得问三星了 
;反正我们程序里这段代码也不会去执行,不用去管它 
;================================================================================== 
ChangeBigEndian    //通过设置CP15中的C1的位7来设置存储格式为大端模式。
;@0x24 
[ ENTRY_BUS_WIDTH=32 
     DCD 0xee110f10 ;0xee110f10 => mrc p15,0,r0,c1,c0,0 
     DCD 0xe3800080 ;0xe3800080 => orr r0,r0,#0x80;  //Big-endian 
     DCD 0xee010f10 ;0xee010f10 => mcr p15,0,r0,c1,c0,0 

[ ENTRY_BUS_WIDTH=16 
     DCD 0x0f10ee11 
     DCD 0x0080e380 
     DCD 0x0f10ee01 

[ ENTRY_BUS_WIDTH=8 
     DCD 0x100f11ee 
     DCD 0x800080e3 
     DCD 0x100f01ee 
    ] 
DCD 0xffffffff  ;swinv 0xffffff is similar with NOP and run well in both endian mode. 
DCD 0xffffffff 
DCD 0xffffffff 
DCD 0xffffffff 
DCD 0xffffffff 
b ResetHandler

;Function for entering power down mode,下面这段程序为进入掉电模式及从掉电模式中唤醒的相关设置和处理
; 1. SDRAM should be in self-refresh mode. SDRAm应该设置为自刷新的模式
; 2. All interrupt should be maksked for SDRAM/DRAM self-refresh. 所有中断必须屏蔽 for SDRAM/DRAM self-ref
; 3. LCD controller should be disabled for SDRAM/DRAM self-refresh. LCD 控制器关闭
; 4. The I-cache may have to be turned on.   
; 5. The location of the following code may have not to be changed.

//;void EnterPWDN(int CLKCON);           //PWDN:powerdown
EnterPWDN   
 mov r2,r0  ;r2=rCLKCON                 //rCLKCONr [3;2]位为电源模式标置位。若[3]为1,表示转为了掉电模式
 tst r0,#0x8  ;POWER_OFF mode?   //按位与判断,若[3]为1则跳转到ENTER_POWER_OFF
 bne ENTER_POWER_OFF

ENTER_STOP                              //进入停止模式相关处理
 ldr r0,=REFRESH  
 ldr r3,[r0]  ;r3=rREFRESH 
 mov r1, r3
 orr r1, r1, #BIT_SELFREFRESH
 str r1, [r0]                                      ;Enable SDRAM self-refresh

 mov r1,#16                                   ;wait until self-refresh is issued. may not be needed.等待自刷新生效
0 subs r1,r1,#1
 bne %B0                                     //表示不相等则往回跳转到标号为0的位置,在此为上一句。

 ldr r0,=CLKCON                         ;enter STOP mode.
 str r2,[r0]   

 mov r1,#32
0 subs r1,r1,#1                           ;1) wait until the STOP mode is in effect.
 bne %B0                                   ;2) Or wait here until the CPU&Peripherals will be turned-off
                                                  ;   Entering POWER_OFF mode, only the reset by wake-up is available.

                                                   //进入掉电 模式后,仅唤醒中断有效

 ldr r0,=REFRESH                       ;exit from SDRAM self refresh mode.
 str r3,[r0]
 
 MOV_PC_LR                            //开始处定义的返回跳转宏

ENTER_POWER_OFF 
 ;NOTE.注意在rGSTATUS3寄存器中应该保存掉电模式唤醒的返回地址,rGSTATUS3,4可在掉电下保存信息
 ;1) rGSTATUS3 should have the return address after wake-up from POWER_OFF mode.
 
 ldr r0,=REFRESH  
 ldr r1,[r0]  ;r1=rREFRESH 
 orr r1, r1, #BIT_SELFREFRESH
 str r1, [r0]  ;Enable SDRAM self-refresh

 mov r1,#16     ;Wait until self-refresh is issued,which may not be needed.
0 subs r1,r1,#1
 bne %B0

 ldr  r1,=MISCCR
 ldr r0,[r1]
 orr r0,r0,#(7<<17)  ;Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up 
 str r0,[r1]

 ldr r0,=CLKCON
 str r2,[r0]   

 b .   ;CPU will die here.


 ;=================================================================================

从掉电模式唤醒的过程

1、               某个唤醒源生效将产生一个内部复位信号。复位时间由一个内部16位计数器决定,此计数器的时钟是tRST=(65535/XTAL_frequency)。

2、               查询GSTATUS[2]位看从掉电模式唤醒是否产生了一个POWER-UP。

3、               通过将MISCCR[19:17]设置为000b,释放SDRAM信号保护。

4、               配置SDRAM控制器。

5、               等待SDRAM自我刷新完毕。大部分SDRAM需要refresh cycle of all SDRAM row。

6、               GSTATUS3,4的信息可以被用户使用,因为GSTATUS3,4的值已经在掉电模式下被保存了。

7、               对于EINT[3:0],检查SRCPND寄存器;对于EINT[15:4],检查EINTPND寄存器;对于RTC报警唤醒,检查RTC时间,因为在唤醒时SRCPND寄存器的RTC位不被置位;如果在掉电模式期间有nBATT-FLT assertion,SRCPND寄存器的相关位被置位。

;==================================================================================

WAKEUP_POWER_OFF
 ;Release SCLKn after wake-up from the POWER_OFF mode.

 ldr  r1,=MISCCR           //MISCCR寄存器用来设置一些USB等相关的时钟周期等
 ldr r0,[r1]
 bic r0,r0,#(7<<17)        //SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->H

 str r0,[r1]                     //通过将MISCCR[19:17]设置为000b,释放SDRAM信号保护。

 ;Set memory control registers配置内存控制寄存器。
 ldr r0,=SMRDATA       //在程序的后面 LTORG SMRDATA DATA中定义了

                                    //一个数据缓冲池就是用来配置相关的内存控制寄存器的
 ldr r1,=BWSCON         ;BWSCON Address
 add r2, r0, #52            ;End address of SMRDATA
0       
 ldr r3, [r0], #4    
 str r3, [r1], #4    
 cmp r2, r0  
 bne %B0

 mov r1,#256
0 subs r1,r1,#1                    ;1) wait until the SelfRefresh is released.
 bne %B0  
 
 ldr r1,=GSTATUS3            ; GSTATUS3 has the start address just after POWER_OFF wake-up
 ldr r0,[r1]
 mov pc,r0              //从掉电模式下唤醒后,将保存在GSTATUS3 返回地址传给PC

如上所说,这里采用HANDLER宏去建立Hander***和Handle***之间的联系

LTORG   ;声明文字池,因为我们用了ldr伪指令 
HandlerFIQ      HANDLER HandleFIQ 
HandlerIRQ      HANDLER HandleIRQ 
HandlerUndef    HANDLER HandleUndef 
HandlerSWI      HANDLER HandleSWI 
HandlerDabort   HANDLER HandleDabort 
HandlerPabort   HANDLER HandlePabort 

;=================================================================================== 
;呵呵,来了来了.好戏来了,这一段程序就是用来进行第二次查表的过程了. 
;如果说第一次查表是由硬件来完成的,那这一次查表就是由软件来实现的了. 
;为什么要查两次表?? 
;没有办法,ARM把所有的中断都归纳成一个IRQ中断异常和一个FIRQ中断异常 
;第一次查表主要是查出是什么异常,可我们总要知道是这个中断异常中的什么中断呀! 
;没办法了,再查一次表呗! 
;=================================================================================== 
IsrIRQ                      //第二次中断查表,因为ARM把所有的中断都归为一个IRQ异常,通过此处查表可知道具体中断
sub sp,sp,#4               ;给PC寄存器保留 
stmfd sp!,{r8-r9}          ;把r8-r9压入栈 

ldr r9,=INTOFFSET     ;把INTOFFSET的地址装入r9 
ldr r9,[r9]                     ;把INTOFFSET的值装入r9 
ldr r8,=HandleEINT0    ;这就是我们第二个中断向量表的入口的,先装入r8 
;=================================================================================== 
;哈哈,这查表方法够好了吧,r8(入口)+index*4(别望了一条指令是4 bytes的喔), 
;这不就是我们要找的那一项了吗.找到了表项,下一步做什么?肯定先装入了! 
;==================================================================================  
add r8,r8,r9,lsl #2  
ldr r8,[r8]                       ;装入中断服务程序的入口 
str r8,[sp,#8]                 ;把入口也入栈,准备用旧招 
ldmfd sp!,{r8-r9,pc}       ;施招,弹出栈,哈哈,顺便把r8弹出到PC,O了,跳转成功! 

关键字:S3C2410  启动代码 引用地址:S3C2410启动代码详解(2)

上一篇:S3C2410启动代码详解(1)
下一篇:S3C2410启动代码详解(3)

推荐阅读最新更新时间:2024-03-16 15:05

WinCE-IIC调试助手(S3C2410)
这两天在调试一款新的硬件平台,它采用的MCU依然是S3C2410。该平台新增了一个RTC模块,采用的芯片是DS1337。这是一个IIC接口的时钟芯片。在开始调试时碰到了一些问题,MCU始终无法与DS1337通讯,走了些弯路,浪费了不少时间。后来发现是IIC的SDA和SCL接反了。为了以后能方便调试2410下的IIC设备,所以决定为2410的WinCE做一个IIC调试助手,以免下次再碰到类似的问题,而多花冤枉时间。 IIC调试助手的主要功能:检测S3C2410 IIC-Bus上的设备,并给出对应的Slave Address。这样,我们就可以快速判断硬件是否有问题。除了侦测设备,同时也要支持读和写的功能。通过选择,能方便控制IIC
[单片机]
WinCE-IIC调试助手(<font color='red'>S3C2410</font>)
基于GPRS 技术的电能质量在线监测系统
  0 引言   近年来,随着电力工业的飞速发展及电力系统容量不断扩大,各种分布式发电单元逐步接入电网,各种非线性负载使用也不断增加,造成公用电网电能质量日益恶化,而各种电子设备对电压扰动的敏感性有增无减。因此,电力运行对电力调度自动化水平的要求和安全性的要求越来越高。电力调度需要各种功能更为齐全、操作更为简便的各种电力检测仪器仪表,对电能质量扰动进行检测、定位和分类,以便及时治理。随着中国电力市场的逐步建立,电能逐步实现按质论价,电力用户也要求高质量的电能来保证其设备、仪器和系统的正常运行。   传统的电能质量监测仪表多采用RS - 485、光纤、Modem 拨号等有线传输方式,在偏远地区监测点分散,环境恶劣,涉及到布线施工
[单片机]
基于GPRS 技术的电能质量在线监测系统
ARM S3C2410硬件手册上的重要部分
a.Memory Controller b.Nand Flash c.UART d.Interrupt e.Timer Memory Controller SDRAM: S3C2410 提供了外接ROM、SRAM、SDRAM、NOR Flash、NAND Flash的接口。S3C2410外接存储器的空间被分为8 BANKS,每BANK容量为128M:当访问BANKx(x从0到7)所对应的地址范围x*128M到(x+1)*128M-1 SDRAM使用BANK6,它的物理起始地址为6*128M=0x30000000。 (注:bank就是片选,一个片选就是一个bank,在U-Boot中,配制的时候要配制SDRAM和FLAS
[单片机]
嵌入式ARM启动代码的工作
(1)定义代码的初始入口点:初始入口点是指代码运行时的起始点,它在每个映像文件中是唯一的,也是每个可执行的映像文件 所必须含有的,而且必须位于映像文件的可执行域内。 (2)设置中断向量表,链接到包括复位、未定义指令,软件中断、取指中断、取数中断、IRQ和FIQ等异常或中断的处理程序。 (3)初始化存储系统。 (4)初始化ARM各个模式下的堆栈:根据应用程序使用资源的情况,设置每种或者某些ARM处理器模式下的堆栈区域。 (5)始化关键的I/O设备:用于防止在使能中断时产生不必要的开销。 (6)初始化中断时需要使用的一些变量。 (7)中断使能。 (8)根据情况切换处理器的模式和状态:ARM在运行
[单片机]
嵌入式s3c2410A UART部分中文解释
异步串口通信 概述 S3C2410的UART提供3个独立的异步串行通信端口,每个端口可以基于中断或者DMA进行操作。换句话说,UART控制器可以在CPU和UART之间产生一个中断或者DMA请求来传输数据。UART在系统时钟下运行可支持高达230.4K的波特率,如果使用外部设备提供的UEXTCLK,UART的速度还可以更高。每个UART通道各含有两个16位的接收和发送FIFO。 S3C2410的UART包括可编程的波特率,红外 接收/发送,一个或两个停止位插入,5-8位数据宽度和奇偶校验。 每个UART包括一个波特率发生器、一个发送器、一个接收器和一个控制单元,如图11-1所示。波特率发生器的输入可以是PCLK或者UEX
[单片机]
嵌入式<font color='red'>s3c2410</font>A UART部分中文解释
基于嵌入式Linux图像采集恢复和应用
1.引言       随着后PC时代的到来和嵌入式的蓬勃发展,运用嵌入式系统实现远程数据采集已成为社会需求的趋势。本文采用嵌入式系统采集图像数据实现加工零件的远程测量,代替传统的人工检测。其特点有:网络化,准确性高,节约人力和物力。   2.系统软硬件平 台       由于嵌入式设备资源有限,所以在开发嵌入式系统的软件部分需要在宿主机平台上实现,运用宿主机的资源编译目标机平台上可运行的软件。本文系统的宿主机平台:Redhat 9.0,交叉编译环境:ARM-Linux-Gcc;目标机平台:UBOOT 1.1,Linux 2.4.18 和YAFFS 根文件系统。       系统硬件平台的处理器采用 Samsung 公司的集成
[嵌入式]
几乎是每个arm程序必备的启动代码
启动代码是几乎是每个arm程序程序必备的,刚开始看的时候看别人的启动代码时感觉云里雾里,所以懒惰的想法浮现脑中:别人都写好了我还写什么,直接拿来用不就行了,对在我懂得情况下,我一定会拿来就用,但是现在我还不懂,一切就要从头开始,经过几天的努力,现在的感觉是启动代码不过如此 :) ,呵呵。 ;--------------------------------------------------------------------- ;startup.s ;系统启动代码 ;起始时间 : 2009.5.7 ----- 2009.5.11 ;--------------------------------------------
[单片机]
几乎是每个arm程序必备的<font color='red'>启动</font><font color='red'>代码</font>
S3C2440 启动代码分析
启动代码是系统上电或复位以后运行的第一段代码,它的作用是在用户程序运行之前对系统硬件及软件运行环境进行必要的初始化并在最后使程序跳转到用户程序,它直接面对ARM 处理器内核及硬件控制器进行编程,所执行的操作与具体的目标系统紧密相关。 S3C2440 支持两种方式的启动:Nor Flash 启动和Nand Flash 启动。Nor Flash 和Nand Flash 都是非易失性存储器,Nor Flash 的特点是芯片内执行,程序可以直接在其中运行,而不必将程序读取到RAM 中运行。Nor Flash 虽然具有这个优点,但是它的性价比远低于Nand Flash,因而很多系统采用Nand Flash 启动。Nand Flash 的特
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved