个人修改的用于MDK的2440init.s

发布者:紫色小猫最新更新时间:2020-06-10 来源: eefocus关键字:MDK  2440init  小端格式 手机看文章 扫描二维码
随时随地手机看文章

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

; 文件名: 2440INIT.s

; 描述: 1).ARM 指令集,

; 2).小端格式

; 3).NOR Flash总线16位,大小2MB

; 4).NAND Flash型号:K9F2G08,大小256MB

; 5).GPIO总线32位,

; 更改日期: 2012年1月31日 

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

 

 

GET 2440addr.inc ; 引入寄存器地址

_STACK_BASEADDRESS EQU 0x33FF8000 ; 堆栈基地址

_MMUTT_STARTADDRESS EQU 0x33ff8000 ; 这个没用着啊~

_ISR_STARTADDRESS EQU 0x33FFFF00 ; 定义第一级中断向量表的寻址地址

 

;============================== 系统时钟参数 ================================

 

; UCLK:UPLL固定为1:1,其中UCLK必须为48MHz(p7-24),UPLL由UPLLCON设置,后面的代码将其设置为48MHz

; 可选择的是 Fclk:Hclk:Pclk 分频比,该分频比可通过CLKDIV_VAL来选择:

; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.

 

CLKDIV_VAL EQU 5 ;选择Fclk:Hclk:Pclk=1:4:8

 

; FCLK由MPLLCON寄存器设置,可通过M_MDIV,M_PDIV,M_SDIV来调整,此处设置为400MHz,见P7-21

 

M_MDIV EQU 92 ; Fin=12.0MHz FCLK=400MHz

M_PDIV EQU 1

M_SDIV EQU 1

 

;============================= 预定义模式常量 ==============================

 

;用于设置CPSR的M[4:0],实现异常模式跳转

 

USERMODE    EQU 0x10

FIQMODE      EQU 0x11

IRQMODE      EQU 0x12

SVCMODE      EQU 0x13

ABORTMODE    EQU 0x17

UNDEFMODE    EQU 0x1b

MODEMASK    EQU 0x1f

NOINT        EQU 0xc0

 

;============================== 栈地址定义 ==================================

 

; 各异常模式的栈在SDRAM内存中的地址

    ;    地址    栈空间

UserStack EQU (_STACK_BASEADDRESS-0x3800) ; 0x33ff4800, 未知 

SVCStack EQU (_STACK_BASEADDRESS-0x2800) ; 0x33ff5800, 4KB

UndefStack EQU (_STACK_BASEADDRESS-0x2400) ; 0x33ff5c00, 1KB

AbortStack EQU (_STACK_BASEADDRESS-0x2000) ; 0x33ff6000, 1KB 

IRQStack EQU (_STACK_BASEADDRESS-0x1000) ; 0x33ff7000, 4KB 

FIQStack EQU (_STACK_BASEADDRESS-0x0) ; 0x33ff8000, 4KB

   

 

;=================================  中断例程相关宏定义  ==================================

;

; 在本启动程序的最下面在SDRAM中定义一段空间,用于存放异常处理程序的入口地址,即异常向量表,

; 除了ResetHandler外,其他异常在本启动程序入口跳转后执行的第一段程序就是下面宏定义这段程

; 序,这段程序从SDRAM中取出异常处理程序的入口地址,并跳转到此地址处开始执行.要本启动程序中,

; 复位异常几乎就是本启动程序,而IRQ异常处理程序是IsrIRQ,其他异常处理程序未定义.

 

 

MACRO

$HandlerLabel HANDLER $HandleLabel ; $HandlerLabel比$HandleLabel多了个‘r’,两者不一样!

$HandlerLabel

SUB  SP, SP, #4          ; SP=SP-4,此地址用于存放转跳地址,也即中断程序的入口地址

STMFD SP!, {R0} ; 把工作寄存器R0压入栈,sp=SP-4(sp先减)

LDR     R0, =$HandleLabel   ; 将HandleXXX的值放入r0

LDR     R0, [R0]    ; 把HandleXXX的值所指向的内容(也就是中断程序的入口地址)放入R0

STR     R0, [SP,#4]      ; 通过R0把中断服务程序(ISR)入口地址压入栈的sp=SP+4处

LDMFD   SP!, {R0,pc}      ; 出栈(sp后增),恢复r0的原值,pc值更新为中断服务程序的入口

; 地址(也就完成了到ISR的转跳)

MEND

 

;=====================================  RO RW ZI  =======================================

;

; 要了解RO,RW和ZI区是什么意思,需要首先了解以下知识:

; 1)ARM程序的组成

; 注意:此处所说的“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的bin映像(image)文件。

; 一个ARM程序包含3部分:RO区,RW区和ZI区

; RO是程序中的指令和常量,就是readonly

; RW是程序中的已初始化"全局"变量,就是read/write

; ZI是程序中的未初始化的"全局"变量,就是zero initialise(0初始化)

; 2)ARM映像文件的组成

; 所谓ARM映像文件就是指烧录到ROM中的bin文件,也成为image文件。以下用Image文件来称呼它。

; Image文件包含了RO和RW区数据,之所以Image文件不包含ZI区数据,是因为ZI区数据都是0,没必要包含,只

; 要程序运行之前将ZI区数据所在的区域一律清零即可。包含进去反而浪费存储空间。

; 3)ARM程序的执行过程

; 从以上两点可以知道,烧录到ROM中的image文件与实际运行时的ARM程序之间并不是完全一样的。因此

; 就有必要了解ARM程序是如何从ROM中的image到达实际运行状态的。实际上,RO区中的指令至少应该有这样

; 的功能:

; 1. 将RW区从ROM中搬到SDRAM内存中,因为RW区都是"全局"变量,不能存在ROM中,因为ROM只读不写

; 2. 将ZI区所在的SDRAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI区地址

;    及大小来将相应得RAM区域清零。ZI区也都是"全局"变量,同理,"全局"变量不能存在ROM/SROM中        

; 在main()执行前,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含"全局"变量的代码。

;

; RO区存放的起始地址 = RO base = |Image$ER_ROM1$RO$Base|,

; RO区存放的终止地址 = RO limit - 1 = |Image$ER_ROM1$RO$Limit| - 1

; RW区在SDRAM中存放的起始地址 = RW base = |Image$RW_RAM1$RW$Base|

; ZI区在SDRAM中存放的起始地址 = ZI base = |Image$RW_RAM1$ZI$Base|

; ZI区在SDRAM中存放的终止地址 = ZI limit - 1 = |Image$RW_RAM1$ZI$Limit| - 1

; RW区在SDRAM中存放的终止地址 = RW limit - 1 = ZI base - 1,所以没必要再给出

;

; RO base 为 Target Options 中设置的ROM1 start , RO limit = ROM1 start + 代码长度,根据ROM1 start

; 的不同设置,RO区可能存放在NOR flash中,也可能在SDRAM中.

;    RW base 为 Target Options 中设置的RAM1 start , RW limit = ROM1 start + 已初始化全局变量长度

;   ZI base = RW limit, ZI limit = ZI base +  未初始化全局变量长度. RW,ZI区一定或者说必须在SDRAM中

 

IMPORT  |Image$ER_ROM1$RO$Base| ; Base of ROM code

IMPORT |Image$ER_ROM1$RO$Limit| ; End of ROM code (=start of ROM data)

IMPORT  |Image$RW_RAM1$RW$Base| ; Base of RAM to initialise

IMPORT  |Image$RW_RAM1$ZI$Base| ; Base of area to zero initialise

IMPORT  |Image$RW_RAM1$ZI$Limit| ; limit of area to zero initialise

 

 

;**************************************  代 码 段  ***************************************

PRESERVE8 ; 不知何用

AREA    RESET,CODE,READONLY ; 代码段开始处

 

ENTRY ; 标识程序入口处,要求编译器不将下面的异常跳转列表进行优化

EXPORT __ENTRY ; 声明__ENTRY可用被其他源文件全局引用,应该是用于.c文件

__ENTRY

 

;====================================   异常跳转   ======================================

 

ResetEntry ; 程序开始的地方 相对地址

B ResetHandler ; 0x00000000

B HandlerUndef ; handler for Undefined mode, 0x00000004

B HandlerSWI ; handler for SWI interrupt, 0x00000008

B HandlerPabort ; handler for PAbort, 0x0000000C

B HandlerDabort ; handler for DAbort, 0x00000010

B . ; reserved, 0x00000014

B HandlerIRQ ; handler for IRQ interrupt, 0x00000018

B HandlerFIQ ; handler for FIQ interrupt, 0x0000001C

B EnterPWDN ; 由正常模式进入低功耗模式(power down),地址必须是

; 0x00000020,貌似是约定好的

 

;=====================================  使用宏  ===================================

;

; 采用上面定义的HANDLER宏去建立Hander***和Handle***之间的联系

 

HandlerFIQ      HANDLER HandleFIQ

HandlerIRQ      HANDLER HandleIRQ

HandlerUndef    HANDLER HandleUndef

HandlerSWI      HANDLER HandleSWI

HandlerDabort   HANDLER HandleDabort

HandlerPabort   HANDLER HandlePabort

 

;==================================   IRQ中断例程  ===============================

;

; IRQ中断可细分为多个中断源的中断,如果异常向量表是一级向量表的话,细分后的中

; 断向量表就是二级向量表,下面的程序就是二级向量表的查询,下面会用到

 

IsrIRQ

SUB SP, SP, #4        ; reserved for PC,SP=SP-4

STMFD SP!, {R8-R9} ; SP=SP-8

 

LDR R9, =INTOFFSET ; 把INTOFFSET寄存器的值装入R9,其值指向的存储地址存着中断的

; 偏移量(以字为单位,即4字节,见P14-16)

LDR R9, [R9] ; 中断的偏移量装入R9

LDR R8, =HandleEINT0 ; 将HandleEINT0装入R8,其值为二级向量表的入口地址

ADD R8, R8, R9, lsl #2 ; R8=R8+R9*4

LDR R8, [R8] ; 将所要的中断处理程序的入口地址装入R8

STR R8, [SP,#8] ; SP=SP+8,将中断处理程序的入口地址推入堆栈

LDMFD SP!, {R8-R9,pc} ; 出线,R8,R9还原其值,将中断处理程序的入口地址装入pc

LTORG ; 文字池

;-----------------------------------------------------------------------------------------

 

ResetHandler

 

;================================= 关闭看门狗, 屏蔽所有中断 ==============================

 

LDR R0, =WTCON ; 关看门狗定时器,p18-3

LDR R1, =0x0

STR R1, [R0]

 

LDR R0, =INTMSK

LDR R1, =0xFFFFFFFF ; 关所有中断,p14-12

STR R1, [R0]

 

LDR R0, =INTSUBMSK

LDR R1, =0x7FFF ; 关所有子中断,p14-18

STR R1, [R0]

 

;================================== 配置系统时钟 =====================================

 

; 通过设置LOCKTIME寄存器,减少PLL锁存时间

LDR R0, =LOCKTIME ; P7-20,

LDR R1, =0x01360136 ; p7-20,将S_LTIME和U_LTIME由初始值的OxFFFF改为0x136,只有310>300

STR R1, [R0]

 

LDR R0, =CLKDIVN ; CLKDIVN寄存器,p7-8,p7-24

LDR R1, =CLKDIV_VAL ; CLKDIV_VAL在上面定义,为UCLK:UPLL和FCLK:HCLK:PCLK的分频比选项,UPLL下面设置为48MHz

STR R1, [R0] ; CLKDIVN取0x00000101,即5

; 如果FCLK:HCLK不是1:1的关系的话,就要转成异步总线模式。反之,如果是这个比例关系的话,就转

; 成快速总线模式。

; MMU_SetAsyncBusMode 和 MMU_SetFastBusMode 都在4K代码以上,不可能拷到4K大小的steppingstone中, 

; 而nandflash启动后,会将前4KB的引导代码拷到steppingstone(4KB大小)中执行,因此不能使用这两个

; 函数如果你不想nandflash启动的话,就可以直接用上面的代码调用MMU_SetAsyncBusMode和MMU_SetFastBusMode

; 下面的代码就是实现和上面两函数一样的功能. 利用的协处理器指令实现了对总线模式的设置

; 至于为什么要用协处理器指令,代码是什么意思,我也不清楚。

 

IF CLKDIV_VAL>1 ; 意味着Fclk:Hclk不是1:1.

MRC p15, 0, R0, c1, c0, 0 ; MMU_SetAsyncBusMode,对协处理器15的c1和c0进行

; 操作0(第0类),并将结果送入r0

ORR R0, R0, #0xC0000000 ; R1_nF:OR:R1_iA

MCR p15, 0, R0, c1, c0, 0

ELSE

MRC p15, 0, R0, c1, c0, 0 ; MMU_SetFastBusMode

BIC R0, R0, #0xC0000000 ; R1_iA:OR:R1_nF

MCR p15, 0, R0, c1, c0, 0

ENDIF

; 配置UPLL

LDR R0, =UPLLCON

LDR R1, =((56<<12)+(2<<4)+2)  ; UPLL=48MHz,Fin=12MHz

STR R1, [R0]

NOP    ; 配置完UPLL后延迟7-clocks,才能配置MPLL,P7-21

NOP

NOP

NOP

NOP

NOP

NOP

; 配置 MPLL

LDR R0, =MPLLCON

LDR R1, =((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ; Fin=12MHz

STR R1, [R0]

;检查这次启动是否是睡眠模式的唤醒导致的

LDR R1, =GSTATUS2 ; p9-35

LDR R0, [R1]

TST R0, #0x2

;如果是则跳到SLEEP_WAKEUP handler

BNE WAKEUP_SLEEP

;=============================  配置SDRAM内存控制寄存器 ===================================== 

;

;此段代码把13个存储控制器的内容批量的读取到了对应的特殊功能寄存器中首先是有一个数据区SMRDATA,

;在程序的后面有定义,这个数据区给13个寄存器分配52字节的地址空间。BWSCON寄存器的地址0x48000000

;貌似是所有寄存器中最低的,故从它开始设置。

 

EXPORT StartPointAfterSleepWakeUp

StartPointAfterSleepWakeUp

 

;配置存储器控制寄存器

ADRL R0, SMRDATA ; 用adrl要比ldr要好,因为可以省去设置文字池的麻烦

LDR R1,=BWSCON ; BWSCON的地址,p5-14

ADD R2, R0, #52 ; End address of SMRDATA

 

0

LDR R3, [R0], #4

STR R3, [R1], #4

CMP R2, R0

BNE %B0 ; 向后(BACK)搜索标号为0的行,以此实现循环,具体可看局部标号的知识

; 延时等待SDRAM稳定运行,好像设置SDRAM寄存器后都要延时,只是没说要延时多久

MOV R0, #256

1

SUBS R0, R0, #1 ; 向后(BACK)搜索标号为1的行,以此实现循环,具体可看局部标号的知识

BNE %B1

 

;====================================  初始化栈 =====================================

;

; 下面这段用初始于初始化堆栈,所以不能用stmfd,ldmfd之类用到的堆栈指令,UndefStack,

; AbortStack,IRQStack,FIQStack,SVCstack上面定义过。有一点要搞清楚,每一种模式都有专门

; 的SP寄存器(r13,r13_fiq,r13_svc……),下面代码貌似在设置同一个SP寄存器,其实是设置不同的

[1] [2] [3]
关键字:MDK  2440init  小端格式 引用地址:个人修改的用于MDK的2440init.s

上一篇:mini2440---keil for ARM下的调试与下载环境的搭建
下一篇:S3C2440在MDK开发环境下的相关配置

推荐阅读最新更新时间:2024-11-06 00:44

基于S3C2410的光伏并网发电模拟装置
    太阳能作为一种巨大的可再生能源,可以很好地供人类开发和利用,因此太阳能光伏利用的技术在这种形式下进入了快速发展的阶段。太阳能光伏发电时太阳能的转换和利用方式的一种,即通过光伏电池将太阳辐射的能量直接转化成电能,同时与储能装置、直流一交流转换装置以及测量装置相配套构成光伏发电装置。近年来,在国内外在此项技术上的发展非常迅速并取得了可观的社会效益。本系统采用ARM嵌入式系统的S3C2410控制芯片,结合SPWM技术,设计并制作了一个光伏并网发电模拟装置。通过硬件和软件之间的配合,实现了逆变电压输出,最大功率、同频同相的跟踪,最终实现光伏并网发电。     1 系统总体设计     模拟光伏电池US经过DC/AC逆变器。其中SPW
[电源管理]
基于<font color='red'>S</font>3C2410的光伏并网发电模拟装置
STM8S的HALT模式与AWU唤醒
/* ********************************************************************************************************************************** * Name : STM8S的HALT模式与AWU唤醒 * Author : MingMing * Release : 2014/1/2 * Update : 2014/1/2 * E-mail : clint.wang@foxmail.com *************************************************************
[单片机]
《Linux驱动:s3c2410/s3c2440 ts驱动分析》
前言 前面结合“平台总线-设备-驱动”模型分析了ts(触摸)驱动的加载过程,现在进入驱动程序分析下其具体的实现。涉及到输入子系统、s3c2440的ADC转换和触摸控制器。 涉及的寄存器 image.png 调用probe函数 根据上一篇的分析,驱动层通过platform_driver_register注册后,会调用到该驱动层的probe函数。 s3c2410ts_probe函数分析 1. 硬件寄存器设置 获取设备参数 struct s3c2410_ts_mach_info *info; info = ( struct s3c2410_ts_mach_info *)pdev- dev.platform_data;
[单片机]
N76E003替换STM8S003F3
有款国产mcu ne76e003据说可以pin to pin完美替换。 主要信息和价格 N76E003AT20和STM8S003F3P6技术指标对比 STM8S003F3P6:一共20个脚,最多支持16个GPIO,支持16个外部中断;2个16位定时器 ,最多可以输出3路PWM信号;5个ADC通道,支持SPI/I2C/UART;8KBYTE FLASH,1K RAM,128 BYTE EEPROM;还有内置16M 高速振荡器,WDG等等。 单从器件的性能上来看:新唐的N76E003AT20相比之下更具备经典的优势: • 1T/8051 :1T超值单片机,8051我们更熟悉的经典内核; • 18KB Flash ROM:优
[单片机]
N76E003替换STM8<font color='red'>S</font>003F3
S注入法”与电压互感器的特殊接线方式
基于“S注入法”的选线定位保护新原理的TY系列选线定位保护已大量运行于国内电力系统。“S注入法”需通过电压互感器向故障系统注入检测信号,而为了消谐等目的,电压互感器有多种特殊的接线方式。本文对这些特殊的接线方式进行了分析,论证说明了这些特殊接线方式既能够满足消谐的需要,又可以适合于“S注入法”选线定位。 关键词:小电流接地系统;S注入法;电压互感器;接线方式 A S's Signal Injection Method and Connection Mode of Voltage Transformer WAN Hui, HU Ke, SANG Zai-zhong School of Electrical Engineerin
[电源管理]
“<font color='red'>S</font>注入法”与电压互感器的特殊接线方式
AT89S51单片机对十字路口交通信号灯的控制设计
一、技术要求 某十字路口,如下图所示,设计一个交通灯信号控制器,指挥交通车的通行。要求如下: 1)东西通道和南北通道交替通行,东西通道每次放行时间大于南北通道每次放行时间。 2)绿灯亮表示可以通行,红灯亮表示禁止通行。 3)每次绿灯变红灯时,绿灯先闪转变黄灯(此时另一干道上的红灯不变)。 4)要有数字显示,作为时间提示,以便人们更直观地把握时间。具体要求东西通道、南北通道通行时间及黄灯亮的时间均以秒为单位作减计数。 二、硬件电路说明 2.1电路设计原理图 本设计是以89S51为主控芯片 ,利用P1口控制74LS240(八反相缓冲器,线驱动器)驱动发光二极管模拟交通灯。倒计时显示部分采用串口实现。串口工作在方式0时通过外接
[单片机]
AT89<font color='red'>S</font>51单片机对十字路口交通信号灯的控制设计
LCD基础及S3C2410 LCD控制器
一、超薄平面显示器时代来临 电视机所采用的 CRT(阴极射线管)有着体积大、重量重、尺寸受限等缺点。随着电子科技的发展,对移动显示的要求越来越多,CRT 的先天限制,让其小型化、行动化的理想受到阻碍。这使得开发新一代的显示器技术变得更有其必要! 新一代的显示器讲求几个重点:平面直角,画面显示不变形、轻薄短小耗能少,携带方便且同时要与现有的影像信号技术兼容。目前谈论到超薄型显示器技术,最普及当是 TFT LCD 的应用了,举凡数字相机、笔记型计算机、PDA 等,需要显示复杂信息的电子产品通通少不了它。TFT LCD 技术又包含了,低温多硅晶TFT LCD、反射式TFT LCD 等,多项不同的显示技术,下面我们就要来一探 LCD
[应用]
MC9S12XS128 事件处理
一、复位 1.1 上电复位(Power-On Reset ) 在 S12 的 VDD 引脚上的一个正向变化将触发上电复位,当给 S12 上电时,它以一个已知的、确定的设置启动,具体启动流程如下图 首先 VDD 有一个正跳变初始化 然后 CPU 经历 8192 个 E-clock 延时保持晶振的稳定 CPU 内部软件复位,启动系统 如果VDD上升缓慢,到延时结束时尚未到达MCU的额定工作电压,那么退出POR开始工作就可能出现无法预料的结果,特别是片内EEPROM的安全,在混乱中如果意外被改写,将造成系统信息的丢失 1.2 外部复位(External Hardware Reset ) 为了解决上面的问题,S12配备一个
[单片机]
MC9<font color='red'>S</font>12XS128 事件处理
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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