




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、ARM9 启动代码(裸机版)所谓启动代码,就是处理器在启动的时候执行的一段代码,主要任务是初始化处理器模式, 设置堆栈,初始化变量等等。 由于以上的操作均与处理器体系结构和系统配置密切相关,所以一般由汇编来编写。在一般 32 位 ARM 应用系统中,软件大多数采用 c 语言进行编程,并且以嵌入式操作系统为开发平台, 这样就大大提高了开发效率和软件性能。 为了能够进行系统初始化, 通常采用一个汇编文件作启动代码。 它可以实现向量表定义、 堆栈初始化、系统变量初始化、 中断系统初始化、 I/O 初始化、地址重映射等操作。启动代码是芯片复位后进入 c 语言的 main 函数前执行的一段代码, 主要是
2、为运行 c 语言程序提供基本运行环境。在实际应用中,为提高系统的实时性,加快代码的执行速度,系统启动后程序往往要被搬移到 RAM 中,因为 RAM 的存取速度要比 ROM 快得多,这样大大提升系统的性能。启动程序要完成的任务包括: 硬件初始化,系统存储系统的配置,复制二级中断向量表。启动程序大概过程如下:( 1)系统硬件初始化系统上电或复位后,程序从位于地址0 x0 的 Reset Exception Vector处开始执行,因此需要在这里放置 bootloader 的第一条指令: b Reset,跳转到标号为Reset 处进行第一阶段的硬件初始化, 主要内容为:关看门狗定时器, 关中断,初始
3、化 PLL 和时钟,初始化存储器系统。 执行完以上程序后, 系统进行堆栈和存储器的初始化。 系统堆栈初始化取决于用户使用了哪些中断, 以及系统需要处理哪些错误类型。一般情况下,管理者堆栈必须设置,如果使用了 IRQ 中断,则 IRQ堆栈也必须设置。如果系统使用了外设,则需要设置相关的寄存器,以确定其刷新频率、总线宽度等信息。( 2)代码复制到 RAM 中运行因为嵌入式系统的代码通常都是固化在ROM 或 Flash 中,上电后开始运行。由于 ROM 和 Flash 的读取速度相对较慢, 这样无疑会降低代码的执行速度和系统的运行效率。因此,需要把系统的代码复制到 RAM 中运行。( 3)建立二级中
4、断向量表在 ARM 系统中,中断向量表位于 0 x0 开始的地址处,意味着无论运行什么样的上层软件, 一旦发生中断, 程序就得到 Flash 存储器的中断向量表里去, 降低系统的运行效率。因此在 RAM 中建立自己的二级中断向量表,当中断发生后,程序直接从 RAM 中取中断向量进入中断子程序。( 4) MMU 的应用MMU 是存储器管理单元的缩写,是用来管理虚拟内存系统的器件。MMU 完成的两个主要功能是:将虚地址转换成物理地址,控制存储器存取允许。 MMU 关掉时,虚地址直接输出到物理地址总线。由于跑的是裸机,没有用到操作系统,以下启动代码不包含MMU 的应用。下面是对 arm 处理器模式寄
5、存器对应的常数进行赋值,arm 处理器有一个 CPSR寄存器,它的后五位决定了处理器处于哪个模式下。可以看出常数的定义都不会超过后5 位的。 */Pre-defined constants.equUSERMODE,0 x10.equFIQMODE,0 x11.equIRQMODE,0 x12.equSVCMODE,0 x13.equABORTMODE,0 x17.equUNDEFMODE,0 x1b.equMODEMASK,0 x1f.equNOINT,0 xc0各个异常模式的堆栈The location of stacks.equ_STACK_BASEADDRESS, 0 x33ff8000
6、.equ_ISR_STARTADDRESS,0 x31ffff00.equUserStack,(_STACK_BASEADDRESS-0 x3800) 0 x33ff4800 .equSVCStack,(_STACK_BASEADDRESS-0 x2800) 0 x33ff5800 .equUndefStack,(_STACK_BASEADDRESS-0 x2400) 0 x33ff5c00 .equAbortStack,(_STACK_BASEADDRESS-0 x2000) 0 x33ff6000 .equIRQStack,(_STACK_BASEADDRESS-0 x1000) 0 x3
7、3ff7000 .equFIQStack,(_STACK_BASEADDRESS-0 x0)0 x33ff8000 .equINTMSK,0 x4a000008 Interrupt mask control.equINTSUBMSK,0 x4a00001cInterrupt sub mask.equINTOFFSET,0 x4a000014Interruot request source offset.macroHANDLERHandleLabelsubsp,sp,#4decrement sp(to store jump address)stmfdsp!,r0PUSH the work reg
8、ister to stack(lr doesnot push because it return to original address)ldrr0,=HandleLabelload the address of HandleXXX to r0ldrr0,r0loadthecontents(serviceroutinestart address) of HandleXXXstrr0,sp,#4store the contents(ISR)of HandleXXXtostackldmfdsp!,r0,pcPOP the work register and pc(jump toISR).endm.
9、externmain.text.global _start_start:* 中断向量*bReset0 x04: 未定义指令中止模式的向量地址b HandlerUndef0 x08: 管理模式的向量地址,通过 SWI 指令进入此模式 bHandlerSWI0 x0c: 指令预取终止导致的异常的向量地址HandlerPrefetchAbortd91-Bulleted_f47e5591-4327-41bd-88af-b5f0be1ace26-Bulleted_9bf50a39-707f-4853-8328-61e56b357290 0 x10: 数据访问终止导致的异常的向量地址HandlerData
10、Abortd91-Bulleted_f47e5591-4327-41bd-88af-b5f0be1ace26-Bulleted_9bf50a39-707f-4853-8328-61e56b357290 0 x14: 保留HandlerNotUsedd91-Bulleted_f47e5591-4327-41bd-88af-b5f0be1ace26-Bulleted_9bf50a39-707f-4853-8328-61e56b357290 0 x18: 中断模式的向量地址HandlerIRQd91-Bulleted_f47e5591-4327-41bd-88af-b5f0be1ace26-Bull
11、eted_9bf50a39-707f-4853-8328-61e56b357290 0 x1c: 快中断模式的向量地址HandlerFIQReset:ldr sp, =4096 设置栈指针,以下都是C 函数,调用前需要设好栈bl disable_watch_dog 关闭WATCHDOG,否则CPU 会不断重启ldrr0,=INTMSKldr r1,=0 xffffffffstrr1,r0all interrupt disableldr r0,=INTSUBMSKldr r1,=0 x7fffstrr1,r0all sub interrupt disablebl clock_initbl mem
12、setup 设置 MPLL,改变 FCLK、HCLK、PCLK 设置存储控制器以使用SDRAMbl s3c2440_nand_initldr r0, =0 x300000001.目标地址= 0 x30000000,这是SDRAM 的起始地址mov r1, #4096 2.源地址= 4096,运行地址在SDRAM 中的代码保存在 NAND Flash 4096 地址开始处mov r2, #180*1024 3. 复制长度= 16K,对于本实验,这是足够了bl CopyCode2SDRAM 调用 C 函数CopyCode2SDRAMbl clean_bss 清除 bss 段,未初始化或初值为0 的
13、全局/静态变量保存在 bss 段blInitStacksinital the stack Setup IRQ handlerldr r0,=HandleIRQldr r1,=IsrIRQ0 x1cstr r1,r0This routine is neededif there is not subs pc,lr,#4 at 0 x18,这三条语句很明显就是说明了,HandleIRQ这个中断向量的存储单元被赋上了IsrIRQ标号的地址,这样发生IRQ 中断后就会直接去到二级表,去确认具体发生哪个中断。ldr pc, =on_sdram 跳到 SDRAM 中继续执行on_sdram:msr cpsr
14、_c, #0 x5fldr sp, =0 x34000000ldr lr, =halt_loopldr pc, =main 设置 I-bit=0,开 设置栈指针, 设置返回地址 调用 main 函数IRQ 中断halt_loop:bhalt_loopHandlerFIQ:HANDLERHandleFIQHandlerIRQ:HANDLERHandleIRQHandlerUndef:HANDLERHandleUndefHandlerSWI:HANDLERHandleSWIHandlerDataAbort:HANDLERHandleDabortHandlerPrefetchAbort:HANDLE
15、RHandlePabortHandlerNotUsed:b.InitStacks:Do not use DRAM,such as stmfd,ldmfd.SVCstack is initialized beforeUnder toolkit ver 2.5, msr cpsr,r1 can be used instead of msrcpsr_cxsf,r1mrs r0,cpsrbic r0,r0,#MODEMASKorr r1,r0,#UNDEFMODE|NOINTmsr cpsr_c,r1UndefModeldr sp,=UndefStack UndefStack=0 x33FF_5C00
16、orr r1,r0,#ABORTMODE|NOINTmsr cpsr_c,r1AbortModeldr sp,=AbortStack AbortStack=0 x33FF_6000orr r1,r0,#IRQMODE|NOINTmsr cpsr_c,r1IRQModeldr sp,=IRQStack IRQStack=0 x33FF_7000orr r1,r0,#FIQMODE|NOINTmsr cpsr_c,r1FIQModeldr sp,=FIQStack FIQStack=0 x33FF_8000bic r0,r0,#MODEMASK|NOINTorr r1,r0,#SVCMODEmsr
17、 cpsr_c,r1SVCModeldr sp,=SVCStack SVCStack=0 x33FF_5800USER mode has not be initialized.mov pc,lrthe LR registerwillnot be validifthe currentmodeis not SVCmode.IsrIRQ:sublr, lr, #4stmfd sp!, r0-r12,lr 计算返回地址保存使用到的寄存器sub sp,sp,#4reserved for PC ;保留 pc 寄存器的值stmfdsp!,r8-r9把 r8 r9按入堆栈ldr lr, =int_return
18、设置调用 ISR 即 EINT_Handle 函数后的返回地址ldr r9,=INTOFFSETldr r9,r9ldr r8,=HandleEINT0把中断偏移 INTOFFSET 的地址装入取出 INTOFFSET 单元里面的值给r9向量表的入口地址赋给r8r9里面add r8,r8,r9,lsl #2求出具体中断向量的地址ldr r8,r8中断向量里面存储的中断服务程序的入口地址赋给 r8str r8,sp,#8按入堆栈ldmfdsp!,r8-r9,pc堆栈弹出,跳转到相应的中断服务程序int_return:ldmfdsp!,r0-r12,pc 中断返回 , 表示将spsr的值复制到cp
19、sr.align 4.section .data.equHandleReset,(_ISR_STARTADDRESS+0 x0).equHandleUndef,(_ISR_STARTADDRESS+0 x4).equHandleSWI,(_ISR_STARTADDRESS+0 x8).equHandlePabort, (_ISR_STARTADDRESS+0 xc).equHandleDabort, (_ISR_STARTADDRESS+0 x10).equHandleReserved,(_ISR_STARTADDRESS+0 x14).equHandleIRQ,(_ISR_STARTADDR
20、ESS+0 x18).equHandleFIQ,(_ISR_STARTADDRESS+0 x1c)Do not use the label IntVectorTable,Thevalue of IntVectorTable is different with the address you think it may be.IntVectorTable0 x33FF_FF20.equHandleEINT0, (_ISR_STARTADDRESS+0 x20).equHandleEINT1,(_ISR_STARTADDRESS+0 x24).equHandleEINT2,(_ISR_STARTAD
21、DRESS+0 x28).equHandleEINT3,(_ISR_STARTADDRESS+0 x2c).equHandleEINT4_7,(_ISR_STARTADDRESS+0 x30).equHandleEINT8_23,(_ISR_STARTADDRESS+0 x34).equHandleCAM,(_ISR_STARTADDRESS+0 x38) Added for 2440.equHandleBATFLT, (_ISR_STARTADDRESS+0 x3c).equHandleTICK,(_ISR_STARTADDRESS+0 x40).equHandleWDT,(_ISR_STA
22、RTADDRESS+0 x44).equHandleTIMER0, (_ISR_STARTADDRESS+0 x48).equHandleTIMER1, (_ISR_STARTADDRESS+0 x4c).equHandleTIMER2, (_ISR_STARTADDRESS+0 x50).equHandleTIMER3, (_ISR_STARTADDRESS+0 x54).equHandleTIMER4, (_ISR_STARTADDRESS+0 x58).equHandleUART2, (_ISR_STARTADDRESS+0 x5c)0 x33FF_FF60.equHandleLCD,(
23、_ISR_STARTADDRESS+0 x60).equHandleDMA0,(_ISR_STARTADDRESS+0 x64).equHandleDMA1,(_ISR_STARTADDRESS+0 x68).equHandleDMA2,(_ISR_STARTADDRESS+0 x6c).equHandleDMA3,(_ISR_STARTADDRESS+0 x70).equHandleMMC,(_ISR_STARTADDRESS+0 x74).equHandleSPI0,(_ISR_STARTADDRESS+0 x78).equHandleUART1, (_ISR_STARTADDRESS+0
24、 x7c).equHandleNFCON, (_ISR_STARTADDRESS+0 x80) Added for 2440.equHandleUSBD,(_ISR_STARTADDRESS+0 x84).equHandleUSBH,(_ISR_STARTADDRESS+0 x88).equHandleIIC,(_ISR_STARTADDRESS+0 x8c).equHandleUART0, (_ISR_STARTADDRESS+0 x90).equHandleSPI1,(_ISR_STARTADDRESS+0 x94).equHandleRTC,(_ISR_STARTADDRESS+0 x9
25、8).equHandleADC,(_ISR_STARTADDRESS+0 x9c)以下部分是我们 bootloader 中调用到的 c 程序部分,主要是完成:关看门狗、初始化存储器、初始化时钟、从 Nandflash 将代码拷贝到 SDRAM、初始化数据段。/*关闭 WATCHDOG,否则 CPU 会不断重启*/void disable_watch_dog(void)WTCON = 0; /关闭 WATCHDOG 很简单,往这个寄存器写0 即可#define S3C2410_MPLL_200MHZ(0 x5c12)|(0 x044)|(0 x00)#define S3C2440_MPLL_20
26、0MHZ(0 x5c12)|(0 x014)|(0 x02)/*对于 MPLLCON 寄存器, 19:12为 MDIV, 9:4为 PDIV,1:0为 SDIV有如下计算公式:S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2s)S3C2410: MPLL(FCLK) = (2 * m * Fin)/(p * 2s)其中 : m = MDIV + 8, p = PDIV + 2, s = SDIV对于本开发板, Fin = 12MHz设置 CLKDIVN,令分频比为: FCLK:HCLK:PCLK=1:2:4,FCLK=200MHz,HCLK=100MHz,PCLK=
27、50MHz*/void clock_init(void)/ LOCKTIME = 0 x00ffffff;/使用默认值即可CLKDIVN=0 x03;/FCLK:HCLK:PCLK=1:2:4,HDIVN=1,PDIVN=1/*如果HDIVN 非 0 , CPU 的总 线模式 应该 从“ fast bus mode” 变为“ asynchronous bus mode ” */_asm_(mrcp15, 0, r1, c1, c0, 0n/*读出控制寄存器*/orrr1,r1, #0 xc0000000n/*设置为 “asynchronousbus mode” */mcrp15, 0, r1,
28、 c1, c0, 0n/*写入控制寄存器*/);/*判断是 S3C2410 还是 S3C2440 */if (GSTATUS1 = 0 x32410000) | (GSTATUS1 = 0 x32410002)MPLLCON=S3C2410_MPLL_200MHZ;/*现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */elseMPLLCON=S3C2440_MPLL_200MHZ;/*现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */ 设置存储控制器以使用SDRAM#defineMEM_CTL_BASE0 x48000000/存储器控
29、制器寄存器的起始地址#defineSDRAM_BASE0 x30000000void memsetup(void)volatileunsigned long *p = (volatileunsigned long *)MEM_CTL_BASE;/*这个函数之所以这样赋值,而不是像前面的实验( 比如mmu 实验 ) 那样将配置值写在数组中, 是因为要生成” 位置无关的代码”,使得这个函数可以在被复制到SDRAM 之前就可以在 steppingstone 中运行*/*存储控制器 13 个寄存器的值 */p0 = 0 x22011110;/BWSCONp1 = 0 x00000700;/BANKCO
30、N0p2 = 0 x00000700;/BANKCON1p3 = 0 x00000700;/BANKCON2p4 = 0 x00000700;/BANKCON3p5 = 0 x00000700;/BANKCON4p6 = 0 x00000700;/BANKCON5p7 = 0 x00018005;/BANKCON6p8 = 0 x00018005;/BANKCON7/* REFRESH,*HCLK=12MHz:0 x008C07A3,*HCLK=100MHz:0 x008C04F4*/p9 = 0 x008C04F4;p10 = 0 x000000B1;/BANKSIZEp11 = 0 x00000030;/MRSRB6p12 = 0 x00000030;/MRSRB7/*void copy_steppingstone_to_sdram(void)unsigned int *pdwSrc = (unsigned int *)0;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 高考政策变化下的学科教学与升学指导调整
- 对流动人口的安全管理计划
- 七下必考名著《骆驼祥子》考点汇编及中考真题
- 2025一体式 NB 物联网水表
- 班级风采展示活动的策划计划
- 跨文化交流中的英语口语应用
- 全息档案搜索系统功能需求
- 跨世界一流的跨境服务平台分析报告
- 跨境电商平台的用户行为分析
- 高效激励机制蜜雪冰城员工动力源解析
- 老年人预防及控制养老院院内感染院内感染基本知识
- 牙周检查记录表
- GB/T 10060-2023电梯安装验收规范
- TB编程从入门到进阶
- 教师沟通能力提升培训幼儿园家长沟通技巧教学课件
- 喀喇沁旗楼子店乡上烧锅白石矿石灰岩矿2022年度矿山地质环境治理计划书
- 第三单元名著导读《骆驼祥子》课件部编版语文七年级下册
- 高老师讲语文-灯笼-部编版
- 事业单位个人德能勤绩廉工作总结(2篇)
- 《英语词汇学》课程教学大纲
- YS/T 952-2014铜钼多金属矿化学分析方法铜和钼量的测定电感耦合等离子体原子发射光谱法
评论
0/150
提交评论