hello第四课(二)f2812存储器映射及cmd详解-日志-eyes417-
- 格式:doc
- 大小:26.50 KB
- 文档页数:6
对于TMS320F2812的CMD文件的理解1.COFF格式要谈CMD文件,首先不可避免的要谈下COFF格式,COFF格式是通用目标文件格式(Common Object File Format)的缩写,它是一种流行的二进制可执行文件格式,在DSP里二进制可执行文件包括库文件(.lib)、目标文件(.obj)和最终可执行文件(.out)。
详细的COFF格式文件包括段头、可执行代码、初始化数据、可重定位信息、行号入口、符号表、字符串。
对于DSP的C语言编程我们只需要了解定义段和给段分配空间即可。
采用COFF格式更利于我们对其进行模块化编程,我们可以自由的把哪些段分配到哪些空间。
2.Section(1)其次,在编写CMD文件得时候要碰到SectionS命令,SectionS命令的英文理解就有区域的意思,我们利用SectionS来将目标文件的代码放到指定的区域中。
SectionS目标文件中最小的单位我们称之为块,一个块就是最终在存储器映像中占据连续空间的一段代码或者数据。
COFF文件格式默认有三个块:.text 存放可执行代码;.data 存放已初始化数据;.bss 为未初始化数据留下的保留空间。
(2)汇编器对块的处理和设置未初始化块的设置:.bss 变量存放空间;.usect 用户自定义的未初始化段;初始化块的设置:.text 汇编指令代码.data 常数数据(比如对变量的初始化数据).sect 用户自定义的已初始化段.asect 类似于.sect,多了绝对地址定位功能,一般不用(3)C语言对块得的设置和处理未初始化块(data).bss 存放全局和静态变量.ebss 长调用的.bss(超过了64K地址限制).stack 存放C语言的栈.sysmem 存放C语言的堆.esysmem 长调用的.sysmem(超过了64K地址限制)初始化块.text 可执行代码和常数(program).switch switch语句产生的常数表格(program/低64K数据空间).pinit Tables for global constructors (C++)(program).cinit 用来存放对全局和静态变量的初始化常数值(program).const 全局和静态的const变量初始化值和字符串常数,(data).econst 长.const(可定位到任何地方)(data)(4)C语言自定义块#pragma DATA_SECTION(函数名或者全局变量名,“用户自定义在数据空间的段名”);#pragma CODE_SECTION(函数名或者全局变量名,“用户自定义在程序空间的段名”);必须注意:不能在函数体内声明,必须在定义和使用前声明。
2812存储器映射2812具有32位的数据地址和22位的程序地址,总地址空间可以达到4M的数据空间和4M的程序空间。
32位的数据地址,就是能访问2的32次,是4G,而22位的程序地址,就是能访问2的22次,是4M。
其实,2812可寻址的数据空间最大是4G,但是实际线性地址能达到的只有4M,原因是2812的存储器分配采用的是分页机制,分页机制采用的是形如0xXXXXXXX的线性地址,所以数据空间能寻址的只有4M。
2812的存储器被划分成了下面的几个部分:1. 程序空间和数据空间。
2812所具有的RAM、ROM和FLASH都被统一编址,映射到了程序空间和数据空间,这些空间的作用就是存放指令代码和数据变量。
2. 保留区。
数据空间里面某些地址被保留了,作为CPU的仿真寄存器使用,这些地址是不向用户开放的。
3.CPU中断向量。
在程序空间里也保留了64个地址作为CPU的32个中断向量。
通过CPU 寄存器ST1中的VMAP位来将这一段地址映射到程序空间的底部或者顶部。
映射和空间的统一编址F2812内部的映射空间低地址空间高地址空间2812CMD详解CMD:command命令,顾名思义就是命令文件指定存储区域的分配.2812的CMD采用的是分页制,其中PAGE0用于存放程序空间,而PAGE1用于存放数据空间。
1.)#pragma ,CODE_SECTION和DA TA_SECTION伪指令#pragma DATA_SECTION(funcA,"dataA"); ------ 函数外声明将funcA数据块定位于用户自定义的段"dataA"中 ------ 需要在CMD中指定dataA段的物理地址2.)MEMORY和SECTIONS是命令文件中最常用的两伪指令。
MEMORY伪指令用来表示实际存在目标系统中的可以使用的存储器范围,在这里每个存储器都有自己的名字,起始地址和长度。
TMS320F2812的CMD文件的编写经验总结CMD文件里包含三部分内容:1)输入/输出定义:.obj文件:链接器要链接的目标文件;.lib文件:链接器要链接的库文件;.map文件:链接器生成的交叉索引文件;.out文件:链接器生成的可执行代码;链接器选项2)MEMORY命令:描述系统实际的硬件资源3)SECTIONS命令:描述“段”如何定位F2812的CMD文件只包含后两部分,现对它的编写做一下总结:(一)用于调试时用,取名为SRAM.CMD这里有个比较标准的F2812的CMD文件,可以供大家借鉴使用:MEMORY{PAGE 0:ZONE0 : origin = 0x002000, length = 0x002000ZONE1 : origin = 0x004000, length = 0x002000RAML0 : origin = 0x008000, length = 0x001000ZONE2 : origin = 0x080000, length = 0x080000ZONE6 : origin = 0x100000, length = 0x080000OTP : origin = 0x3D7800, length = 0x000800FLASHJ : origin = 0x3D8000, length = 0x002000FLASHI : origin = 0x3DA000, length = 0x002000FLASHH : origin = 0x3DC000, length = 0x004000FLASHG : origin = 0x3E0000, length = 0x004000FLASHF : origin = 0x3E4000, length = 0x004000FLASHE : origin = 0x3E8000, length = 0x004000FLASHD : origin = 0x3EC000, length = 0x004000FLASHC : origin = 0x3F0000, length = 0x004000FLASHA : origin = 0x3F6000, length = 0x002000BEGIN_H0 : origin = 0x3F8000, length = 0x000002BEGIN_FLASH : origin = 0x3F7FF6, length = 0x000002PRAMH0 : origin = 0x3F8002, length = 0x001FFEZONE7 : origin = 0x3FC000, length = 0x003FC0ROM : origin = 0x3FF000, length = 0x000FC0 // boot ROM available if MP/MCn=0 RESET : origin = 0x3FFFC0, length = 0x000002VECTORS : origin = 0x3FFFC2, length = 0x00003EPAGE 1 : // Data MemoryRAMM0 : origin = 0x000000, length = 0x000400RAMM1 : origin = 0x000400, length = 0x000400DEV_EMU : origin = 0x000880, length = 0x000180FLASH_REGS : origin = 0x000A80, length = 0x000060CSM : origin = 0x000AE0, length = 0x000010XINTF : origin = 0x000B20, length = 0x000020CPU_TIMER0 : origin = 0x000C00, length = 0x000008PIE_CTRL : origin = 0x000CE0, length = 0x000020PIE_VECT : origin = 0x000D00, length = 0x000100ECAN_A : origin = 0x006000, length = 0x000100ECAN_AMBOX : origin = 0x006100, length = 0x000100SYSTEM : origin = 0x007010, length = 0x000020SPI_A : origin = 0x007040, length = 0x000010SCI_A : origin = 0x007050, length = 0x000010XINTRUPT : origin = 0x007070, length = 0x000010GPIOMUX : origin = 0x0070C0, length = 0x000020GPIODAT : origin = 0x0070E0, length = 0x000020ADC : origin = 0x007100, length = 0x000020EV_A : origin = 0x007400, length = 0x000040EV_B : origin = 0x007500, length = 0x000040SCI_B : origin = 0x007750, length = 0x000010MCBSP_A : origin = 0x007800, length = 0x000040RAML1 : origin = 0x009000, length = 0x001000FLASHB : origin = 0x3F4000, length = 0x002000CSM_PWL : origin = 0x3F7FF8, length = 0x000008DRAMH0 : origin = 0x3f9000, length = 0x001000}SECTIONS{// Compiler Required Sections.text : > PRAMH0, PAGE = 0.cinit : > PRAMH0, PAGE = 0.stack : > RAMM1, PAGE = 1.bss : > RAMM0, PAGE = 1.ebss : > RAMM0, PAGE = 1.const : > RAMM0, PAGE = 1.econst : > RAMM0, PAGE = 1.sysmem : > RAMM1, PAGE = 1.reset : > RESET, PAGE = 0, TYPE = DSECT // we are not using the .reset // section//Peripheral Frame 0 Register StructuresDevEmuRegsFile : > DEV_EMU, PAGE = 1FlashRegsFile : > FLASH_REGS, PAGE = 1CsmRegsFile : > CSM, PAGE = 1XintfRegsFile : > XINTF, PAGE = 1CpuTimer0RegsFile : > CPU_TIMER0, PAGE = 1PieCtrlRegsFile : > PIE_CTRL, PAGE = 1PieVectTable : > PIE_VECT, PAGE = 1//Peripheral Frame 1 Register StructuresSysCtrlRegsFile : > SYSTEM, PAGE = 1SpiaRegsFile : > SPI_A, PAGE = 1SciaRegsFile : > SCI_A, PAGE = 1XIntruptRegsFile : > XINTRUPT, PAGE = 1GpioMuxRegsFile : > GPIOMUX, PAGE = 1GpioDataRegsFile : > GPIODAT PAGE = 1AdcRegsFile : > ADC, PAGE = 1EvaRegsFile : > EV_A, PAGE = 1EvbRegsFile : > EV_B, PAGE = 1ScibRegsFile : > SCI_B, PAGE = 1McbspaRegsFile : > MCBSP_A, PAGE = 1//Peripheral Frame 2 Register StructuresECanaRegsFile : > ECAN_A, PAGE = 1ECanaMboxesFile : > ECAN_AMBOX PAGE = 1//Code Security Password LocationsCsmPwlFile : > CSM_PWL, PAGE = 1}(二)用于烧写到FLASH中时用,取名为FLASH.CMDFLASH.CMD与SRAM.CMD基本一样,只是有两处改动:一是MEMORY中将你的程序代码部分映射到FLASH空间里;二是在SECTIONS中添加一个用户定义的起始段,起始段的代码如下://User Defined Sections , Used by file DSP28_CodeStartBranch.asmcodestart : > BEGIN, PAGE = 0其中DSP28_CodeStartBranch.asm中的关键代码为:.ref _c_int00.sect “codestart”Code_start:LB _c_int00.end(三)SECTIONS中段的含义与用户自定义段的方法1、各个段的含义以下是TI公司的技术文档中对一些段的说明,现截个图给大家参考:除此外还有一些段的含义如下(这仅是我见过的,有漏下的还请提示,大家一起学习):.reset 复位中断向量表.vectors 中断向量表.data 已初始化数据,常数数据(比如对变量的初始化数据).pvecs 外围模块中断向量表.ref 引用外部定义的变量或函数名.global 引用全局变量或函数.space 定义要保留的空间.def 定义变量,与#define功能相同.end 段的结束标识.sect 用户自定义的已初始化段.asect 比.sect多了绝对地址定位功能,一般不用.usect 用户自定义的未初始化段已初始化的段:.text, .cinit, .const, .econst, .pinit, .switch.text:所有可以执行的代码和常量.cinit:全局变量和静态变量的C初始化记录.const:包含字符串常量和初始化的全局变量和静态变量(由const)的初始化和说明.econst:包含字符串常量和初始化的全局变量和静态变量(由far const)的初始化和说明.pinit:全局构造器(C++)程序列表.switch:包含转换语气声明的列表非初始化的段:.bss, .ebss, .stack, .sysmem, .esysmem(更好的理解就是,这些段就是存储空间而已)..bss:为全局变量和局部变量保留的空间,在程序上电时,cinit空间中的数据复制出来并存储在.bss空间中.ebss:为使用大寄存器模式时的全局变量和静态变量预留的空间,在程序上电时,cinit空间中的数据复制出来并存储在.ebss中.stack:为系统堆栈保留的空间,主要用于和函数传递变量或为局部变量分配空间.sysmem:为动态存储分配保留的空间。
XINTF信号XA[0]~XA[18] --- 19位地址总线XD[0]~XD[15] --- 16位数据总线XMP/MC` --- 1 -- 微处理器模式 --- XINCNF7有效0 -- 微计算机模式 --- XINCNF7无效XHOLD` --- 外部DMA保持请求信号。
XHOLD为低电平时请求XINTF释放外部总线,并把所有的总线与选通端置为高阻态。
当对总线的操作完成且没有即将对XINTF进行访问时,XINTF释放总线。
此信号是异步输入并与XTIMCLK同步XHOLDA` --- 外部DMA保持确认信号。
当XINTF响应XHOLD的请求时XHOLDA呈低电平,所有的XINTF总线和选通端呈高阻态。
XHOLD和XHOLDA信号同时发出。
当XHOLDA有效(低)时外部器件只能使用外部总线XZCS0AND1` --- XINTF区域O和区域1的片选,当访XINTF区域0或1时有效(低)XZCS2` --- XINTF区域2的片选,当访XINTF区域2时有效(低)XZCS6AND7` --- XINTF区域6和区域7的片选,当访XINTF区域6或7时有效(低)XWE` --- 写有效。
有效时为低电平。
写选通信号是每个区域操作的基础,由XTIMINGX寄存器的前一周期、当前周期和后一周期的值确定XRD` --- 读有效。
低电平读选通。
读选通信号是每个区域操作的基础,由xTIMINGX寄存器的前一周期、当前周期和后一周期的值确定。
注意:XRD`和XWE`是互斥信号XR/W` --- 通常为高电平,当为低电平时表示处于写周期,当为高电平时表示处于读周期XREADY --- 数据准备输入,被置1表示外设已为访问做好准备。
XREADY可被设置为同步或异步输入。
在同步模式中,XINTF接口块在当前周期结束之前的一个XTIMCLK时钟周期内要求XREAD Y有效。
在异步模式中,在当前的周期结束前XINTF接口块以XTIMCLK的周期作为周期对XREAD Y采样3次。
2812存储器映射及CMD2812存储器映射2812具有32位的数据地址和22位的程序地址,总地址空间可以达到4M的数据空间和4M的程序空间。
32位的数据地址,就是能访问2的32次,是4G,而22位的程序地址,就是能访问2的22次,是4M。
其实,2812可寻址的数据空间最大是4G,但是实际线性地址能达到的只有4M,原因是2812的存储器分配采用的是分页机制,分页机制采用的是形如0 xXXXXXXX的线性地址,所以数据空间能寻址的只有4M。
2812的存储器被划分成了下面的几个部分:1. 程序空间和数据空间。
2812所具有的RAM、ROM和FLASH都被统一编址,映射到了程序空间和数据空间,这些空间的作用就是存放指令代码和数据变量。
2. 保留区。
数据空间里面某些地址被保留了,作为CPU的仿真寄存器使用,这些地址是不向用户开放的。
3.CPU中断向量。
在程序空间里也保留了64个地址作为CPU的32个中断向量。
通过CPU寄存器ST1中的VMAP位来将这一段地址映射到程序空间的底部或者顶部。
映射和空间的统一编址F2 812内部的映射空间低地址空间高地址空间2812CMD详解CMD:command命令,顾名思义就是命令文件指定存储区域的分配.2812的CMD采用的是分页制,其中PAGE0用于存放程序空间,而PAGE1用于存放数据空间。
1.)#pragma ,CODE_SECTION和DATA_SECTION伪指令#pragma DATA_SECTION(funcA,"dataA"); ------ 函数外声明将funcA数据块定位于用户自定义的段"dataA"中 ------ 需要在CMD中指定dataA段的物理地址2.)MEMORY和SECTIONS是命令文件中最常用的两伪指令。
MEMORY伪指令用来表示实际存在目标系统中的可以使用的存储器范围,在这里每个存储器都有自己的名字,起始地址和长度。
第4课F2812片内资源、存储器映射以及CMD文件的编写作者:顾卫钢谢芬(HELLODSP资深会员)从今天开始,我们的课程终于进入F2812的核心了,呵呵。
在今天的课程中,我们将带领大家一起学习2812的片内资源,初步了解它究竟有哪些本事,能拿来干些什么,然后一起了解2812存储器的结构,统一编址的方式、存储器映射关系,并重点分析CMD文件,以期望消除大家对CMD文件的迷惑,在自己编写程序的时候会修改CMD文件中的部分内容,从而满足自己设计时的需求。
1.F2812的片内资源我们知道,TMS320F2812是32位的定点DSP,它既具有数字信号的处理能力,又具有强大的事件管理能力和嵌入式控制功能,特别适合用于需要大批量数据处理的测控领域,例如自动化控制、电力电子技术、智能化仪表、电机伺服控制。
下面是F2812的内部资源框图。
图1 TMS320F2812内部资源框图2812采用了高性能的静态CMOS技术,时钟频率可达150MHZ(6.67ns),其核心电压为1.8V,I/O口电压3.3V,Flash编程电压也为3.3V,所以我们在设计2812电源部分的时候,需要将常用的5V电压转换成1.8V和3.3V的电压之后,才能供给2812。
具体的设计我们将会在以后的硬件设计内容里进行探讨。
让我们一起来看看图1,最左边的A(18-0)和D(15-0)是表示2812外扩存储器的能力,2812外扩的存储空间最大是219*16 bit,就是说最多只能扩512K个存储单元,每一个存储单元的位数为16位。
从图中我们也可以看到,F2812支持JTAG边界扫描(Boundary Scan),这也是为什么我们的仿真器都是采用JTAG口的原因了,在这里,提醒大家一点的就是,仿真的时候,JTAG口的方向不能插反,如果插反的话会将仿真器烧坏。
我们所使用的14针JTAG口的第6针是空脚,所以一般情况下仿真器JTAG线的第6针是填针的,同时在板子上的第6脚是拔空的,这样可以防止您插反JTAG口,以避免不必要的损失。
hello第四课(二):f2812存储器映射及cmd详解-日志
-eyes417-...
2812存储器映射
2812具有32位的数据地址和22位的程序地址,总地址空间可以达到4M的数据空间和4M的程序空间。
32位的数据地址,就是能访问2的32次,是4G,而22位的程序地址,就是能访问2的22次,是4M。
其实,2812可寻址的数据空间最大是4G,但是实际线性地址能达到的只有4M,原因是2812的存储器分配采用的是分页机制,分页机制采用的是形如0xXXXXXXX的线性地址,所以数据空间能寻址的只有4M。
 2812的存储器被划分成了下面的几个部分:
1. 程序空间和数据空间。
2812所具有的RAM、ROM和FLASH都被统一编址,映射到了程序空间和数据空间,这些空间的作用就是存放指令代码和数据变量。
2. 保留区。
数据空间里面某些地址被保留了,作为CPU的仿真寄存器使用,这些地址是不向用户开放的。
3. CPU中断向量。
在程序空间里也保留了64个地址作为CPU 的32个中断向量。
通过CPU的一个寄存器ST1中的VMAP
位来将这一段地址映射到程序空间的底部或者顶部。
映射和空间的统一编址 
F2812内部的映射空间 
2812CMD详解CMD:command 命令,顾名思义就是命令文件指定存储区域的分配.2812的CMD采用的是分页制,其中PAGE0用于存放程序空间,而PAGE1用于存放数据空间。
1.)#pragma ,CODE_SECTION和DATA_SECTION伪指令#pragma DATA_SECTION(funcA,"dataA"); ------ 函数外声明
将funcA数据块定位于用户自定义的段"dataA"中------ 需要在CMD中指定dataA段的物理地址2.)MEMORY和SECTIONS是命令文件中最常用的两伪指令。
MEMORY伪指令用来表示实际存在目标系统中的可以使用的存储器范围,在这里每个存储器都有自己的名字,起始地址和长度。
SECTIONS伪指令是用来描述输入端是如何组合到输出端内的。
以常用的F2812_nonBIOS_RAM.cmd
F2812_nonBIOS_Flash.cmd 和
DSP281x_Headers_nonBIOS.cmd为例
F2812_nonBIOS_RAM.cmd ----- 用于仿真,无BIOS系统,片外SRAM配置CMD文件里有两个基本的段:初始化段和
非初始化段。
初始化段包含代码和常数等必须在DSP上电之后有效的数。
故初始化块必须保存在如片内FLASH等非遗失性存储器中,非初始化段中含有在程序运行过程中才像变量内写数据进去,所以非初始化段必须链接到易失性存储器中如RAM。
已初始化的段:.text,.cinit,.const,.econst,..pinit 和.switch..
.text:所有可以执行的代码和常量
.cinit:全局变量和静态变量的C初始化记录
.const:包含字符串常量和初始化的全局变量和静态变量(由const)的初始化和说明
.econst:包含字符串常量和初始化的全局变量和静态变量(由far const)的初始化和说明
.pinit:全局构造器(C++)程序列表
.switch:包含switch声明的列表 
非初始化的段:.bss,.ebss,.stack,.sysmem,和esysmem.(更好的理解就是,这些段就是存储空间而已)
.bss: 为全局变量和局部变量保留的空间,在程序上电时.cinit 空间中的数据复制出来并存储在.bss空间中。
.ebss:为使用大寄存器模式时的全局变量和静态变量预留的空间,在程序上电时,cinit空间中的数据复制出来并存储
在.ebss中
.stack:为系统堆栈保留的空间,主要用于和函数传递变量或为局部变量分配空间。
.sysmem:为动态存储分配保留的空间。
如果有宏函数,此空间被宏函数占用,如果没有的话,此空间保留为0
.esysmem:为动态存储分配保留的空间。
如果有far函数,此空间被相应的占用,如果没有的化,此空间保留为
0.F2812_nonBIOS_Flash.cmd --- 用于无BIOS,从片内FLASH引导对于程序在FLASH中运行时,需要注意的:DSP在150M时钟频率下,FLASH中只能提供大约120M的时钟频率,所以有时候我们希望在RAM中运行时间敏感或计算量很大的子程序(比如AD采样)。
但是我们所有代码都放在FLASH中,这就必须在上电后将FLASH中的这段敏感程序复制到RAM中运行,加快速度。
这是在.CMD文件就必须划分一段用来设置RAM的载入和运行地址。
程序代码如下:
SECTIONS {………
ramfuncs : LOAD = FLASHD,
RUN = RAML0,
LOAD_START(_RamfuncsLoadStart),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
PAGE = 0
}
“load=加载地址run =运行地址”链接器为每个输出段都在目标存储器里分配两个地址:一个是加载地址,一个是运行地址。
通常情况下两个地址是相同的,可以认为输出段只有一个地址,这时就可以不加“run =运行地址”这条语句了;但有时需要将两个地址分开,比如将程序加载到FLASH,然后放到RAM中高速运行,这就用到了运行地址和加载地址的分别配置了.
“load =加载地址”的几种写法需要说明一下,首先“load”关键字可以省略,“=
”可以写成“>”, “加载地址
”可以是:地址值、存储区间的名字、PAGE关键词等,所以大家见到“.text:{ } > 0x0080”这样的语句可千万不要奇怪。
“run =运行地址”中的
“ = ”可以用
“>”DSP281x_Headers_nonBIOS.cmd -----
用于无BIOS,外设寄存器产生的数据段映射至对应的存储器空间查看段的分配及使用情况.map的链接器(存储器)分配映射文件,链接器的map文件描述以下内容:通过map 文件可以查看各段的分配情况,包括段的起始地址,使用的字节数等配合cmd文件的使用,可确定各个段的使用情况,从而保证程序的正常运行和最小的空间使用。
VisualLinker 可视化链接器TI公司出品的DSP软件开发环境CCS还提供了一种可视化生成存储器配置文件的工具:VisualLinker可视化链接器。
如果程序原来包含了一个链接器命令文件(.cmd 文件),则当创建可视化链接文件的时候,原来cmd文件中的内存配置仍然会被使用。
如果读者想修改内存配置,双击.rcp文件就会在CCS中打开可视化链接器的图形界面,调整每个内存模块的大小,直到认为合适,然后只需要重新连编,程序即可生成新的输出文件,重复上面的步骤,直到出现满意的结果。