第4课_2812的片内资源、存储器映射以及CMD文件的编写

第4课_2812的片内资源、存储器映射以及CMD文件的编写
第4课_2812的片内资源、存储器映射以及CMD文件的编写

第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口,以避免不必要的损失。这一点,在我们自己设计板子的时候尤其需要注意。

在图1中,我们可以看到连接整个芯片各个模块的两条黑色的线,从英文单词上我们可以看到一条是Program Bus,另一条是Data Bus,就是程序总线和数据总线。这个概念讲的还是比较笼统的,下面我们详细分析这两天总线,并结合图中总线上的各个箭头来理解这些概念。

我们首先需要知道2812的存储器空间被分成了2块,一块是程序空间,一块是数据空间,而无论是那一块的内容,我们都需要借助于两种总线来进行传送相关的内容——地址总线和数据总线,用地址总线来传送存储单元的地址,而用数据总线来传送存储单元内的内容。2812的存储器接口具有3条地址总线和3条数据总线。了解了这些基本的内容之后我们接下来一一讲述2812内部的总线结构。

先来讲地址总线,顾名思义,这类总线的作用就是来传送存储单元的地址的。

1.PAB (Program Address Bus)程序地址总线,它是一个22位的总线,用于传送程序空间的读写地址。

程序在运行的时候,假如执行到了某一个指令,那么需要去找到这段代码的地址,就是用PAB来传送。

2.DRAB(Data-Read Address Bus)数据读地址总线,它是个32位的总线,用于传送数据空间的读地址。

假如要读取数据空间某一个单元的内容,那么这个单元的地址就是通过DRAB来传送。

3.DWAB(Data-Write Address Bus)数据写地址总线,它也是个32位的总线,用于传送数据空间的写地

址。类似的,如果我要对数据空间的某一个单元进行写操作,那么这个单元的地址就是通过DWAB来传送。

了解了地址总线后,我们再来看看数据总线,这类总线传送的就是数据了,也就是各个存储单元内的具体内容了。

1.PRDW(Program-Read Data Bus)程序读数据总线,它是一个32位的总线,用于传送读取程序空间时

的指令或者数据。我们在执行代码的时候,首先是通过PAB传送并找到了存放该指令的存储单元,但是这个存储单元下的具体内容就要由我们的PRDW来传送了。

2.DRDB(Data-Read Data Bus)数据读数据总线,它是一个32位的总线,在读取数据空间时用来传送数

据。我们在进行读操作时,先通过DRAB总线确定了需要进行读操作的数据单元的地址,接下来传送这个数据单元下面的具体内容时就需要DRDB了。

3.DWDB(Data/Program-Write Data Bus)数据写数据总线,它是一个32位的总线,在进行写操作时,

向数据空间/程序空间传送相应的数据。也就是假如我们要对数据空间的某一个单元进行写操作,我们通过DWAB传送了这一个单元的地址,同时我们需要DWDB来传送写入的内容。

看了这么多总线,大家是不是有些晕乎乎的呢,呵呵。又是程序空间,数据空间,又是地址总线,数据总线,看的乱了。或许有的朋友就要问了,刚才讲了这么多地址总线和数据总线,那图1中标注的是Program Bus和Data Bus,不是什么地址总线和数据总线啊,怎么会这么混乱呢?不急,呵呵,请大家一起来看看我们的图2吧,2812内部的总线结构。

大家在比较上面的内容和图2时,是不是对2812的总线有了豁然开朗的感觉呢?呵呵,希望有,如果没有的话,请反复阅读一下,这个内容虽然不是什么重点,但是对于理解2812内部的存储结构也是有帮助的。从图2我们也可以看到,我们不能同时对程序空间进行读写,因为PAB是复用的,读写操作会同时使用到PAB。同样的,我们也不能同时对程序空间和数据空间进行写操作,因为DWDB也是复用的,对程序空间进行写操作或者对数据空间进行写操作,都要用到DWDB。

图2 2812内部的总线结构

呵呵,用了很长的篇幅来介绍了2812内部的总线结构,一是帮助大家看懂图1中的总线,二是为后面学习存储器方面的内容打下一个伏笔,既然讲到了存储器,我们就接着讲2812内部的存储器资源。CPU 本身没有存储器,但是2812片内集成了RAM、ROM和FLASH,具体的存储器资源如下表所示:

我们通常在调试程序的时候把程序load到RAM里,而固化程序的时候才会把程序烧写到FLASH里。

结束这些看了头晕的内容吧,来了解一下稍微轻松些的CPU资源和外设资源吧。2812有3个32位的CPU定时器,支持动态的改变锁相环的频率,有片内振荡器和看门狗定时器模块。2812具有3个外部中断,但是2812具有外部中断的扩展模块(PIE),它可支持96个外部中断,不过当前仅仅使用了45个外部中断,其他为保留,将来2812功能扩展之后说不定会用到哦。具有128位的密钥,用于保护FLASH、OTP和L0、L1中的内容不被盗读。

接下来,主要看一下2812有哪些外围设备,这些外围设备大概的情况,可以参看图1:

1. 2个事件管理器EVA、EVB,这个应该是使用2812必用的外设了,PWM波形就是需要这个外设来产生的。

2. 2个串行通信接口SCI,标准的UART(SCIA SCIB)。

3. 1个串行外围接口SPI。

4. 改进的CAN通信ECAN。

5. 多通道缓冲串行接口McBSP。

6. 12位的ADC,一共有16个通道,实现AD转换的功能

7. 最多有56个可独立编程的,多功能复用的GPIO引脚。

在这里,我们只需要了解这些就可以了,后面我们会一个外设、一个外设的去详细学习。

2.存储器映射

通过前面的内容我们已经知道,2812具有32位的数据地址和22位的程序地址,总地址空间可以达到4M的数据空间和4M的程序空间。读到这一句话的时候,我不知道大家会不会产生疑问,一个是32位的数据地址,一个是只有22位的程序地址,那么为什么其可寻址的空间却是一样大的呢?这时候,您可能会算一下,32位的数据地址,就是能访问2的32次,是4G,而22位的程序地址,就是能访问2的22次,是4M。不对呀,可寻址的数据空间应该是4G而不是4M,难道TI的文档出错了吗?其实,2812可寻址的数据空间最大确实是4G,但是实际线性地址能达到的只有4M,原因是2812的存储器分配采用的是分页机制,分页机制采用的是形如0xXXXXXXX的线性地址,所以数据空间能寻址的只有4M,但也足足您够用啦,呵呵。

存储器就像一个仓库,用来存放很多的货物,只不过存储器是用来存放指令和数据的。2812的存储器

被划分成了下面的几个部分:

1.程序空间和数据空间。2812所具有的RAM、ROM和FLASH都被统一编址,映射到了程序空间和数据空

间,这些空间的作用就是存放指令代码和数据变量。

2.保留区。数据空间里面某些地址被保留了,作为CPU的仿真寄存器使用,这些地址是不向用户开放的。

3.CPU中断向量。在程序空间里也保留了64个地址作为CPU的32个中断向量。通过CPU的一个寄存器

ST1中的VMAP位来将这一段地址映射到程序空间的底部或者顶部。

这里,我们还得讲一下什么是映射,其实大家在中学的数学里应该学过映射这一个概念。曾经看过一个网友是这么解释映射的,很有趣,大家不妨一读。

对于映射和空间的统一编址,我们用一个通俗的例子来帮助大家进行理解,请大家看图3。假设一个物流公司,它有储藏货物的仓库若干个,每天来来往往成千上万的货物要发送到全国各地,如果拿回来的货物乱七八糟的堆放的话,发货的时候麻烦可大了,不仅仅是一个仓库一个仓库去找,而且要一个货架一个货架的翻,这样效率可是及其低下,匆忙之下也有可能将货物搞错。为了提高效率,老板肯定要进行改革,首先把各个仓库分类,例如仓库1是发往江苏和上海的货物,仓库2是发往北京的货物,仓库3是发往深圳的货物,仓库4是发往西安的。其次,货物进来前要根据目的地贴上统一规格的标签,例如HD1000-HD2009的货物放在仓库1内。这样,发货的时候,只要根据标签就能方便的分辨出货物在哪个仓库的哪个货架,应该装上发往哪个地区的货车,一切井然有序。

图3 映射和空间统一编址的理解

类似的,各个存储空间就像物流公司的仓库一样,有的是存放程序代码的,有的是用来存放数据的。而且我们对各个存储单元进行了统一的编址,确定了各个存储单元所在的位置,在放置代码或者数据的时候,根据他们的类型进行分配究竟放在那个区域,并记录下了它们的地址,这样需要用到的时候只要根据这些地址就能很方便的找到我们所需要的内容。而记录下如何分配存储空间内容的就是我们的CMD文件了。我们会在稍后详细介绍CMD文件的内容以及编写方法。大家可以比对着图3来加深对于这部分内容的理解。

接下来,让我们看看F2812内部的映射空间,如图4所示。其存储空间分布如下表所示:

图4 F2812内部的存储器映射

3.CMD文件的认识(由谢芬编写)

对于大多数初学者而言,在运行程序的过程中,直接运用的是程序本身自带的SRAM.CMD或者是FLASH.CMD。对于其中的内容,大家并没有做过多的了解,但是一旦当外扩了SRAM等的时候,用原来的

CMD文件就编译通过不了,这时需要我们对CMD文件大体结构了解的基础上,作修改,接下来,我就根据自己的经历来谈谈对于CMD文件的认识。

CMD:command命令,顾名思义就是命令文件指定存储区域的分配.2812的CMD采用的是分页制,其中PAGE0用于存放程序空间,而PAGE1用于存放数据空间。

我们以大家最常用的SRAM.CMD文件我们开始说开:

SRAM.CMD

MEMORY

{

PAGE 0 :

PRAMH0 : origin = 0x3f8000, length = 0x001000

PAGE 1 :

/* SARAM */

RAMM0 : origin = 0x000000, length = 0x000400

RAMM1 : origin = 0x000400, length = 0x000400

/* Peripheral Frame 0: */

DEV_EMU : origin = 0x000880, length = 0x000180

FLASH_REGS : origin = 0x000A80, length = 0x000060

CSM : origin = 0x000AE0, length = 0x000010

XINTF : origin = 0x000B20, length = 0x000020

CPU_TIMER0 : origin = 0x000C00, length = 0x000008

CPU_TIMER1 : origin = 0x000C08, length = 0x000008

CPU_TIMER2 : origin = 0x000C10, length = 0x000008

PIE_CTRL : origin = 0x000CE0, length = 0x000020

PIE_VECT : origin = 0x000D00, length = 0x000100

/* Peripheral Frame 1: */

ECAN_A : origin = 0x006000, length = 0x000100

ECAN_AMBOX : origin = 0x006100, length = 0x000100

/* Peripheral Frame 2: */

SYSTEM : origin = 0x007010, length = 0x000020

SPI_A : origin = 0x007040, length = 0x000010

SCI_A : origin = 0x007050, length = 0x000010

XINTRUPT : origin = 0x007070, length = 0x000010

GPIOMUX : origin = 0x0070C0, length = 0x000020

GPIODAT : origin = 0x0070E0, length = 0x000020

ADC : origin = 0x007100, length = 0x000020

EV_A : origin = 0x007400, length = 0x000040

EV_B : origin = 0x007500, length = 0x000040

SPI_B : origin = 0x007740, length = 0x000010

SCI_B : origin = 0x007750, length = 0x000010

MCBSP_A : origin = 0x007800, length = 0x000040

/* CSM Password Locations */

CSM_PWL : origin = 0x3F7FF8, length = 0x000008

/* SARAM */

DRAMH0 : origin = 0x3f9000, length = 0x001000 }

SECTIONS

{

/* Allocate program areas: */

.reset : > PRAMH0, PAGE = 0

.text : > PRAMH0, PAGE = 0

.cinit : > PRAMH0, PAGE = 0

/* Allocate data areas: */

.stack : > RAMM1, PAGE = 1

.bss : > DRAMH0, PAGE = 1

.ebss : > DRAMH0, PAGE = 1

.const : > DRAMH0, PAGE = 1

.econst : > DRAMH0, PAGE = 1

.sysmem : > DRAMH0, PAGE = 1

/* Allocate Peripheral Frame 0 Register Structures: */

DevEmuRegsFile : > DEV_EMU, PAGE = 1

FlashRegsFile : > FLASH_REGS, PAGE = 1

CsmRegsFile : > CSM, PAGE = 1

XintfRegsFile : > XINTF, PAGE = 1

CpuTimer0RegsFile : > CPU_TIMER0, PAGE = 1

CpuTimer1RegsFile : > CPU_TIMER1, PAGE = 1

CpuTimer2RegsFile : > CPU_TIMER2, PAGE = 1

PieCtrlRegsFile : > PIE_CTRL, PAGE = 1

PieVectTable : > PIE_VECT, PAGE = 1

/* Allocate Peripheral Frame 2 Register Structures: */

ECanaRegsFile : > ECAN_A, PAGE = 1

ECanaMboxesFile : > ECAN_AMBOX PAGE = 1

/* Allocate Peripheral Frame 1 Register Structures: */

SysCtrlRegsFile : > SYSTEM, PAGE = 1

SpiaRegsFile : > SPI_A, PAGE = 1

SciaRegsFile : > SCI_A, PAGE = 1

XIntruptRegsFile : > XINTRUPT, PAGE = 1

GpioMuxRegsFile : > GPIOMUX, PAGE = 1

GpioDataRegsFile : > GPIODAT PAGE = 1

AdcRegsFile : > ADC, PAGE = 1

EvaRegsFile : > EV_A, PAGE = 1

EvbRegsFile : > EV_B, PAGE = 1

ScibRegsFile : > SCI_B, PAGE = 1

McbspaRegsFile : > MCBSP_A, PAGE = 1

/* CSM Password Locations */

CsmPwlFile : > CSM_PWL, PAGE = 1

}

上述文件中,MEMORY和SECTIONS是命令文件中最常用的两伪指令。MEMORY伪指令用来表示实际存在目标系统中的可以使用的存储器范围,在这里每个存储器都有自己的名字,起始地址和长度。SECTIONS 伪指令是用来描述输入端是如何组合到输出端内的。

由于DSP281X系列的独特性(片内存在SRAM和FLASH)所以必须创建一个用户链接命令文件,以便在运行程序时,每个块都能对号入座。

在CMD文件里有两个基本的段:初始化段和非初始化段。初始化段包含代码和常数等必须在DSP上电之后有效的数。故初始化块必须保存在如片内FLASH等非遗失性存储器中,非初始化段中含有在程序运行过程中才像变量内写数据进去,所以非初始化段必须链接到易失性存储器中如RAM。

在上述文件中,已初始化的段:.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:为动态存储分配保留的空间。如果有宏函数,此空间被宏函数占用,如果没有的话,此空间保留为0

.esysmem:为动态存储分配保留的空间。如果有far函数,此空间被相应的占用,如果没有的化,此空间保留为0.

总而言之上述所有的存储空间占的寄存器的类型总结如下:

弄懂了伪指令和各个段的含义之后,我们再来看CMD文件的各个细节。我们根据F28X系列DSP存储器映射图可以知道:

数据空间起始地址是0x0000,程序空间的起始地址是0x3D8000,

在程序空间中,M0SRAM和M1SRAM各有1K*16位

所以有RAMM0 起始地址:0x0000 长度:0x0400(2的10次为1K)

RAMM1 起始地址:0x0400(0x0000+0x0400) 长度:0x0800(2的10次方为1K) 同理从0x000800到0x000D00这段地址里面装的是2K*16位的外围结构,映射表中很清楚的可以看出从0x002000到0x006000地址被保留,所以另一部分的外设地址定义是从0x00700开始。掌握一个机构的起始来源,那么无论是SRAM还是FLASH里面的CMD文件我们参照存储器映射图我们都能看懂。

这样对于不开扩的存储器我们能读懂,这些一般情况下,我们对CMD文件不用修改,直接拿个现成的过来用就可以,现在在这解释下外扩SRAM时我们该如何修改存储器的地址。

拿个外扩256K的SRAM来说,对照DSPF2812的存储器映射来看,我们可以定义外扩存储器的地址在0X100000,那么链接的时候直接就链接到外部SRAM中,至于长度,设置小于256K或者等于256K就好了,一般我设置为0x011000.

对于程序在FLASH中运行时,需要注意的:

大家都知道,DSP在150M时钟频率下,FLASH中只能提供大约120M的时钟频率,所以有时候我们希望在RAM中运行时间敏感或计算量很大的子程序(比如AD采样)。但是我们所有代码都放在FLASH中,这就必须在上电后将FLASH中的这段敏感程序复制到RAM中运行,加快速度。这是在.CMD文件就必须划分一段用来设置RAM的载入和运行地址。

程序代码如下:

SECTIONS

{………

adcpage: LOAD=FLASHD,PAGE=0

RUN=RAMH0,PAGE=0

RUN_START(_adcpage_runstart),

LOAD_START(_adcpage_loadstart),

LOAD_END(_adcpage_loadend)

}

以上就是在CMD(SRAM或者FLASH程序在里面运行时所需要注意的),一般情况下,我们都是在原有的CMD文件做修改,一旦成形之后,此文件不需在修改,直接拿出来用即可。

以上有什么不对,希望那个大家提出来,我们一起讨论,共同进步。

欢迎仿真中国DSP开发服务平台:https://www.360docs.net/doc/ec11785039.html,。

HDSP-XDS510 USB仿真器+2812开发板仅需1180元,实惠不容错过!

DSP的CMD文件详解(整理版)

DSP的CMD文件详解 CMD是用来分配ROM和RAM空间用的,告诉链接程序怎样计算地址和分配空间。所以不同的芯片就有不同大小的ROM和RAM,存放用户程序的地方也不尽相同。所以要根据芯片进行修改,分为 MEMORY 和SECTIONS两个部分。 MEMORY { PAGE 0 .......... PAGE 1......... } SECTIONS { .vectors ................. .reset ................. ................ } MEMORY是用来指定芯片的ROM和RAM的大小和划分出几个区间。PAGE 0对应ROM, PAGE 1对应RAM。PAGE 里包含的区间名字与其后面的参数反映了该区间的起始地址和长度。 SECTIONS:(在程序里添加下面的段名,如.vectors。用来指定该段名以下,另一个段名以上的程序(属于PAGE0)或数据(属于PAGE1)放到“>”符号后的空间名字所在的地方。)

{ .vectors : { } > VECS PAGE 0 .reset : { } > VECS PAGE 0 ............ ............ .......... } eg: MEMORY { PAGE 0: VECS :origin = 00000h, length = 00040h LOW :origin = 00040h, length = 03FC0h SARAM :origin = 04000h, length = 00800h B0 :origin = 0FF00h, length = 00100h PAGE 1: B0 :origin = 00200h, length = 00100h B1 :origin = 00300h, length = 00100h B2 :origin = 00060h, length = 00020h SARAM :origin = 08000h, length = 00800h }

初学CMD文件

一、有关段(sections)的知识 汇编器和链接器产生的可被DSP装置执行的目标程序,这些目标文件格式被称为通用目标文件格式(COFF)。COFF使得模块化编程更容易,它鼓励用户在写汇编语言程序时根据代码块和数据块的方式来思考如何编写程序,这些“模块(block)”就是“段(sections)”。 目标文件的最小单位称为段,段是占据一个连续空间的代码块或数据块,与其他段一起在存储器映射图内。目标文件的各个段是分开的,有特色的。 一个COFF目标文件总是包含3个默认段: (1).text段,通常包含可执行代码; (2).data段,通常含有初始化数据; (3).bss段,通常为未初始化变量预留的空间。 自定义的段: (1)由汇编伪指令.sect创建的段 (2)由汇编伪指令.usect创建的段 其中,.text、.data、由.sect创建的段属于初始化段(含有数据和代码);.bss、由.usect创建的段属于未初始化段(为未初始化的数据在存储器映像图内预留空间)。 注:不能用不同的伪指令定义相同的段。 二、由汇编器产生的COFF格式的OBJ文件中的段作为构造块,当有多个文件进行链接时,链接器会将输入段结合在一起产生可执行的COFF输出模块,然后链接器为各输出段选择存储器地址,这就是CMD文件。 CMD文件是用来分配ROM和RAM的,告诉链接程序怎么计算地址和分配空间。它包括三个部分: (1)输入、输出定义:.obj文件——链接器要链接的目标文件;.lib文件——链接器要链接的库文件;.map文件——链接器生成的交叉索引文件;.out文件——链接器生成的可执行代码。这部分可通过CCS中的Build Option菜单进行设置。 (2)MEMORY命令:描述系统实际的硬件资源,即指定芯片的ROM和RAM的大小和并划分出的几个区间。默认的,PAGE0对应ROM(程序存储区),PAGE1对应RAM(数据存储区),例定义一个VECS存储区域,具有R和W属性,填充常数ffffh: MEMORY { PAGE 0:VECS(RW):origin=0000h,length=00ffh,f=ffffh; } 注: 1)PAGE就是对一个存储空间进行标记,最多可以有255个PAGE,每个PAGE代表一个完全独立的地址空间,不同的PAGE上的存储器区间可以取相同的名字; 2)Attr:可选项,规定存储器属性: ①R,可以对存储器执行读操作; ②W,可以对存储器执行写操作; ③X,命名的存储器能包含可执行的代码; ④I,可以对存储器进行初始化; 3)origin:起始地址,可写成org或o;length:长度,可写成len或l。 4)fill:为存储区域指定的填充字符,可选项。填充值用来填充那些未分配给段的存储器区域。(3)SECTIONS命令:描述“段”如何定位。例如,在程序里定义段名.vectors,将引用字段名“.vectors”的程序或数据放到VECS(如上所示,VECS是ROM空间00h至ffh的地方):SECTIONS

CMD文件的编写

CMD文件的原理玄德(网名)于2009 年3 月 一、前言 开发TI 公司的DSP 芯片,肯定要编写或者修改CMD 文件,这是在单片机开发中没有碰到过的新事物,也是学习DSP的难点。面对里面种类繁多、名称各异、来历不明、作用不清、功能千差万别的存储器、区域和变量、寄存器,初学者往往都会一头雾水。甚至很多人已经把项目成功地完成了,对CMD文件仍然是一知半解。笔者也经历了极度困惑的过程,曾经大量地看书,下载资料,分析所能搜集到的CMD源文件。可惜的是,无论是TI 公司的原始文档,还是网上的资料,或者BBS的帖子,都没有透彻地说明CMD 文件的原理和使用,只说“然” ,要靠自己去体会“所以然” ,去“悟” 。终于有一天,我悟到了,也许只是“一些” 。现在,我把自己的“一些”写下来。我将细致而通俗地说明CMD 文件的原理,给您“鱼” ,更给您“渔” ,一步步地引导象我当初一样的初学者。我将以TI 的2407 为对象展开说明,对于TI 公司其他型号、其他系列的DSP,道理是完全相同的。用时下学术界最最最流行的语式,叫做“基于2407” ——这个词起源于英文的“based on” ,或“something based” ,被我们大量地引用,以至于令人反胃了——我们美妙、绚烂的语言,现在只剩下“基于”了。笔者水平有限,但保证会用心去写,您会看到很多别处没有的思路和信息,相信会基本打通初学者的任督二脉。本文适用于那些有单片机的开发基础、刚开始学习DSP 的初学者。如果你还不知道程序空间,数据空间这些名词,可能就比较困难了。 二、CMD文件的起源 在DSP系统中,存在大量的、各式各样的存储器,CMD文件所描述的,就是开发工程师对物理存储器的管理、分配和使用情况。有必要先复习一下存储器的知识。目前的物理存储器,种类繁多,原理、功能、参数、速度各不相同,有PROM、EPROM、EEPROM、FLASH、NAND FLASH、NOR FLASH等(ROM 类),还有SRAM、DRAM、SDRAM、DDR、DDR2、FIFO 等(RAM 类)。无论多么复杂,从断电后保存数据的能力来看,只有两类:断电后仍然能够保存数据的叫做 非易失性存储器(non-volatile,本文称为ROM 类),数据丢失的叫做易失性存储器(本文称为RAM 类);ROM 类的芯片都是非易失性的,而RAM 类都是

CMD命令文件详解

CMD 命令文件解析 CMD 文件的专业名称叫做链接器配置文件,用以存放链接器的配置信息,简称命令文件。其中比较关键的就是MEMORY、SECTIONS两个伪指令的使用。MEMORY和SECTIONS 的相关语句必须使用大写字符。MEMORY是用以配置目标存储器的,而SECTIONS是用以指定段的存放位置的。 1 存储空间的配置 DSP存储器分为三个独立选择的空间:程序空间、数据空间和I/O空间,其中程序存储器存放待执行的指令和执行中所用的系数(常数),可使用片内或片外的RAM、ROM、EPROM 等构成;数据存储器存放指令执行中产生的数据,可使用片内或片外的RAM和ROM来构成。I/O存储器存放与映像外围接口相关的数据,也可以作为附加的数据存储空间来使用。下表是TMS320F28335的存储空间分布: TMS320F28335的存储空间分布:

2 BootRom BootRom 是位于存储器地址0x3F E000 ~ 0x3F FFFF处的8K * 16位存储区域。并利用M0区域的0x0002 ~ 0x004E作为其Boot程序的堆栈和ebss区。其内存映射如下:

3 Cmd 文件的分配方法 TI公司新的汇编器和链接器创建的目标文件采用一种COFF(通用目标文件格式),该目标文件格式更利于模块化编程,为管理代码段和目标系统存储器提供了强有力和灵活的编程方法。用户可以通过编写链接命令文件(cmd文件)将链接信息放在一个文件中,以便在多次使用同样的链接信息时调用。在命令文件中使用两个十分有用的伪指令MEMORY 和SECTIONS,来指定实际应用中的存储器结构和进行地址的映射。M EMORY用来指定目标存储器结构,MEMORY下可以通过PAGE选项配置地址空间。链接器把每一页都当作一个独立的存储空间,通常情况下,PAGE0 代表程序存储器用来存放程序,PAGE1 代表数据存储器,用来存放数据。由编译器生成的可重定位的代码和数据块叫做“SECTIONS”(段),SECTIONS 用来控制段的构成与地址分配。对于不同的系统配置,“SECTION”的分配方式也不相同,链接器通过“SECTIONS”来控制地址的分配,所以“SECTIONS”的定义及分配就成了配置.cmd 文件的重要环节。以下是对“SECTIONS”的定义及分配的详细介绍。 4 SECTIONS介绍 SECTIONS可分为两个基本的部分:

BAT和CMD脚本的编写与实际应用全解

BAT、CMD脚本的编写与实际应用 在微软官方的定义中,BAT属于批处理脚本(可以运行在DOS、WINDOWS下),是用来进行简化平时操作的批量化集成文件。而CMD,则是只能运行在NT系统下的批处理文件,其功能与BAT是一样的。 从早期的BAT开始,该文件就为大家提供了方便,并在WINDOWS出现后,它的能力可以说是万能的。从最基础的启动盘的引导,到注册表,甚至系统服务的操作,BAT与CMD都可以胜任。而且由于它简便的编写与通用性,很快就布满整个世界。 本文将简单介绍BAT与CMD脚本的编写过程,因为在下水平不高,所以如有错误欢迎指出! 一、BAT与CMD中的部分参数 1、定义文件夹的参数 目前我能够搜集到并可以给出意思的通用系统参数如下(不包括后边的解释部分): %windir% ——操作系统文件夹,一般为C:下的WINDOWS文件夹 %sys% ——系统根目录,也就是C:盘目录 %programfiles% ——Program Files目录,安装程序通常都安装在这个目录下 %systemdrive% ——操作系统所在磁盘,与%sys%属于同一目录 %systemroot% ——操作系统文件夹,一般为C:下的WINDOWS文件夹 %InfDir% ——系统根目录,也就是C:盘目录 %TEMP% ——当前用户的临时目录,一般是C:\Documents and Settings\用户名\Local Settings\Temp目录 2、基础操作参数(可以在CMD命令行模式中输入HELP获得) ASSOC 显示或修改文件扩展名关联。 AT 计划在计算机上运行的命令和程序。 ATTRIB 显示或更改文件属性。 BREAK 设置或清除扩展式CTRL+C 检查。 CACLS 显示或修改文件的访问控制列表(ACLs)。 CALL 从另一个批处理程序调用这一个。 CD 显示当前目录的名称或将其更改。 CHCP 显示或设置活动代码页数。 CHDIR 显示当前目录的名称或将其更改。 CHKDSK 检查磁盘并显示状态报告。 CHKNTFS 显示或修改启动时间磁盘检查。 CLS 清除屏幕。 CMD 打开另一个Windows 命令解释程序窗口。 COLOR 设置默认控制台前景和背景颜色。 COMP 比较两个或两套文件的内容。 COMPACT 显示或更改NTFS 分区上文件的压缩。 CONVERT 将FAT 卷转换成NTFS。您不能转换 当前驱动器。 COPY 将至少一个文件复制到另一个位置。 DATE 显示或设置日期。 DEL 删除至少一个文件。 DIR 显示一个目录中的文件和子目录。 DISKCOMP 比较两个软盘的内容。 DISKCOPY 将一个软盘的内容复制到另一个软盘。

第4课 2812的片内资源、存储器映射以及CMD文件的编写

第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口,以避免不必要的损失。这一点,在我们自己设计板子的时候尤其需要注意。 在图1中,我们可以看到连接整个芯片各个模块的两条黑色的线,从英文单词上我们可以看到一条是Program Bus,另一条是Data Bus,就是程序总线和数据总线。这个概念讲的还是比较笼统的,下面我们详细分析这两天总线,并结合图中总线上的各个箭头来理解这些概念。 我们首先需要知道2812的存储器空间被分成了2块,一块是程序空间,一块是数据空间,而无论是那一块的内容,我们都需要借助于两种总线来进行传送相关的内容——地址总线和数据总线,用地址总线来传送存储单元的地址,而用数据总线来传送存储单元内的内容。2812的存储器接口具有3条地址总线和3条数据总线。了解了这些基本的内容之后我们接下来一一讲述2812内部的总线结构。 先来讲地址总线,顾名思义,这类总线的作用就是来传送存储单元的地址的。 1.PAB (Program Address Bus)程序地址总线,它是一个22位的总线,用于传送程序空间的读写地址。 程序在运行的时候,假如执行到了某一个指令,那么需要去找到这段代码的地址,就是用PAB来传送。 2.DRAB(Data-Read Address Bus)数据读地址总线,它是个32位的总线,用于传送数据空间的读地址。 假如要读取数据空间某一个单元的内容,那么这个单元的地址就是通过DRAB来传送。 3.DWAB(Data-Write Address Bus)数据写地址总线,它也是个32位的总线,用于传送数据空间的写地 址。类似的,如果我要对数据空间的某一个单元进行写操作,那么这个单元的地址就是通过DWAB来传送。 了解了地址总线后,我们再来看看数据总线,这类总线传送的就是数据了,也就是各个存储单元内的具体内容了。 1.PRDW(Program-Read Data Bus)程序读数据总线,它是一个32位的总线,用于传送读取程序空间时 的指令或者数据。我们在执行代码的时候,首先是通过PAB传送并找到了存放该指令的存储单元,但是这个存储单元下的具体内容就要由我们的PRDW来传送了。 2.DRDB(Data-Read Data Bus)数据读数据总线,它是一个32位的总线,在读取数据空间时用来传送数 据。我们在进行读操作时,先通过DRAB总线确定了需要进行读操作的数据单元的地址,接下来传送这个数据单元下面的具体内容时就需要DRDB了。 3.DWDB(Data/Program-Write Data Bus)数据写数据总线,它是一个32位的总线,在进行写操作时,

CMD文件编写

F2812的CMD文件的编写 CMD文件里包含三部分内容: 1)输入/输出定义: .obj文件:链接器要链接的目标文件; .lib文件:链接器要链接的库文件; .map文件:链接器生成的交叉索引文件; .out文件:链接器生成的可执行代码; 链接器选项 2)MEMORY命令:描述系统实际的硬件资源 3)SECTIONS命令:描述“段”如何定位 F2812的CMD文件只包含后两部分,现对它的编写做一下总结: (一)用于调试时用,取名为SRAM.CMD (二)用于烧写到FLASH中时用,取名为FLASH.CMD FLASH.CMD与SRAM.CMD基本一样,只是有两处改动:一是MEMORY中将你的程序代码部分映射到FLASH空间里;二是在SECTIONS中添加一个用户定义的起始段,起始段的代码如下: //User Defined Sections , Used by file DSP28_CodeStartBranch.asm codestart : > BEGIN, PAGE = 0 其中DSP28_CodeStartBranch.asm中的关键代码为: .ref _c_int00 .sect “codestart” Code_start: LB _c_int00 .end 这里有个比较标准的F2812的CMD文件,可以供大家借鉴使用: MEMORY {s PAGE 0: ZONE0 : origin = 0x002000, length = 0x002000 ZONE1 : origin = 0x004000, length = 0x002000 RAML0 : origin = 0x008000, length = 0x001000 ZONE2 : origin = 0x080000, length = 0x080000 ZONE6 : origin = 0x100000, length = 0x080000 OTP: origin = 0x3D7800, length = 0x000800 FLASHJ : origin = 0x3D8000, length = 0x002000 FLASHI : origin = 0x3DA000, length = 0x002000 FLASHH : origin = 0x3DC000, length = 0x004000 FLASHG : origin = 0x3E0000, length = 0x004000 FLASHF : origin = 0x3E4000, length = 0x004000 FLASHE : origin = 0x3E8000, length = 0x004000 FLASHD : origin = 0x3EC000, length = 0x004000

CMD文件详解

开发 TI 公司的 DSP 芯片,肯定要编写或者修改 CMD 文件,这是在单片机开 发中没有碰到过的新事物,也是学习 DSP的难点。面对里面种类繁多、名称各异、来历不明、作用不清、功能千差万别的存储器、区域和变量、寄存器,初 学者往往都会一头雾水。甚至很多人已经把项目成功地完成了,对CMD文件仍 然是一知半解。 笔者也经历了极度困惑的过程,曾经大量地看书,下载资料,分析所能搜集到 的CMD源文件。可惜的是,无论是TI 公司的原始文档,还是网上的资料,或 者BBS的帖子,都没有透彻地说明 CMD 文件的原理和使用,只说“然” ,要 靠自己去体会“所以然” ,去“悟” 。 终于有一天,我悟到了,也许只是“一些” 。现在,我把自己的“一些”写下来。我将细致而通俗地说明 CMD 文件的原理,给您“鱼” ,更给您“渔” ,一步步地引导象我当初一样的初学者。我将以 TI 的 2407 为对象展开说明, 对于 TI 公司其他型号、其他系列的 DSP,道理是完全相同的。用时下学术界最最最流行的语式,叫做“基于2407”——这个词起源于英文的“based on” ,或“something based” ,被我们大量地引用,以至于令人反胃了——我们美妙、绚烂的语言,现在只剩下“基于”了。 笔者水平有限,但保证会用心去写,您会看到很多别处没有的思路和信息,相 信会基本打通初学者的任督二脉。本文适用于那些有单片机的开发基础、刚开 始学习 DSP 的初学者。如果你还不知道程序空间,数据空间这些名词,可能就 比较困难了。 二、CMD文件的起源 在DSP系统中,存在大量的、各式各样的存储器,CMD文件所描述的,就是开 发工程师对物理存储器的管理、分配和使用情况。有必要先复习一下存储器的知识。目前的物理存储器,种类繁多,原理、功能、参数、速度各不相同,有PROM、 EPROM、 EEPROM、 FLASH、 NAND FLASH、 NOR FLASH等(ROM 类),

.cmd文件通俗解释

本人dsp菜鸟,在dsp门边徘徊已久,就是入不了门。都说要要先学会编写CMD文件,也没找见什么详细资料。今天终于在C6000汇编用户工具指南中寻到蛛丝马迹。迫不及待的发上来。英语水平有限。翻译的不好,凑合看吧。有错的别拍砖。 另强烈恳求前辈高人给菜鸟们指个明路吧 MEMORY伪指令 连接器决定输出段(output section)分配到存储器里的位置,必须有一个目标的存储器模型来完成这个任务。MEMORY伪指令允许你建立目标存储器的模型,你可以定义系统包含的存储器类型和存储器的地址空间。连接器保持输出段分配模型并根据它决定可被目标代码使用的存储器位置。 C6000的存储器的配置随具体应用不同而不同。MEMORY 伪指令可以实现不同的配置。用MEMORY伪指令定义存储器模型后,可以用SECTIONS 伪指令分配输出段(out section)到一定义的存储器中。 默认的存储器模型 如果不使用MEMORY伪指令,连接器将使用基于C6000体系结构的默认存储器模型。默认模型假设系统提供所有的32bit地址空间并且可用。查看7-46业 MEMORY伪指令语法 MEMORY伪指令确定目标系统实际提供的可以被程序使用的存储器空间。每个空间都有如下特性: 名称 起始地址 长度 可选的属性设置(Optional set of attributes) Optional fill specification 在使用MEMORY伪指令时,必须保证所有的存储范围可以载入代码(loading code)。被MEMORY伪指令定义存储器都是一配置的;任何没有用MEMORY详细描述的存储器都是未初始化的。MEMORY伪指令表达式中没有定义的地址空间代表不存在的存储器空间。 MEMORY伪指令在command file中用MEMORY( 大写)表示,后面的大括号中列出了存储器空间。下面的例子定义了一个拥有4KB的快速外部存储器在地址0x0000 0000处,一个2KB的慢速外部存储器在地址0x0000 1000处,还有一个4KB的慢速存储器在地址0x1000 0000处。 /* Sample command file with MEMORY directive */ File.obj file2,obj //input files -o prog.out //options MEMORY

cmd文件

我的DSP之路-关于CMD文件的心得和问题 2008-2-21 1.关于对段的定义 目标文件至少包含三个默认段: .text 文本段通常包含可执行代码 .data 数据段通常包含初始化的数据.bss 保留空间段通常为没有初始化的变量保留空间 自定义段: .usect 保留空间段为没有初始化的数据保留空间的自定义段 .sect 初始化段自定义段 .asect 初始化段 和默认段的使用相同,但它们被单独汇编。例如,重复使用.text段在目标文件中创建单个.text段,在链接时,这个.text段作为单个单元分配到存储器中。假如有一部分可执行代码(如初始化程序)不希望和.text段分配在一起,可以将它们汇编进一个自定义段,这 样就可以分配在与.text段不同的地方。 不能用不同的伪指令定义相同的段。如.usect和.sect用同一个段名。 初始化 段 .text .data .sect .asect .text.data.sect “section name(段名)”.asect “section name” address(地址)当汇编器第一次遇到一个.data时,.data段为空的。跟在第一个.data伪指令后的指令被汇编进.data段,直到遇到.text、.sect、.asect。如果后面还遇到.data,则将跟在这些.data 后面的语句汇编时已经存在的.data段。这样就形成了单个可被连续分配到存储器中的.data段。.asect的伪指令的address是必需的。如果使用.asect指令继续汇编一个包含代码的绝对地址段(这里应该是指同一个段名的绝对地址段,还是说.asect只能有一个有地址参数?个人认识应该是前者),那么就不能使用地址参数。 .asect将代码从片外存储器加载到片内存储器里很有用。但已经很少使用,以属于过时的指令。未初始化段 .bss .usect .bss symbol(符号), size in words(字数)[blocking flag] symbol .usect “section name(段名)”size in words,[blocking flag] symbol:指向.bss或.usect伪指令所保留的存储空间的第一个字。这个符号与保留空间所使用的变量名相对应。这个符号可以让其化段引用,并且也可以用一个全局符号(.global)来声明。相当于C中定义 unsigned char symbol[size in words];Size in words:保留空 间大小。

C语言生成的段和CMD文件(精)

C 语言生成的段和CM D 文件 通用目标文件格式COFF (Common Object File Format), 是一种很流行的二进制可执行文件格式。二进制可执行文件包括库文件(以后缀.lib 结尾)、目标文件(以后缀.obj 结尾)、最终的可执行文件(以后缀.out 结尾)等。 1. COFF格式 详细的COFF 文件格式包括段头、可执行代码和初始化数据、可重定位信息、行号入口、符号表、字符串表等,这些属于编写操作系统和编译器人员关心的范畴。从应用的层面上讲,DSP 的C 语言程序员应掌握两点:通过伪指令定义段;并给段分配空间。至于二进制文件到底如何组织分配,则交由编译器完成。 把握COFF 格式的概念,最关键的一点就是:二进制可执行文件是以段(section )的形式存储的。 使用段的好处是鼓励模块化编程,提供更强大而又灵活的方法来管理代码和目标系统的内存空间。这里模块化编程的意思是,程序员可以自由决定愿意把哪些代码归属到哪些段,然后加以不同的处理。 编译器处理段的过程为:每个源文件都编译成独立的目标文件(以后缀.obj 结尾),每个目标文件含有自己的段,连接器把这些目标文件中相同段名的部分连接在一起,生成最终的可执行文件(以后缀.out 结尾)。 段分为两大类:已初始化的段和未初始化的段。 已初始化的段含有真实的指令和数据,存放在程序存储空间。程序存储空间在DSP 片内的FLASH 。调试代码时,则常常把代码在线下载到RAM 中运行。 未初始化的段只是保留变量的地址空间,未初始化的段存放在数据存储空间中,数据存储空间多为RAM 存储单元。在DSP 上电调用_c_int0初始化库前,未初始化的段并没有真实的内容。

C语言生成的段和CMD文件

C语言生成的段和CMD文件 通用目标文件格式COFF(Common Object File Format),是一种很流行的二进制可执行文件格式。二进制可执行文件包括库文件(以后缀.lib结尾)、目标文件(以后缀.obj结尾)、最终的可执行文件(以后缀.out结尾)等。 1. COFF格式 详细的COFF文件格式包括段头、可执行代码和初始化数据、可重定位信息、行号入口、符号表、字符串表等,这些属于编写操作系统和编译器人员关心的范畴。从应用的层面上讲,DSP的C语言程序员应掌握两点:通过伪指令定义段;并给段分配空间。至于二进制文件到底如何组织分配,则交由编译器完成。 把握COFF格式的概念,最关键的一点就是:二进制可执行文件是以段(section)的形式存储的。 使用段的好处是鼓励模块化编程,提供更强大而又灵活的方法来管理代码和目标系统的内存空间。这里模块化编程的意思是,程序员可以自由决定愿意把哪些代码归属到哪些段,然后加以不同的处理。 编译器处理段的过程为:每个源文件都编译成独立的目标文件(以后缀.obj 结尾),每个目标文件含有自己的段,连接器把这些目标文件中相同段名的部分连接在一起,生成最终的可执行文件(以后缀.out结尾)。 段分为两大类:已初始化的段和未初始化的段。 已初始化的段含有真实的指令和数据,存放在程序存储空间。程序存储空间在DSP片内的FLASH。调试代码时,则常常把代码在线下载到RAM中运行。 未初始化的段只是保留变量的地址空间,未初始化的段存放在数据存储空间中,数据存储空间多为RAM存储单元。在DSP上电调用_c_int0初始化库前,未初始化的段并没有真实的内容。 汇编语言中,通过六条伪指令来定义段,因此时常把伪指令和段混为一谈,比如伪指令“.bss”,也是段“.bss”。 (1)未初始化的段 1).bss:定义变量存放空间。 2).usect:用户可自行定义未初始化的段,提供给用户更多的灵活性。 (2)已初始化的段 1).text:包含可执行的汇编指令代码。.text是系统定义的默认段,如果不明确声明,代码就归属.text段。 2).data:一般包括常数数据。比如,用来对变量初始化的数据或一个正弦表格等。 3).sect:用户可自行定已初始化的段,提供给用户更多的灵活性。 4).asect:作用类似于.sect,但是多了绝对地址定位功能。由于地址定位功能常用功能更强大又灵活的命令文件来完成,这条指令在汇编编程中已经废弃不用。 2.C语言生成的段 先解释一下堆栈的概念,二者是不同的概念。 栈(stack)是由系统自动管理的一片内存,用来存放局部变量和函数压栈出栈的状态量。进入C语言函数时需要保存一些寄存器的状态,即压栈操作;退出函数时要还原那些寄存器,即出栈操作。 堆(heap)是当用户想要自己能独立灵活地控制一些内存时,可以用malloc()等函数开辟一些动态内存区,这些动态内存区称为堆。

DSP的CMD文件详解(整理版)(精)

DSP 的CMD 文件详解(整理版 CMD 是用来分配ROM 和RAM 空间用的, 告诉链接程序怎样计算地址和分配空间。所以不同的芯片就有不同大小的ROM 和RAM ,存放用户程序的地方也不尽相同。所以要根据芯片进行修改,分为 MEMORY 和SECTIONS 两个部分。 MEMORY { PAGE 0 .......... PAGE 1......... } SECTIONS { .vectors ................. .reset ................. ................ } MEMORY 是用来指定芯片的ROM 和RAM 的大小和划分出几个区间。PAGE 0对应ROM , PAGE 1对应RAM 。PAGE 里包含的区间名字与其后面的参数反映了该区间的起始地址和长度。 SECTIONS :(在程序里添加下面的段名,如.vectors 。用来指定该段名以下,另一个段名以上的程序(属于PAGE0 或数据(属于PAGE1 放到“>”符号后的空间名字所在的地方。

{ .vectors : { } > VECS PAGE 0 .reset : { } > VECS PAGE 0 ............ ............ .......... } eg: MEMORY { PAGE 0: VECS :origin = 00000h, length = 00040h LOW :origin = 00040h, length = 03FC0h SARAM :origin = 04000h, length = 00800h B0 :origin = 0FF00h, length = 00100h PAGE 1: B0 :origin = 00200h, length = 00100h B1 :origin = 00300h, length = 00100h B2 :origin = 00060h, length = 00020h

CCS 中CMD文件的原理

CMD文件的原理玄德(网名)于2009年3月 一、前言 开发TI公司的DSP芯片,肯定要编写或者修改CMD文件,这是在单片机开发中 没有碰到过的新事物,也是学习DSP的难点。面对里面种类繁多、名称各异、来历不明、作用不清、功能千差万别的存储器、区域和变量、寄存器,初学者往往都会一头雾水。甚至很多人已经把项目成功地完成了,对CMD文件仍然是一知半解。 笔者也经历了极度困惑的过程,曾经大量地看书,下载资料,分析所能搜集到的 CMD源文件。可惜的是,无论是TI公司的原始文档,还是网上的资料,或者BBS的帖子,都没有透彻地说明CMD文件的原理和使用,只说“然”,要靠自己去体会“所以然”,去“悟”。终于有一天,我悟到了,也许只是“一些”。现在,我把自己的“一些”写下来。我将细致而通俗地说明CMD文件的原理,给您“鱼”,更给您“渔”,一步步地引导象我当初一样的初学者。我将以TI的2407为对象展开说明,对于TI公司其他型号、其他系列的DSP,道理是完全相同的。用时下学术界最最最流行的语式,叫做“基于2407”——这个词起源于英文的“based on”,或“something based”,被我们大量地引用,以至于令人反胃了——我们美妙、绚烂的语言,现在只剩下“基于”了。 笔者水平有限,但保证会用心去写,您会看到很多别处没有的思路和信息,相信会 基本打通初学者的任督二脉。本文适用于那些有单片机的开发基础、刚开始学习DSP的 初学者。如果你还不知道程序空间,数据空间这些名词,可能就比较困难了。 二、CMD文件的起源 在DSP系统中,存在大量的、各式各样的存储器,CMD文件所描述的,就是开发 工程师对物理存储器的管理、分配和使用情况。 有必要先复习一下存储器的知识。目前的物理存储器,种类繁多,原理、功能、参 数、速度各不相同,有PROM、EPROM、EEPROM、FLASH、NAND FLASH、NOR FLASH等(ROM类),还有SRAM、DRAM、SDRAM、DDR、DDR2、FIFO等(RAM 类)。无论多么复杂,从断电后保存数据的能力来看,只有两类:断电后仍然能够保存数据的叫做非易失性存储器(non-volatile,本文称为ROM类),数据丢失的叫做易失性存储器(本文称为RAM类);ROM类的芯片都是非易失性的,而RAM类都是易失性的。即使同为ROM类或同为RAM类存储器,仍然存在速度、读写方法、功耗、成本等诸多方面的差别。比如SRAM的读写速度,从过去的15ns、12ns,提高到现在的8ns、10ns,FLASH的读取速度从120ns、75ns,到现在的40ns、30ns。有没有人这样想过:使用存储器的人,希望存在这样的区别吗?或者说,理想的存储器,应当是什么样的? ………… 我们使用存储器时,如果没有人为地改变它,就希望里面的数据永远不要变,即使 断了电也要完好地保存;如果里面的内容是我不需要的或者不能用的,我自然就会给它写入有用的内容,比如初始化。理想的存储器就应当永远保存数据,无论掉电与否,而且,希望读写速度为每秒无穷多字节,是0ns,而不是什么8ns,10ns。——不是吗? 然而,人类实现存储器芯片的技术,还没有达到理想情况,所以才会有这么多类别。 “非易失”和“速度”就是一对典型的矛盾。非易失的ROM类存储器,可以“永远”地保存数据,但读写速度却很低,比如30ns;RAM的速度(8ns)一般都比ROM(30ns) 快得多,但却不能掉电保存。这是很无奈的现实。假如有那么一天,ROM类的读写速度 和RAM一样快,或者RAM也可以掉电保存数据,就不存在易失和非易失的区别了,那将是革命性的进步。那时,智能芯片和智能系统的设计将会有很大的变化,编写CMD文件

cmd文件写法

DSP的存储器的地址范围,CMD是主要是根据那个来编的。 CMD 它是用来分配rom和ram空间用的,告诉链接程序怎样计算地址和分配空间. 所以不同的芯片就有不同大小的rom和ram.放用户程序的地方也不尽相同.所以要根据芯片进行修改.分两部分.MEMORY和SECTIONS. MEMORY { PAGE 0 .......... PAGE 1......... } SECTIONS {SECTIONS { .vectors ................. .reset ................. ................ } MEMORY是用来指定芯片的rom和ram的大小和划分出几个区间. PAGE 0 对应romAGE 1对应ram PAGE 里包含的区间名字与其后面的参数反映了该区间的起始地址和长度. SECTIONS:(在程序里添加下面的段名如.vectors.用来指定该段名以下, 另一个段名以上的程序(属于PAGE0)或数据(属于PAGE1)放到“>”符号后的空间名字所在的地方。 SECTIONS { .vectors : { } > VECS PAGE 0 .reset : { } > VECS PAGE 0 ............ ............ .......... } eg: MEMORY { PAGE 0: VECS: origin = 00000h,length= 00040h LOW: origin = 00040h,length= 03FC0h SARAM: origin = 04000h,length= 00800h B0: origin = 0FF00h,length= 00100h PAGE 1: B0: origin = 00200h,length= 00100h B1: origin = 00300h,length= 00100h B2: origin = 00060h,length= 00020h SARAM: origin = 08000h,length= 00800h } SECTIONS

dsp实验报告( CMD文件和Gel文件的编写 )

CMD文件和Gel文件的编写 一、实验目的 1. 掌握Gel文件的编写, 2. 熟悉Code Composer Studio的使用 二、实验设备 1. 集成开发环境CCS 2. 实验代码ccs_gel.s54、ccs_gel.cmd和ccs_gel.gel 三、实验内容 1. 建立项目并添加相应文件,连接编译(步骤同实验二一样),双击打 开CMD文件,对照教材理解CMD文件的编写结构,改变其中的内容,增加自定义段,保存并重新编译,比对前后两次编译得到的Map文件的异同。 2.了解GEL文件的功能。Gel文件不是DSP开发必须的文件,而是给 CCS使用的文件,它帮助设置CCS的仿真环境,而且可以完成一些常用的调试操 enuitem "C54x Experiment"; hotmenu C5402_Textout() { GEL_TextOut(“Hello,GEL is a solid tool !\n”); } hotmenu C5402_DSK_Test() /*此功能实现需要用到DSK板,可暂不添加,如做测试,需将此中文注释去掉*/ { *(int *)0x0@io = 0xff07; /* turn on LED */ } 测试其功能。 4. 查询help了解所有Gel的函数功能,并修改文件实现一个其它的Gel函数。 四、实验结果和提示 1. 当设备被选用后,与其关联的gel文件将被使用,其中的StartUp

函数将被调用。可修改其中的内容,如PMST寄存器的数值,并测试。 2. 如果当前CCS中装载了gel文件,那么就会出现相应的菜单项, 如图3-1所示。 图3-1 GEL菜单 3. 添加代码后,重新装载Gel文件将出现新的子菜单,如图3-2 所示,并测试新菜单的功能。 图3-2 新的子菜单 五、实验心得 通过以前两次的实验我已经能比较熟练的应用CCS这个软件,本次实验做的是Gel文件的编写,Gel文件不是DSP开发必须的文件,而是给CCS 使用的文件,它帮助设置CCS的仿真环境,而且可以完成一些常用的调试操,本次实验让我受益匪浅。

XX.cmd文件编写

1·什么是CMD文件,它有什么作用。 CMD文件是用来说明对应的对应的代码、数据、变量的存放空间。 它包括两个指令SECTOINS和MEMORY。 如果把RAM和ROM看成是两个仓库的话,那MEMORY指令就是把这两个仓库再分成不同的区域。如果把不同的代码段是看成一件件货物的话,那么SECTOINS指令则指出了这些货物对应的存放位置。 .cmd文件 由汇编器产生的COFF格式的OBJ文件中的段作为构造块,当有多个文件进行链接时,链接器会将输入段结全在一起产生可执行的COFF输出模块,然后链接器为各输出段选择存储器地址。 1.1 MEMORY指令说明 存储器(MEMORY)伪指令,用来定义目标系统的存储器空间。MEMORY可以定义存储器的区域,并指定起始地址和长度。 MEMORY伪指令的一般语法: MEMORY { PAGE 0: name1[(attr)]:origin=constant, length=constant; PAGE n: name1[(attr)]:origin=constant, length=constant; } PAGEn中的页号n最大为255。每个PAGE代表一个完全独立的地址空间。通常PAGE0为程序存储器,PAGE1为数据存储器。 Name1:存储器区间名。可包含8个字符。不同PAGE可以取同样的name1,但在同一个PAGE 内区间名不可以相同。 Attr:可选项。规定存储器属性。 R,可以对存储器执行读操作 W,可以对存储器执行写操作 X,破除可以装入可执行的程序代码 I,规定可以对存储器进行初始化 Origin:起始地址。 Length:区间长度。 初始化段用SECTIONS可定位两次:装入和运行。如:一些关键的执行代码必须装在系统的ROM中,但希望在较快的RAM中运行。 未初始化段只可被定位一次。 自己写的关于LF2406A的.cmd文件 MEMORY { PAGE 0: VECS: origin=0h, length=40h ;中断向量表,40h~43h为安全代码 ;或保留代码区,复位向量是0h和1h FLASH: origin=44h, length=0ffbch ;32Kflash

相关文档
最新文档