版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第四章ARM存储系统系统其配置4.1 RealView MDK仿真环境建设4.2 Nand Flash启动配置4.3 SDRAM配置4.4 CP15协处理器4.5 MMU配置本章小结 4.1 RealView MDK仿真环境建设 本书采用的软件为RealView MDK-ARM Version 3.24(即安装软件),集成开发环境为Keil,MDK内部使用的编译连接器为版本。安装完成后的开发环境界面如图4-1所示,后续的交叉开发工作均基于该集成开发环境。图4-1 RealView MDK工作环境4.1.1 开发平台建设将UP-NETARM2410实验箱的JP1(位于实验箱的左上方)跳线跳至2-
2、3脚,即使2-3脚相连接,工作在ARM-ICE状态下。然后,将ULINK2连接到实验箱的J1接口(位于实验箱的左上方,20针),ULINK2仿真器的另一端与计算机的USB口相连接(支持热插拔)。翻开实验箱电源开关,翻开计算机,进入图4-1所示界面。由于ULINK2仿真器基于USB口,可以使用不带并口的笔记本电脑作为研发计算机,十分方便。当需要测试数字信号或输出信号的时序和波形时,读者还要具备示波器、逻辑分析仪等;需要接外部设备时,读者甚至需要做一些专用接口板卡,特别是针对技创SBC2440实验板。但是本书的学习,不需要这些贵重的仪表。本书主要讲解UP-NETARM2410实验箱自身硬件能够实现
3、的功能,第七章中还要讲述串口通信程序设计,读者需要用到一根串口线。4.1.2 第一个MDK工程在图4-1中点击菜单“Project | New mVision Project,在弹出的“Create New Project对话框中选择保存工程文件的目录,在文件名框中输入ex4_1,如图4-2所示,点击对话框右下角的“保存按钮(工程文件完整目录为E:ARM9BOOKex4_1ex4_1.uv2),之后如图4-3所示。图4-2 创立新工程对话框图4-3 选择ARM芯片对话框在图4-3中选择S3C2410A,点击“OK按钮。这里选择S3C2410A是由于UP-NETARM2410实验箱上使用了S3C
4、2410A。如果读者的ARM实验箱上不是该芯片,那么要选择相应的芯片;如果没有找到相应的芯片(这是有可能的),说明MDK芯片数据库中还没有包括该芯片,这时读者可任选一个,但是需要自己编写初始化文件。这种情况下,使用MDK和使用RVDS的编程工作量差不多,MDK的优点在于对其芯片数据库中的ARM芯片可图形化地配置芯片存储器和外设,这一点对初学者尤其是那些只懂C语言的读者十分方便。 需要指出的是,在基于ARM芯片级程序设计中需要做这些初始化工作;如果读者直接使用了商业化的操作系统,例如Windows CE等,那么无需理会这些初始化工作,操作系统供给商为用户考虑了初始化工作。 点击图4-3的“OK按
5、钮后,弹出如图4-4所示的对话框,对话框标题中有乱码,这是因为使用特殊字符“的缘故。图4-4询问“将Samsung S3C2410A启动代码文件拷贝到工程文件夹中并将该文件添加到工程中吗?,答复“是(Y),进入图4-5所示窗口。图4-4 添加初始化代码对话框图4-5 添加了初始化文件的ex4_1工程窗口双击图4-5左边的工程工作区(Project Workspace)中的,如图4-6所示。文件具有两种编辑和显示方式:即Text Editor文本编辑和显示方式以及Configuration Wizard图形配置智能向导方式。 在图4-6中显示了文本形式的文件的开始几行,这几行均为注释,这局部注释
6、的含义为“该文件(指S3C2410A.s)是mVision/ARM开发工具的一局部,所有版权归Keil公司。该软件(指MDK)仅供具有Keil授权的合法有效的最终用户使用。 由此可见Keil公司对该文件的重视程度。图4-6中也解释了Startup Code的含义,即Executed After Reset(复位后执行的代码)。这段代码的含义和使用方法将在本章和第五章中逐步介绍(笔者也将编写一个启动代码)。同时,笔者强调,所有MDK软件及启动代码的版权归Keil公司,笔者使用了评估版本,并且,遵守了Keil公司相关的协议,仅用于教学评估。 图文件 聪明的读者可能会问及能不能自己写启动代码,答案是
7、肯定的。比照一下MDK软件的启动代码及我们自己写的启动代码,一定会从中学到不少东西。尽管如此,笔者建议高级的ARM程序员自己编写启动代码。 在图4-6中点击菜单“File | New,并输入如下的代码:1 #define Seg7_1_addr (*(volatile unsigned char*)0 x08000110)2 #define Seg7_2_addr (*(volatile unsigned char*)0 x08000112)3 4 #define uchar unsigned char56 uchar seg7table16 =7 80 xC0,0 xF9,0 xA4,0 x
8、B0,0 x99,0 x92,0 x82,0 xF8,0 x80, 0 x90,0 x88,0 x83,0 xC6,0 xA1,0 x86,0 x8E9 / 0 1 2 3 4 5 6 7 8 9 A B C D E F10 ;11 12 int main()13 14 Seg7_1_addr = seg7table2;15 Seg7_2_addr = seg7table9;16 while(1)17 18 19 20 这些代码将在第七章中解释,将上述代码保存为文件,并添加到工程中(在图4-6中,右键点击Source Group 1,在弹出菜单中选择“Add Files to Group(So
9、urce Group 1),在弹出的添加文件对话框中选择刚创立的文件ex4_1.c)。目前工程文件窗口如图4-7所示。图4-7 ex4_1工程文件窗口图4-7右下角的状态栏“Simulation表示当前工程工作在软件仿真模式下(常被称作模拟模式)。如果工程中还包括其他的文件,通过鼠标右键菜单添加文件的方式将那些文件添加到工程中,这样一个工程文件即创立成功。此处,工程仅包括两个文件,即启动代码和C程序。查看一下工程所在的目录,还可以看到扩展名为.opt、.plg和.dep的三个MDK软件后台自动创立的文件,这些文件均为ASCII格式,可以用记事本或UltraEdit等软件翻开查看,它们是与编译连
10、接相关的文件。4.1.3 硬仿真环境设置在图4-7中,选择菜单“Project | Options for TargetTarget 1,或右键点击窗口左侧的“Project Workspace中的“Target 1,在弹出菜单中选择“Options for Target Target 1,进入图4-8所示窗口,选中“Debug页签。图4-8 Debug调试设置选项图4-9 ULINK仿真设置点选图4-8中的“Use,从组合框中选择“ULINK ARM Debugger,如图4-9所示。图4-10 ARM目标仿真驱动配置点击图4-9右上角的“Settings,弹出如图4-10所示窗口。 在图4
11、-10中选中“Automatic Detection,将自动检测到ARM核。点击“OK按钮回到图4-9。点击图4-9中的“OK按钮,回到图4-7,此时图4-7右下角的状态栏将由“Simulation变为“ULINK ARM Debugger,表示此时集成开发环境处于硬仿真工作状态,简称仿真状态。4.1.4 编译配置在主界面下选择菜单“Project | Options for Target Target 1,在弹出的目标选项窗口中选择“Target页签,并设置其内容,如图4-11。图4-11中,根据硬件中使用的时钟频率设置Xtal的值为,将片外SDRAM的16MB配置为只读存储区,48MB配置
12、为读写存储区,同时片上有4KB的RAM区。在图4-11中,点击Debug页签,添加初始化文件,如图4-12所示。图4-11 “Target选项页仿真设置图4-12 添加初始化文件其中,的内容如下:/*/* S3C2410SDRAM.INI: External RAM (SDRAM) Initialization File*/*/ / /*/* This file is part of the uVision/ARM development tools. */* Copyright (c) 2005-2006 Keil Software. All rights reserved. */* Thi
13、s software may only be used under the terms of a valid, current, */* end user licence from KEIL for a compatible version of KEIL software */* development tools. Nothing else gives you the right to use this software. */*/FUNC void Setup (void) _WDWORD(0 x53000000, 0 x00000000); / watch _WDWORD(0 x4A0
14、00008, 0 xFFFFFFFF); / intmsk1 _WDWORD(0 x4A00001C, 0 x000007FF); / intsub _WDWORD(0 x4C000014, 0 x00000003); / CLKDIVN _WDWORD(0 x4C000004, 0 x0005C042); / MPLLCON _WDWORD(0 x56000070, 0 x00280000); / GPHCON _WDWORD(0 x56000078, 0 x00000000); / GPHUP _WDWORD(0 x48000000, 0 x22111110); / BWSCON _WDW
15、ORD(0 x48000004, 0 x00000700); / BANKCON0 _WDWORD(0 x48000008, 0 x00000700); / BANKCON1 _WDWORD(0 x4800000C, 0 x00000700); / BANKCON2 _WDWORD(0 x48000010, 0 x00000700); / BANKCON3 _WDWORD(0 x48000014, 0 x00000700); / BANKCON4 _WDWORD(0 x48000018, 0 x00000700); / BANKCON5 _WDWORD(0 x4800001C, 0 x0001
16、8009); / BANKCON6 _WDWORD(0 x48000020, 0 x00018009); / BANKCON7 _WDWORD(0 x48000024, 0 x00AC0459); / REFRESH _WDWORD(0 x48000028, 0 x000000B1); / BANKSIZE _WDWORD(0 x4800002C, 0 x00000020); / MRSRB6 _WDWORD(0 x48000030, 0 x00000020); / MRSRB7 _WDWORD(0 x56000014, 0 x00000001); / GPBDAT _WDWORD(0 x56
17、000020, 0 xAAAA55AA); / GPCCON _WDWORD(0 x56000028, 0 x0000FFFF); / GPCUP_WDWORD(0 x56000024, 0 x00000000); / GPCDATSetup(); / Setup for InitLOAD ex4_1.axf INCREMENTAL/ DownloadPC = 0 x30000000;/ Program Entry Pointg, main / Run to main function上述代码为调试脚本,使用过AXD Debugger软件调试ARM程序的读者对此一定不陌生。调试脚本由命令和函数
18、组成,例如_WDWORD(address, ulong val)表示向address地址写入一个32位的(配置)字。这段代码的主要功能为配置外部SDRAM。4.1.5 在线仿真 在主界面下点击菜单“Project | Rebuild all target files或点击工具栏上的快捷编译按钮,编译ex4_1工程,如图4-13所示。图4-13 编译工程文件点击图4-13中菜单“Debug | Start/Stop Debug Session Ctrl+F5或点击工具栏上的快捷调试图标,如图4-14所示。图4-14中可以查看存放器的值、存储空间和反汇编及程序执行位置等信息,按F11键可单步执行程
19、序,执行到死循环后,UP-NETARM2410实验箱上的两个七段数码管会显示“29字样。程序中定义的字节型数组seg7table包含16个元素,为RW型数据,根据图4-11的存储区配置,该数组应位于地址0 x31000000处,如图4-14右侧的Memory区所示。图4-14 调试窗口 4.2 Nand Flash启动配置 本节介绍UP-NETARM2410上电后如何从Nand Flash启动以及如何借助ULNK2向Nand Flash写入启动程序。对Nand Flash访问的程序设计可参考MDK软件自带的写Flash算法,如下文的图4-18。 在工程文件主界面上,点击菜单“Project |
20、 Options for Target Target 1,选择“Target页签,设置该页如图4-15所示。图4-15 Target页签设置情况图4-16 Utilities页签设置情况点击图4-15上的Debug页签,设置如图4-9所示,即去掉配置初始化文件。然后点击图4-15上的Utilities页签,设置如图4-16所示。图4-17 Flash下载配置对话框点击图4-16上的“Settings,弹出如图4-17所示的“Flash Download Setup对话框,配置内容如图4-17所示。图4-18 选择Flash编程算法图4-17中,点击“Add按钮,在弹出的对话框中选择K9F120
21、8,如图4-18所示。图4-18中的“K9F1208Flash编程算法(Programming Algorithm),是将C:KeilARMFlash S3C2410_NAND_SP中的struct FlashDevice const FlashDevice结构体常量修改如下:struct FlashDevice const FlashDevice = FLASH_DRV_VERS, / Driver Version, do not modify! “K9F1208, /“S3C2410 NAND Flash SP, / Device Name EXT8BIT, / Device Type 0
22、 x00000000, / Device Start Address 512, / Programming Page Size 0, / Reserved, must be 0 0 xFF, / Initial Content of Erased Memory 200, /Program Page Timeout 200 mSec 3000, / Erase Sector Timeout 3000 mSec/ Specify Size and Address of Sectors 0 x4000, 0 x000000, / Sector Size 16KB SECTOR_END;即把设备名(D
23、evice Name)修改为“K9F1208,把存储容量(Device Size in Bytes)改为“0 x04000000。同时,把中的函数InitFlashController_HW的寻址时钟周期“*adr_cycles = 3;修改为“*adr_cycles = 4;。然后重新编译工程文件。 点击图4-18中的“Add按钮,得到图4-19。图4-19 配置好的Flash下载设置对话框点击图4-19中的“OK按钮回到如图4-16所示窗口,点击图上的“OK按钮回到主工作窗口。必须重新编译一下工程ex4_1,然后点击主工作窗口的菜单“Flash | Download,将当前工程生成的下载到
24、UP-NETARM2410实验箱的Nand型Flash芯片K9F1208中,如图4-20所示。这一操作将把K9F1208芯片出厂时的程序和数据全部或局部删除掉。图4-20 Flash编程完成如图4-20,在Flash编程完成后,UP-NETARM2410实验箱上的两个七段数码管将显示“29字样。 此时,可以关闭UP-NETARM2410实验箱电源,取下ULINK2仿真器,然后翻开实验箱电源,七段数码管将会显示“29,说明程序是从K9F1208启动的。如果读者手上有UP-NETARM2410实验箱,可以看一下焊有S3C2410A的核心板上靠近12MHz晶体的一侧有一个ROM101,注明了如果1-
25、2焊接,那么OM1:0=00b,从Nand Flash引导;而2-3焊接,OM1:0=01,从Nor Flash引导。核心板上可以清楚地看到1-2脚上焊了0 W的电阻。至此,读者对RealView MDK软件的使用及Nand Flash引导都应比较熟悉了。读者在输入这个短小的程序时,可能会和笔者一样,对MDK的编辑器十分不满意。当然,MDK是个优秀的软件,尽管如此,笔者对它的调试也有一些不满意的地方,而这一两点缺乏在RVDS上均不存在。 4.3 SDRAM配置 ARM芯片S3C2410A上电复位后,将首先完成对芯片的初始化工作,即初始化存储器和需要用到的片上外设等,然后开始执行主程序。外部SD
26、RAM配置属于初始化工作的一局部。下面的小节将介绍MDK启动代码是如何配置SDRAM的,接着在小节给出笔者编写出的相应代码。4.3.1 MDK启动代码配置SDRAM 前面的小节和附录是本节的硬件根底,这里配置SDRAM相关的存放器均需参考这些内容。 承图4-20,当前的工作主窗口如图4-21所示。图中的窗口是本节讨论的重点,该窗口的下面有两个页签,即Text Editor和Configuration Wizard,表示启动代码的配置和显示方式。图4-21 工作主窗口由附录知,0 x48000000至0 x48000030为存储器配置存放器,共13个。通过图4-22中的Memory Contro
27、ller可以图形化地配置这13个存放器的值,其中的Bank 0Bank 7分别表示8个区块的配置情况,Refresh表示SDRAM的刷新情况。图4-22 启动代码图形配置窗口由前面小节可知,此外,仅需要配置Bank 6即可,因为只有区块6映射了64MB的物理SDRAM芯片,其他区块没有映射到实际的物理存储空间上;虽然区块0配置了64MB的启动Nand型Flash,但并不需要存储器映射存放器配置它。 区块6的配置如图4-23所示(区块7的配置与区块6完全相同)。图4-22中Refresh的配置如图4-24所示。区块0的配置保持默认值,区块1的配置如图4-25所示(区块25的配置与区块1完全相同)
28、。图4-23 区块6配置情况图4-24 SDRAM刷新配置图4-25 区块1配置情况进行上述配置后,启动代码中第470482行的值将随之自动变更为如图4-26所示的值。在此把区块6之外的所有存储区块进行了配置,这是因为这样配置后的存储器存放器值与小节中的文件中相应的存储器存放器值相同。当然,对于UP-NETARM2410实验箱,读者完全可以只配置区块6和SDRAM刷新存放器,而不用理会其他的存储区块。图4-26 存储器存放器配置结果需要说明的是,当仅配置图4-22中的Memory Controller时,只有图4-26中第470482行的值会随之变动,而中的其他代码将保持不变。当配置图4-22
29、中其他外设时,中将有相应的存放器值随之变动。这种图形化配置ARM芯片的方法十分方便。一般地,初始化代码是用汇编语言写的,MDK这一做法可以让不懂汇编语言的人也可以进行系统初始化设计。这种图形化初始化芯片存放器的方法,很早被用于CCS软件的DSP/BIOS中。启动代码有1000多行,当然大局部为注释,作者将在以后的章节中逐步剖析这个程序,本小节只就存储器配置,特别是SDRAM配置进行讲解。下面,把中与存储器存放器相关的初始化代码提取出来逐一解释。这些相关的代码如表4-1所示(行号是在不编辑的情况下的行号,如果读者编辑了,行号可能与书上列出的行号不统一)。表4-1 中存储器配置相关的代码序号行号注
30、 释 或 语 句10183; Memory Controller definitions20184MC_BASE EQU 0 x48000000 ; Memory Controller Base Address30186;/ Memory Controller40187MC_SETUP EQU 1501890469注释,为附录2.1存储器配置寄存器的解释60470BANKCON0_Val EQU 0 x0000070070471BANKCON1_Val EQU 0 x0000070080472BANKCON2_Val EQU 0 x0000070090473BANKCON3_Val EQU 0
31、 x00000700100474BANKCON4_Val EQU 0 x00000700110475BANKCON5_Val EQU 0 x00000700120476BANKCON6_Val EQU 0 x00018009130477BANKCON7_Val EQU 0 x00018009140478BWSCON_Val EQU 0 x22111110150479REFRESH_Val EQU 0 x00AC0459160480BANKSIZE_Val EQU 0 x000000B1170481MRSRB6_Val EQU 0 x00000020180482MRSRB7_Val EQU 0
32、x00000020190484;/ End of MC200890; Memory Controller Configuration210891IF MC_SETUP 0220892MC_CFG230893DCD BWSCON_Val240894DCD BANKCON0_Val250895DCD BANKCON1_Val260896DCD BANKCON2_Val270897DCD BANKCON3_Val280898DCD BANKCON4_Val序号行号注 释 或 语 句290899DCD BANKCON5_Val300900DCD BANKCON6_Val310901DCD BANKCO
33、N7_Val320902DCD REFRESH_Val330903DCD BANKSIZE_Val340904DCD MRSRB6_Val350905DCD MRSRB7_Val360906ENDIF370970IF MC_SETUP 0380971ADR R14, MC_CFG390972LDMIA R14, R0-R12400973LDR R14, =MC_BASE410974STMIA R14, R0-R12420975ENDIF 表4-1中,第3列中以“;号开头的单元格为注释,顶格写的单元格语句在程序中也是顶格写的。顶格写的一般为标号,而前面有空格的单元格语句在程序中也是前面有空格的。
34、EQU伪指令表示相等赋值,DCD伪指令表示分配一个32位的字空间,并使用其后的值初始化该空间,IF和ENDIF伪指令与C语言相似,当IF后面的表达式为真时执行IF和ENDIF间的语句块。符号“表示不等于。 表4-1解释如下:序号2:定义标号MC_BASE,其值为0 x48000000,表示存储器映射存放器地址的基地址。由附录一附表1-1可知,在MC_BASE基地址上偏移0得到存放器BWSCON的地址,偏移4得到存放器BANKCON0的地址,偏移8得到存放器BANKCON1的地址,依次类推,偏移0 x30得到存放器MRSRB7的地址。序号4:图4-22中的Memory Controller被勾选
35、后,MC_SETUP为1,此时后面的IF语句块均将被执行(严格意义上讲是被预编译);如果没有勾选,那么MC_SETUP为0,此时后面的IF语句块均不被执行。 序号618:前文提到的图形化配置Memory Controller的值均被反映在此处。这些标号的值即为需要写到相应存放器中的值,例如BANKCON0_Val表示要写到存放器BANKCON0中的值。这个值即为配置字,其含义可参考附录二的附。序号3和序号19均为注释,这两个注释是一对,序号3表示存储器控制器配置开始,序号19表示存储器控制器配置结束。序号2136:如果MC_SETUP不等于0,那么为标号MC_CFG分配13个连续的字空间,依次
36、初始化为BWSCON_Val、BANKCON0_Val等,排列顺序与附表1-1中存放器地址的排列顺序相同。 序号3742:当UP-NETARM2410实验箱上电复位后,将会跳转到Reset_Handler标号处执行,在初始化看门狗和时钟后,将执行本段代码(参见第0945行)。由于MC_SETUP为1,故IF语句块中的四条语句均被执行(参见节和节理解这四条语句)。语句“ADR R14, MC_CFG将MC_CFG标号的值赋给R14,此时,R14即为13个存储器存放器配置字空间的首地址,参见序号22;语句“LDMIA R14, R0-R12将序号2335的值装入R0R12中;伪指令语句“LDR R
37、14, =MC_BASE执行后,R14的值为存储器存放器的基地址0 x48000000。语句“STMIA R14, R0-R12执行后,将把R0R12中的值写入到存储器存放器中,完成存储器控制器的初始化工作。 至此,应该能感受到MDK软件在初始化存储器控制器(甚至外设)方面的高明之处了。下一小节我们将把这些代码从启动代码文件中别离出来,形成自定义的SDRAM配置代码。4.3.2 自定义SDRAM配置代码 新建一个工程ex4_2,位于,将工程ex4_1的文件和拷贝到目录E:ARM9BOOKex4_2下,并把改名为,设置工程选项如图4-9、图4-10、图4-15和图4-16所示。工作主窗口如图4-
38、27所示。此时可以编译连接运行工程ex4_2,执行结果和工程ex4_1相同。设置工程选项图4-28中的“Create HEX File,编译连接后,将在当前工程目录下生成文件。图4-27 工作主窗口图4-28 工程选项“Output页签如图4-29所示,将Memory Controller的勾选取消。此时中的“MC_SETUP EQU 0,即MC_SETUP为0,启动代码文件将不对存储器控制器进行初始化。图4-29 启动代码图形化配置向导编写一个新汇编文件,并把该文件添加到工程ex4_2中,的内容罗列如下,工程ex4_2的工作界面如图4-30所示。图4-30 工程ex4_2工作主界面文件的内容
39、如下:1 AREA INITMEM, CODE, READONLY2 EXPORT InitMemCon3 Mem_Addr_Base EQU 0 x480000004 InitMemCon5 ADR R8, Mem_Val_Conf6 LDR R9, =Mem_Addr_Base7 LDMIA R8!, R0-R78 STMIA R9!, R0-R79 LDMIA R8, R0-R410 STMIA R9, R0-R4 11 ; MOV PC, LR ; Subroutine Return but not recommended in MDK12 BX LR13 Mem_Val_Conf;
40、The Configuration Value of Memory Controller14 DCD 0 x22111110, 0 x700, 0 x700, 0 x700, 0 x700, 0 x700, 0 x70015 ;BWSCON, BANKCON0,BANKCON1,BANKCON2,BANKCON3,BANKCON4,BANKCON516 DCD 0 x18009, 0 x18009, 0 x0AC0459, 0 xB1, 0 x20, 0 x2017 ;BANKCON6, BANKCON7, REFRESH, BANKSIZE, MRSRB6, MRSRB718 END同时,修
41、改启动代码文件,添加三行代码,如图4-31所示,后面跟着注释“Added by ZY的三行语句为添加的语句。在图4-30所示工作界面上编译连接工程ex4_2,然后点击菜单“Flash | Download,随后,点击菜单“Debug | Start/Stop Debug Session或直接按“Ctrl + F5组合键,进入调试状态,可以通过查看Memory了解的工作情况。如图4-32所示。图4-31 添加三行代码的图4-32 工程ex4_2调试情况图4-32窗口右侧Memory区可以同时查看四个区段,图中显示了从地址0 x48000000开始的存储器控制存放器区,当PC指针执行到如图4-32
42、所示情况时,Memory #2中的地址0 x48000000至0 x48000030间的值即为Mem_Val_Conf的值。现在回忆一下添加的程序及语句的含义,相信在第三章的帮助下读者能够完全读懂这个程序。图4-31中第0945行添加的“IMPORT InitMemCon表示引用不在本程序文件中定义的标号InitMemCon,这个标号在中定义了;第0976行和第0977行添加的语句“ELSE和“BL InitMemCon,结合上下文,表示当MC_SETUP为0时,将跳转到标号InitMemCon,同时把下一条要执行的语句地址赋给LR(即R14)存放器。 文件按语句的先后顺序依次解释如下:定义只
43、读代码段,段名为INITMEM;定义外部文件可引用的标号InitMemCon;标号Mem_Addr_Base赋值为0 x48000000,表示存储器控制存放器组的基地址;标号InitMemCon;R8赋值为标号Mem_Val_Conf,即存储存放器配置字的空间首地址;R9赋值为0 x48000000;以R8的值为地址,将其后的8个字地址的值装入R0R7中,R8=R8+0 x20;将R0R7的值存储到以R9的值为地址的字存储空间处,R9=R9+0 x20; 以R8的值为地址,将其后的5个字地址的值装入R0R4中;将R0R4的值存储到以R9的值为地址的字存储空间处;上述四条语句把Mem_Val_C
44、onf指向的13个存放器配置字赋给0 x480000000 x48000030处的存储器控制存放器。语句“BX LR实现子程序的跳转。比照一下工程ex4_1和工程ex4_2,可以看到MDK软件的启动代码的功能也可以自己编写。显然,MDK软件实现的启动代码具有配置直观、不用编写汇编程序等优点,自己编写的初始化代码需要使用汇编语言,针对性和专用性稍强一些。4.3.3 堆和栈ARM程序运行时,总会用到栈,尤其在中断和子程序调用情况下,所以程序中需要开辟一定大小的可读写存储空间给栈,并把栈指针SP(即R13)指向栈顶。栈是先进后出的存储空间,一般地,压栈后,栈顶向地址减少的方向变化,即栈底地址小于栈顶
45、地址。由于ARM系统有用户、管理等七种工作模式,每种工作模式都需要有各自独立的栈空间(用户模式和系统模式下的存放器相同,其栈区也是共用的),当切换到指定工作模式时,首先要把SP指针初始化。栈空间分配过小,导致栈数据压破栈底,可能会导致整个程序致命性的错误;栈空间分配过大,会严重浪费存储空间,但是只要存储空间够大,对程序运行没有任何影响。故栈空间分配上就大不就小。栈有时也被称为堆栈,但是堆本身是与栈完全不同的概念。在高级语言中,定义了引用(或指针)数据类型,指针的地址保存在栈中,而指针指向的数据集保存在堆中。因此,堆是比栈容量更大的存储空间。在ARM存储系统中,可读写的空间均可视为堆,所以,无需
46、为堆开辟空间(在使用C+编程时有特殊情况)。新建一个工程ex4_3,包括文件、和,其中,与工程ex4_2中的完全相同,中不使能看门狗复位系统功能(当然,这个功能是看门狗的主要用途之一),设置如图4-33所示,图中也展示了堆和栈的设置情况。图4-33 启动代码配置向导C语言程序的代码如下所示:1 #define Seg7_1_addr (*(volatile unsigned char*) 0 x08000110)2 #define Seg7_2_addr (*(volatile unsigned char*) 0 x08000112)3 4 #define uchar unsigned cha
47、r5 6 uchar seg7table16 =7 8 0 xC0,0 xF9,0 xA4,0 xB0,0 x99,0 x92,0 x82,0 xF8,0 x80, 0 x90,0 x88,0 x83,0 xC6,0 xA1,0 x86,0 x8E9 / 0 1 2 3 4 5 6 7 8 9 A B C D E F10 ;11 12 void Delay(int lcnt) / Delay subroutine13 14 int i,j;15 for(i=0;ilcnt;i+)16 17 for(j=0;j=16)33 iSeat=0;34 jSeat=(iSeat*2)%16;35 36
48、37 上述代码将在两个七段数码管上循环显示“00、“12、“24、“FE等16个值。需要强调指出的是,该工程与小节介绍的工程ex4_2的工程选项(Options for Target“Target 1)设置相同,以后所有工程文件都不再给出工程选项设置。工程选项有10个页签,其中的某些页签设置比较简单,本书中没有提及。由图4-33可见,六种工作模式的栈空间共占有0 + 0 x8 + 0 + 0 + 0 x80 + 0 x400 = 0 x488 = 1160d。使用记事本或UltraEdit软件翻开文件,该文件称为MAP表文件,在第179行处注明了栈的总大小为1160。下面把中初始化堆和栈的代码
49、罗列出来分析一下,如表4-2所示。注意:表4-2中的行号是针对修改后的启动代码文件。表4-2中第三列中以“;号开头的单元格语句为注释,顶格写的均为标号,“:OR:表示按位取或,另外,“:AND:和“:EOR:分别表示按位取与和取异或。按表4-2中的序号依次解释各语句如下:序号28:存放器CPSR的低5位M4:0的值表示当前工作模式,这里把相应的模式值定义为不同的标号。序号9、10:将CPSR中的中断位I和快速中断位F定义为标号,I位于第7位,当I=1时,屏蔽普通中断,即取为0 x80;F位于第6位,当F=1时,屏蔽快速中断,取为0 x40。序号1217:定义代表各工作模式下栈大小的标号。序号1
50、8:定义表示总的栈大小的标号。序号19、20:定义可读写的段,段名为STACK,按8字节对齐方式,分配空间大小为总的栈大小,这片连续空间的首地址为Stack_Mem。序号21:定义表示栈顶的标号Stack_Top,指向序号19、20分配的连续空间的末地址,相当于栈顶。序号2325:定义堆大小,然后,定义可读写的名称为HEAP的段,8字节对齐方式,开辟大小为Heap_Size的堆Heap_Mem。序号26:在系统初始化外设和存储器控制器之后,将工作在管理工作模式下,然后需要依次设置各工作模式下的栈大小,最后,切换到用户工作模式下执行程序。序号27:设置R0的值为栈顶。序号2931:借助MSR指令
51、切换到未定义工作模式,屏蔽普通中断和快速中断;SP指针指向R0(此时为总的栈顶);R0减去立即数UND_Stack_Size(表示未定义模式栈大小的标号)的值赋给R0,此时R0为新的栈顶。序号3247:道理与序号2931相同。序号4951:进入用户工作模式;SP指向R0(此时的R0为总的栈顶减去前面五种模式下栈的大小之和后的值,此处为总的栈顶减去0 x88);SL即存放器R10,SL的值为栈底。序号5361:为用户可调用的子程序,调用标号为_user_initial_stackheap,调用语句为“BL _user_initial_stackheap。调用该子程序后,R0指向堆头,R2指向堆尾
52、,R3指向栈底,R1指向栈顶,然后,执行“BX LR从该子程序返回。 根据工程ex4_3,可总结出MDK软件下ARM工程文件的框架结构,即工程文件由以.s结尾的汇编语言程序和以.c结尾的C语言程序组成。一般地,.s文件完成系统的初始化工作,.c文件实现程序的功能。MDK软件工程中C语言标号反映在汇编语言中为标号前添加双下划线,同样汇编语言中的标号去掉前面的双下划线后可用在C语言中访问(混沌语言编程的详细情况参见第六章)。4.4 CP15协处理器CP15协处理器,又称系统控制协处理器,协助控制存储器和特定的系统设备,CP15协处理器具有16个32位的存放器。这里讨论CP15协处理器是为下面“4.
53、5 MMU配置一节内容效劳的,因此,重点介绍与MMU相关的协处理器存放器。同时,需要说明的是,节的内容对于ARM芯片级程序设计来说意义不大,本书只做一简略的介绍。回忆第二章图2-20,图上的C13即为协处理器存放器13,C13之前的地址称为虚拟地址(Virtual Address, VA),虚拟地址是由ARM9TDMI核产生的;C13之后到AMBA总线之前的地址称为转译的虚拟地址(Modified Virtual Address, MVA),转译虚拟地址只有MMU和高速缓存(Cache)可见;AMBA总线出口的地址称为物理地址(Physical Address, PA),是指图2-6所示的“映
54、射地址。在节内容中,PA和映射地址被视为完全相同的概念,其他地方出现的“物理地址是指能进行数据访问(包括读和写)的有效存储地址。4.4.1 CP15协处理器存放器汇总CP15协处理器包括16个存放器,如表4-3所示,其中,FCSE PID为Fast Context Switch Extension Process Identifier,即快速上下文切换扩展进程标识符,其含义可参考小节的内容。在表4-3中,存放器0映射到两个不同的物理地址;存放器5、9和10对应于数据和指令情况均分别映射为两个不同的物理地址。与MMU操作相关的存放器有存放器1、2、3、5、6、8和10等;存放器1、7和9与高速缓
55、存操作相关。4.4.2 存放器c0存放器c0对应两个不同的物理地址,结合小节,使用MRC指令读出c0的值,当opcode2取0时读ID代码;当opcode2取1时读Cache类型。因此,读ID代码的语句为:MRC p15, 0, Rd, c0, c0, 0 ; Rd可取R0、R1等读Cache类型的语句为: MRC p15, 0, Rd, c0, c0, 1 ; Rd可取R0、R1等 新建工程ex4_4R的工作窗口如图4-34所示,包括3个文件,即、和,与工程ex4_3中的文件完全相同。图4-34 工程ex4_4的工作窗口对CP15协处理器存放器的访问需要工作在特权模式下,同时,由于MMU一般
56、工作在系统模式下,所以修改文件的第1071行如下:修改前的代码: MSR CPSR_c, #Mode_USR ; 进入用户模式修改后的代码: MSR CPSR_c, #Mode_SYS:OR:I_Bit:OR:F_Bit ; 进入系统模式然后,修改文件代码如下:1 #define Seg7_1_addr (*(volatile unsigned char*)0 x08000110)2 #define Seg7_2_addr (*(volatile unsigned char*)0 x08000112)3 4 #define uchar unsigned char5 6 uchar seg7ta
57、ble16 =7 8 0 xC0,0 xF9,0 xA4,0 xB0,0 x99,0 x92,0 x82,0 xF8, 0 x80,0 x90,0 x88,0 x83,0 xC6,0 xA1,0 x86,0 x8E9 / 0 1 2 3 4 5 6 7 8 9 A B C D E F10 ;11 12 void Delay(int lcnt) / Delay subroutine13 14 int i,j;15 for(i=0;ilcnt;i+)16 17 for(j=0;j=16)46 iSeat=0;47 jSeat=(iSeat*2)%16;48 49 50 编译连接工程ex4_4,并将
58、ex4_4下载到Flash中,然后,按“Ctrl+F5组合键,进入调试窗口,如图4-35所示。图4-35 工程ex4_4的调试窗口CP15协处理器存放器0是只读的。由图4-35的Watch #1窗口可以看到reg0为0 x41129200,reg1为0 x0D172172。对照S3C2410A芯片资料的“appendix2-programmer model第535536页,可知读出来的这两个值的正确性(说明:仿真器连接时读出来的ID值0 x0032409D为JTAG的ID,不是这里的ID代码)。ID代码的含义如表4-4所示,高速缓存类型的含义如表4-5所示。表4-4 存放器0的ID代码含义寄存
59、器位值含 义31:240 x41设计者23:200 x1规范修订19:160 x2指令集架构ARMv4T15:40 x920产品编号3:00 x0封装修订表4-5 存放器0的高速缓存类型含义寄存器位值含 义31:290 x0保留28:250 x6写回类型,支持清空、充满、锁定操作240 x1数据Cache和指令Cache独立的哈佛Cache结构23:210 x0保留20:180 x5数据Cache大小为16KB17:150 x6数据Cache线64根140保留13:120 x2数据Cache每线8个字长11:90保留8:60 x5指令Cache大小为16 KB5:30 x6指令Cache线64
60、根20保留1:00 x2指令Cache每线8个字长4.4.3 存放器c13 存放器c13如图4-36所示。图4-36 存放器c13图4-36中,第24:0位为0(SBZ,Should Be Zero),高7位为进程标识符。访问该存放器的语句为: MRC p15, 0, Rd, c13, c0, 0 ; 读c13 MCR p15, 0, Rd, c13, c0, 0 ; 写c13当前执行的进程位于032MB空间内(参见嵌入式操作系统方面的资料),有多个进程,例如128个,保存在图4-37所示右侧的0、1、2127空间块中。当由进程0切换到进程1执行时,需要把进程1拷贝到地址032MB空间(慢速切
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 学校实习合同范例
- 单位供菜合同范例
- 样品间家具合同范例
- 德州粮食购销合同范例
- 大数据服务合同范例
- 商场员工合同范例
- 娱乐会所合伙合同范例
- 兼职正式合同范例
- 店铺赠予股合同范例
- 快艇转让合同范例
- NB-T47003.1-2009钢制焊接常压容器(同JB-T4735.1-2009)
- 聚焦高质量+探索新高度+-2025届高考政治复习备考策略
- 惠州市惠城区2022-2023学年七年级上学期期末教学质量检测数学试卷
- 北京市西城区2022-2023学年七年级上学期期末英语试题【带答案】
- ISO45001-2018职业健康安全管理体系之5-4:“5 领导作用和工作人员参与-5.4 工作人员的协商和参与”解读和应用指导材料(2024A0-雷泽佳)
- 看图猜成语共876道题目动画版
- 小学二年级上册数学-数角的个数专项练习
- 曲式与作品分析智慧树知到期末考试答案章节答案2024年兰州文理学院
- 园林设施维护方案
- 特种设备使用单位日管控、周排查、月调度示范表
- 供应链成本控制与降本增效
评论
0/150
提交评论