文档库 最新最全的文档下载
当前位置:文档库 › CMD文件的编写

CMD文件的编写

CMD文件的编写
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 文件就会很简单,甚至不需要了。已经有芯片厂家做了一些这方面的工作,比如把电池和RAM 结合起来,就是一个能掉电保存的RAM。它既可以作为传统的ROM 使用,又可以当RAM 使用。但这显然只是一个暂时、折中的方法,其原理、成本、体积、容量还不如人意,不能算是“革命性”的进步。我们平时在用到存储器的时候,要考虑哪些因素呢?首先必须确认,在你的使用场合,是要永久保存数据,还是暂时保存?这关系到选择非易失性,还是易失性存储器的大问题,是首要的问题。在某些场合,如果必须永远地保存数据,即使希望速度快一些,也只能选择非易失的ROM 类存储器,而把速度问题放在其次,或者另外想办法解决;另外一些场合,却要把速度放在第一位,只要在通电期间能够始终保存数据,就够了,当然就要选择RAM 类的存储器了。这两种情况我们都会遇到:程序代码一般都要存储在ROM 类存储器中,否则,从设备生产开始,储存、运输,一直到用户手里,要必备不间断电源,还要保证不发生断电的意外;程序运行的时候,为了提高速度,就必须在RAM 中运行,试想想,如果你的MP4放电影一停一顿的,谁还

会用它看电影呢?所以ROM 和RAM 都是必不可少的,各有各的用途,而且,出于功能、参数、速度、读写方法、功耗、工艺、成本等方面的考虑,往

往要同时使用不止一种存储器。

事实上,TI 在设计DSP芯片时,也遇到同样的问题,TI 考虑的情况要比我们更多,更复杂。要知道,设计芯片的人是最牛X的,开发工程师只是跟在人家后面,在人家规定的框框里亦步亦趋。翻开DSP的PDF文档,找到memory map 就会看到,芯片上集成了形形色色的存储器:FLASH、ROM、BROM、OTP ROM,SRAM、SARAM、DARAM、FIFO 等。就2407和2812而言,如果是做个流水灯之类的小东东,DSP芯片加晶体加电源就可以了,片上集成的ROM 和RAM,在仿真状态下已经足够用了,烧写并脱离仿真器运行也足够。所以,它们的最小系统不需要外扩任何存储器。但也只能做简单的东东,往往还需要外扩一些ROM 和/或RAM 存储器,才能委以大用。(顺便说一句,DSP的最小系统,要比8951芯片的最小系统大得多。)千万不要被这些存储器的名称所迷惑!翻来覆去,其实就是两大类:非易失和易失。初学者往往忽略了这一点。两大类!记住这一点,CMD文件就是以这两类存储器为主轴,然后展开的。DSP芯片的片内存储器,只要没有被TI占用,用户都可以全权支配。TI设计了“CMD文件”这种与用户的接口形式,用户通过编写CMD 文件,来管理、分配系统中的所有物

理存储器和地址空间。

CMD文件其实就是用户的“声明” ,包括两方面的内容:

1、用户声明的整个系统里的存储器资源。无论是DSP 芯片自带的,还是用户外扩的,凡是可以使用的、需要用到的存储器和空间,用户都要一一声明出来:有哪些存储器,它们的位置和大小。如果有些资源根本用不到,可以视为不存在,不必列出来;列出来也无所谓。

2、用户如何分配这些存储器资源,即关于资源分配情况的声明。用户根据自己的需要,结合芯片的要求,把各种数据分配到适当种类、适当特点、适当长度的存储器区域,这是编写CMD文件的重点。用户编写完自己的程序以后,要经过开发环境(编译器)的安排和解释(即编译),转换为芯片可以识别的机器码,最后下载到芯片中运行。CMD 文件就是在编译源程序、生成机器码的过程中,发挥作用的,它作为用户的命令或要求,交给开发环境(编译器)去执行:

就这么分配!

下面将从这两个方面入手,详细说明如何编写CMD文件。

三、编写CMD文件之——资源清单如上文所述,CMD 文件包含两大内容,首先就是存储器的资源清单,或者说,系统中(电路板上)可用的存储器资源。TI 规定,CMD文件的资源清单用关键字“MEMORY”作为标识,具体内容写在后面的大括号{ } 里面。如下面的形式:

MEMORY

{

PAGE 0:

xxx : org = 0x1234 , length = 0x5678 /*This is my house.*/

PAGE 1:

aaa : org = 0x1357 , length = 0x2468 /*My home here.*/

}

其中,MEMORY,PAGE n,org,length,包括冒号、等于号、花括号,都是关键字符,必不可少。PAGE n表示把可用的资源空间再划分成几个大块,最多允许分256块,从PAGE 0到PAGE 255。如果把MEMORY比作图书馆,PAGE n就是其中的“社科类” 、“工程类” 、“外文类”等。大家都习惯于把PAGE 0作为程序空间,把PAGE 1作为数据空间。如果你很好奇,也可以试试别的数字。凡智能芯片,都离不开这两种“空间” ,大名鼎鼎的冯·诺依曼结构和哈佛结构,都是建立在程序空间和数据空间两种结构的基础上,我们面对的DSP也是如此。只要学习过单片机,就很容易理解。如果你构思出第三种结构,恭喜您,您将与这二位齐名了。

CMD文件中还可以写上注释,用“/*”和“*/”包围起来,但不允许用“//” ,这一点和C语言不同。上面的例子,仅仅就是个“例子” ,不针对任何特定的芯片。带注释的语句有两行,每一行都是一项声明,表示在程序空间或数据空间下,再细分更小的块,好比是“社科类”又分了几个书架。比如xxx : org = 0x1234 , length = 0x5678 表示在程序空间PAGE 0里面,划分出一个命名为xxx的小块空间,起始地址从存储单元0x1234 开始,总长度为0x5678 个存储单元,地址和长度通常都以十六进制数表示。所以,xxx空间的实际地址范围从0x1234开始,到

0x1234 + 0x5678 – 1 = 0x68AB 结束(起始地址加长度再减一),这一段连续的存储区域,就属于xxx小块了。上面的例子中,PAGE 0和PGAE 1各包含了只有一个“小块” ,用户可以根据自己的情况,按照同样的格式任意增加。在支持多个CMD文件的开发环境里,某个或某几个CMD文件中,“小块”的数量可以为0,也就是说,关键字PAGE 0或PAGE 1下面,可以是空白的。但不允许所有的CMD 文件的同一空间都是空白。另外,没有资料提到过“小块”数量上限的限制,需要去查阅文档或咨询TI 公司。很多关键字,还允许有别的写法,比如“org”可以写为“o” ,“length”可以写为“len” 。这些规定和其他细节,可以去查阅TI 的pdf 文档,一般叫做“xxxxx Assembly Language Tools User's Guide.pdf” ,汇编语言工具指南,xxxxx是芯片的型号或系列。但这个文档不适合初学者。实践证明,至少对于C2000 系列的2407 和2812 而言,存储单元的单位是“字word” ,即16bit。但TI 的文档却说是“字节byte” ,应当是TI 写错了。要特别注意以下几点:

1、必须在DSP芯片的空间分配的架构体系以内,分配所有的存储器。这里举两个例子:

a、对于2407,程序空间和数据空间都是从地址0x0000 到0xFFFF,最大数值是四个F,共64K 字范围。所以,2407 的CMD文件中不能出现五位数的地址,也不允许任何一个小块空间的地址范围覆盖到64K 以外的区域,因为2407根本就无法控制这些区域,或者说不能访问、无法寻址。要注意,起始地址和长度不要算错了。2812也有同样的问题。

b、2407的数据空间里,0x0100~0x01FF 和其他几块区域,是TI 声明的保留空间(Reserved 或illegal),也是芯片无法访问的,分配资源的时候不能涉及到这些区域。同样地,2812的程序空间和数据空间,都有大片的保留区域,不能使用。

2、每个小块的空间,必须是一片连续的区域。因为,编译器在使用这块区域的时候,默认它是连续的,而且每个存储单元都是可用的。

3、同一空间下面,任何两个小块之间,不能有任何的相互覆盖和重叠。在外扩存储器时,要保证片外的存储空间之间,特别是片外与片内的存储空间之间,不要发生冲突。有些空间,已经被DSP 芯片的内部存储器占用了,用户是不可更

改的,或只能通过模式配置,在一定范围内改动,用户自行扩展存储器时,要避开这些地方。

4、用户所声明的空间划分情况,必须与用户电路板的实际情况相符合!对于用户自制的电路板,这是很容易出错的地方,通常会出现两种错误:

a、在设计硬件电路的时候,通常用CPLD 作为片外存储器的选通信号,用verilog 或者VHDL 进行编程;也有用74 或4000 系列芯片来搭建的,已经很少了。如果CPLD 逻辑出错,或者逻辑并没有真正写入CPLD 芯片里面,即使CMD 文件是正确的,即使编译已经通过,在仿真下载或者烧写的时候,PC机都会报错而无法继续操作。

b、电路板有虚焊的地方,主要发生在DSP 芯片的管脚、电平转换芯片的管脚,及片外存储器的管脚上。这种情况,效果等同于上面所说的CPLD 逻辑错误。更要命的是,补焊一次、两次甚至几次,虚焊仍然存在,这最容易把人搞糊涂了。笔者就经常遇到这样的事情。出现这些硬件错误时,初学者往往不能正确地对故障作出定位,一会儿认为CMD文件有问题,一会儿觉得硬件电路有问题,反复地折腾,最后陷入迷茫。这时,一定要保持清醒的头脑:先检查原理设计;再检查硬件电路板,保证逻辑正确,焊接可靠;最后再去检查CMD文件。

5、一般地,初学者会找一些现成的CMD 文件来用,一点改动都不敢。其实,胆子可以大一些,改一改,试一试,没什么大不了的。想学会游泳,必须要下水。DSP芯片上的存储器,只要没有被TI 用作专门的用途,用户都可以全权支配。空间的划分,是由用户决定的,可以根据需要,甚至个人的喜好来划分,名称也可以随意起,和C语言的变量名一样。这里应当举一个CMD 文件资源声明的例子,但为时过早。资源声明常常与资源分配是密切相关的,笔者把例子放在下一节,与资源分配一起详细说明,效果会好一些。

四、编写CMD文件之——资源分配

系统资源已经声明完了,现在就要说明,用户是如何分配这些存储器资源的,即向编译器声明资源的分配情况。要合理地分配存储器资源,首先要搞清一个问题:资源要分配给谁?有哪些东东需要占用存储器?

我们来看下面这段不严格的C程序:

{

unsigned int i;

i ++;

}

这“段”程序只是笔者建立的一个模型,用它来代表几乎所有的程序:哪怕变量(包括数组)有一千个、一万个,都用一个“i”来代表;哪怕程序主体包含了各种搬移、运算、逻辑等动作,哪怕有一万行那么长,都用一句“i++”来表示。让我们站在TI 公司和编译器的角度,来考虑下面的问题:程序经过编译以后,会产生哪些对存储器资源有要求的“状况”?

有单片机开发经验的人都知道,至少要产生两种情况:

1、指令码,即二进制形式的指令,需要占用芯片的“程序空间” 。这些数据,完全等价于或等同于用户编写的程序,只是转换成了另一种形式而已。这种“数据”有两个特点:

a、只要用户程序编写完成,这些“数据”就已经是可知的、可预期的,是由用户编写的程序代码和编译器共同决定的。

b、在系统运行过程中,这些数据的内容不会发生任

何变化,只会被读取,不会被修改。

2、在运行过程中,动态变化的“量” ,需要占用“数据空间” 。上面例子程序中的

变量i,就属于这种情况。这些数据,在设计师编写程序的时候,有时会预先写入具体的

数值,即初始化,有时甚至根本不需要进行初始化。在运行过程中,既要被读取,又会被

改写,经常在变化。设计师自己也很难确切知道,在某一时刻,这些数据的具体的数值是

什么,最多只知道它们的位数、最大和最小值的范围。

那么,什么样的物理存储器适合于数据空间使用,什么样的存储器适合于程序空间

对于数据空间,其最基本、最首要的要求是速度快,并不要求掉电保存数据的能力,

显然应当由RAM 类存储器来承担,所以,RAM 一般都必不可少。但是,并不是说数据空

间只能连接RAM 芯片,只要你能够接受比较慢的速度,并且安排好芯片的控制时序,你

完全可以在数据空间扩展ROM 类存储器。

程序空间的代码数据,一般都要求掉电保存,只能由ROM 来承担,所以ROM 必不可少。那么,ROM 的读取速度慢的问题,怎么解决呢?对于有些低速的智能芯片,ROM

的速度慢一点,是完全可以接受的,可以直接从ROM 中读取代码指令,然后译码、执行;

我们熟悉的MCS51、PIC 系列单片机,都是这么做的(以下信息笔者不能保证正确性:

2407 脱离仿真器运行时,似乎也是直接从ROM 中读取程序代码)。另外有一些低端的智

能芯片,生产商通过特殊的技术手段,在一定范围内等效地提高内部程序ROM 的读取速

度,比如NXP 公司的ARM 芯片LPC213x,虽然ARM 内核的数据接口只有32 位,但

LPC213x 的片内FLASH程序存储器,与内核之间的接口居然是128位宽度,通过所谓“加

速器”相连接。对于高速的智能芯片,从ROM 直接读取代码并执行,已经不能满足速度

的要求了,通常的解决方法是,把程序代码储存在ROM 中,在每次上电运行时,通过“引

导程序”把用户代码读出并保存在RAM 中,然后从RAM 中运行,这样做既解决了ROM

速度慢的问题,又解决了RAM 掉电丢失数据的问题。

实际操作中,并不是只有指令码和变量i 这么简单,除这两项以外,还会出现很多

小“状况” ;而且,当芯片型号不同,甚至用户源程序不同时,出现的细节也是变化的。恰

恰就是这些变化,导致CMD文件变得复杂。

但是,任何大“状况” 、小“状况” ,都归属于对程序空间和数据空间的操作,不存在第三种空间。(有些DSP 的所谓“IO 空间” ,实质上是数据空间的一个变种,但又脱离

了数据空间,不属于CMD文件考虑的范围。)

编写CMD文件,就是要搞清楚以下情况,并对编译器做出声明:

1、你的系统都有哪些存储器资源?

2、哪些存储器安排在程序空间,哪些在数据空间?

3、你的系统会产生哪些大“状况”和小“状况”?

4、哪些状况属于程序空间,哪些属于数据空间?

5、程序空间的“状况”如何安排在程序空间的资源里,数据空间的“状况”如何

安排在数据空间的资源里?

笔者想从事情的起源入手,逐步引导初学者自己去发现“资源要分配给谁?有哪些

东东需要占用存储器?”这个问题的答案,所以使用了一些不正规的术语,比如“状况”

这个词。

让我们从一个实际使用过的2407 芯片的CMD文件来展开说明,其他DSP芯片的

CMD文件与此大同小异:

/******************************************************************** **************************/

-stack 200h /* #1 */

/******************************************************************** **************************/

MEMORY /* #2 */

{

PAGE 0 :

VECS : origin = 0000h , length = 0040h /* 中断向量*/ /* #3 */

PROG : origin = 0100h , length = 7F00h /* 片上FLASH */ /* #4 */

PAGE 1 :

B2 : origin = 0060h , length = 0020h /* DARAM B2 块*/ /* #5 */

B0B1 : origin = 0200h , length = 0200h /* DARAM B0 块*/ /* #6 */

SARAM : origin = 0800h , length = 0800h /* SARAM 块*/ /* #7 */

ExtSRAM : origin = 8000h , length = 8000h /* 外部存储器*/ /* #8 */

}

/******************************************************************** **************************/

SECTIONS /* #9 */

{

.vectors : > VECS PAGE 0 /* 中断向量表*/ /* #10 */

.text : > PROG PAGE 0 /* 代码*/ /* #11 */

.cinit : > PROG PAGE 0 /* #12 */

.bss : > SARAM PAGE 1 /* #13 */

.stack : > B0B1 PAGE 1 /* #14 */

.extdata : >ExtSRAM PAGE 1 /* #15 */ }

/******************************************************************** **************************/

下图是2407芯片的空间分配情况(Memory Map),是从2407的数据手册直接复

制过来的:

#2行至#8行,MEMORY {……} 部分,就是上一节我们已经说明的,系统可用资源的声明,包括程序空间PAGE 0和数据空间PAGE 1 两部分。

程序空间PAGE 0,又分为VECS区域和PROG 区域。

#4行所声明的PROG区域,是为用户指令码分配的存储空间,这部分空间一般都很大(比如0x7E00h)。

相当于PROG 用户指令码区域,#3行声明的VECS 区域是一个特殊的“小状况” ,TI 在设计2407 的硬件电路时,用这块区域来保存各种中断服务程序的入口地址,即中断

向量,与硬件电路挂钩,不能与一般的程序代码相混杂,所以要单独声明。按照芯片手册

的说法,0x0000 至0x003F 共0x40 个存储器单元是中断向量,0x0040 至0x0043 四个单

元是保留位置。在上面的例子中,由于0x0040 ~ 0x0043四个单元暂时无用(reserved),

所以,VECS区域只覆盖了0x0000 ~ 0x003F;如果把0x0040 ~ 0x0043 也覆盖进来,估

计也没有问题,因为存放中断服务程序入口地址,是编译器根据用户的声明填充的,它会

把有用的地址数据安排到对应的单元里,至于没用的空间,无论保存了什么样的地址,对

于用户都无所谓。另外,按手册的说法,用户代码似乎应当从0x0044单元开始(User code

begins at 0044h),实际上可以这么做,也可以不这么做,只要在芯片的程序空间里,与其他

空间不发生冲突,从哪个单元开始都可以,编译器自然会安排,上面的例子就是从0x0100

单元开始存储程序代码。长度也是用户确定的,不一定要象例子那样,在0x7FFF 单元结

束。

笔者自行扩展了一块SRAM 存储芯片,型号为IS61LV6416,是ISSI 公司的产品,总容量64K 字(word),通过CPLD 逻辑电路,把一半的容量安排在程序空间的0x0000

至0x7FFF,覆盖了PROG和VECS两块区域。所谓“安排” ,就是常说的“映射” 。仔细

看一下2407 的Memory Map,程序空间从0x0000 至0x7FFF,已经全部被片内FLASH

存储器“占用” ,怎么能分配给其他芯片呢?再说,程序代码保存到SRAM 里面,掉电岂

不丢失?…… TI 在设计2407硬件电路的时候,给用户提供了一个MP/MC管脚,该管脚

接0电平时,程序空间通向外部存储器的接口(External Memory Interface)被切断,只

对片内的FLASH 存储器进行寻址,程序空间全部被FLASH 占用;该管脚接 1 电平时,

片内FLASH 被隔离,只对外接的存储器进行访问。在开发阶段,程序代码写入SRAM,

断电当然就丢失了,但这只麻烦开发人员一个人,每次都要重新往SRAM 里写一遍,开发

的时候,程序本来就在变,就必须重写;开发成功了,再写入FLASH 里,交付用户。那

么,TI 这么做,是否多此一举,直接在FLASH 里开发,不行吗?笔者不好妄下结论,估

计是出于以下考虑:a、烧写FLASH,需要特殊的算法即时序,在仿真状态下进行烧写可

能有困难,或存在其他问题;b、在FLASH 中运行程序时,难以同时进行仿真;

c、FLASH

存储器的烧写寿命有限。各位可以结合自己的经验,考虑一下这个问题。……总之,TI 设

计了这种方式,在仿真开发阶段,使用外扩的SRAM存储器,工程师把VECS数据和PROG

数据,通过仿真器和CCS环境的“load program”指令,下载到SRAM 芯片里运行;开发成功以后,再通过TI 提供的专用烧写插件,把代码烧到FLASH 存储器的对应空间里,

交付用户使用。所以,开发成功以后,程序空间外扩的SRAM 芯片也就不需要了,完全可

以删除,说不定还能节省一些产品成本呢。

顺便说一下,对于2407,无论是仿真开发还是脱离仿真,最好不要使用0x8000 ~

0xFFFF 的高32K 程序空间,原因有三:a、仿真阶段和脱离仿真器运行时,无法使用同

一个CMD 文件;b、会出现中断不正常的问题,在网上的论坛里,经常有人提问;c、最

重要的原因,是笔者的经历,曾经搞一个项目,代码量超出了32K,需要在高32K 空间扩

展程序存储器,咨询TI 公司后得知,必须由TI 提供特殊的CCS 文件,而且TI 不能保证

结果的正确性!后来笔者只好缩减代码。在CMD文件中,有意把片内FLASH的地址和

片外的SRAM 地址相重合,只需要用跳线改变MP/MC 管脚的电平,就能同时避开a和

b 两个问题,何乐而不为呢?!在仿真阶段和脱离仿真阶段,完全可以使用同一个CMD

文件。

IS61LV6416 的另一半,安排在数据空间,下文会进一步说明。至于把IS61LV6416

的低32K 安排在程序空间、高32K 安排在数据空间,还是正好相反,都无所谓,也都是

可以实现的,仅仅CPLD的逻辑不同而已,很多人会在这里糊涂半天。

PAGE 1是数据空间。#5、#6、#7三行所声明的B2、B0B1、SARAM 三块存储区,是2407芯片内部集成的存储器,彼此的地址都不连续,所以要分别声明。B0B1块,是由

B0块和B1块合并组成,但二者是有区别的:B1块地址始终固定在数据空间的0x0300h ~

0x03FF区域,B0块在芯片复位后的默认地址是数据空间的0x0200h ~ 0x02FF区域,但

用户可以通过软件设置CNF位,把B0块转移到程序空间里。如果用户需要这样的转移,

就不能把B0、B1 合并起来;如果用户不做这样的转移,就可以象这个例子一样,B0B1

合并起来整体使用,占用地址范围为0x0200h ~ 0x03FF。

#8行所声明的区域,就是上文所说的IS61LV6416 芯片的“另一半” 。之所以安排

在数据空间的0x8000 至0xFFFF 区域,原因很简单,因为这里是TI 指定的外扩数据存储

器的位置,数据空间的其他位置,基本上都被片内集成的存储器所占用,或者被禁用。起

始位置和长度是由用户自己决定的,你可以把这片区域分成几个小块来使用,只要相互不

重叠,不超出0x8000 至0xFFFF 区域,并且修改和增加对应的声明,就可以。声明语句

的格式都是一样的。另一方面,如果片内的2K 多的存储器已经够用,就不必外扩了,也

就不再需要#8这一行的声明。所以,如果只是用2407 做个流水灯之类的小东东,就不需

要外扩任何存储器,片上的ROM 和RAM 资源,在仿真状态下已经足够用了,脱离仿真

器运行也足够。#4~#8 五行所声明的空间,都可以进一步拆分,如我在前面所说的,是由用户决定

的,可以根据需要,甚至个人的喜好来划分。但#3 行的VECS 区域,因为与硬件挂钩的

缘故,一般都不再细分。#3~#8 共六行资源声明里,VECS、PROG、B2、B0B1、SARAM、

ExtSRAM这些名称,都允许用户自己来起名,和C语言的变量名一样;但在后面#10 ~ #15

的几行里引用的时候,必须使用同样的名称。

片上的存储器,B2、B0、B1三块是DARAM,全称是dual-access RAM,根据手册的说明,它能够在同一个“循环”内(in the same cycle),同时完成读出和写入;另一

块是SARAM,全称single-access RAM,不要与“SRAM”相混淆。手册上和TI 网站的

其他材料上,没有进一步的介绍。我们可以推断,DARAM 的速度要比SARAM 快,SARAM

比SRAM 快,但是电路结构的复杂性、实现的成本也与速度成正比关系,所以,2407 的

片内DARAM只有544个字,SARAM 却有2K字之大。好了,我们不必知道它们的细节,

总线接口、读取方式、写入方式、刷新方式、指标参数,这些是TI 更关心的事,我们只要

记住它们的特点:它们都是RAM 类存储器,掉电要丢失数据的;DARAM 的读写速度最

快,SARAM 次之。我们分配资源的时候要考虑这些特点,量才适用。

#9行至#15行,SECTIONS {……} 部分,就是所谓资源的分配。

首先,SECTIONS,PAGE,包括花括号、冒号,都是关键字符。注意:SECTIONS

字符是复数形式。在花括号内,每一行最左侧的“.vectors” 、“.text” 、“.cinit” 、“.bss” 、

“.stack”这些名称,包括小数点,都是TI 默认的关键字符,只有“.extdata”是用户自

己定义的名称。另外,“VECS”、“PROG” 、“SARAM” 、“B0B1” 、“ExtSRAM”必须是

在MEMORY 里声明过的资源名称。除此以外,有些字符也允许有别的写法,参见

“Assembly Language Tools User's Guide.pdf” ,汇编语言工具指南。

这些东西,就是前文所说,对存储器资源有要求的“状况” !前面声明的存储器资

源,就是要分配给这些“状况”使用的!

初次接触这些名称,一定会一头雾水:这些都是什么东西?从哪里冒出来的?在TI 的《汇编语言工具指南》里,这些名词统称为“directives” ,“指令”的意思,

实际上是针对编译器的“伪指令” ,在芯片的指令集里是找不到这些指令的,不要把二者相

混淆。“.vectors” 、“.text” 、“.cinit” 、“.bss” 、“.stack” ,这些包括小数点的单词,都是TI

规定的关键字(这些定义应当隐含在TI 提供的某个文件中国,比如.lib 库文件),在用户

自己的源程序中,一般不能也不需要对这些关键字做定义或声明,只是去引用它们;但

“.extdata”与这些关键字不同,是由用户自己定义的,下文会进一步说明。每条伪指令,

要求编译器在程序空间或数据空间里,保留指定数量的存储单元,这些存储单元叫做“sections” ,一般翻译为“段” ,与笔者所说的“状况”相对应。大家在提到这些伪指令

名词的时候,有时来代表这些指令,更多的时候是代表它们所对应的段。如果使

用汇编语

言开发DSP,一定要用到这些伪指令,也会对它们有较深刻的理解。

段分为两类:已初始化段(Initialized Sections)和未初始化段(Uninitialized Sections)。所谓“已初始化” ,具有两个特点:a、只要用户程序编写完成,这些“数据”

就已经是可知的、可预期的,是由用户编写的程序代码和编译器共同决定的;b、在系统

运行过程中,这些数据的内容不会发生任何变化,只会被读取,不会被修改,下次再通电,

这些数据依然存在。显然,指令码就属于“已初始化的” ,但“已初始化”并非只包含指令

码,指令码只是“段”的一种而已,一般还会有其他的“段” 。所谓“未初始化” ,就是上

文所说的,“设计师自己也很难确切知道,在某一时刻,这些数据的具体的数值是什么”的

意思,上面提到的变量i 就属于“未初始化的” ,同样地,“未初始化”还包括其他段。这

里的“初始化” ,是从编译器的角度来考虑的,是“可预知、可预期”的意思,并不是我们

通常说的,给某个变量赋予初始值的那个“初始化” 。

当芯片型号不同,甚至用户源程序不同时,编译产生的“段”也是不同的;反之,产生哪些段,是由芯片型号和用户的源程序共同决定的。

那么,我们怎么知道,我的工程项目会产生哪些“段”呢?工程项目在编译之后,会在项目文件夹内产生一个.map 文件,用随便一个文本编辑器就可以打开,内容也很容

易理解。初学者可以先找一个现成的CMD 文件,稍作修改或者不修改,加入项目中进行

编译,如果编译失败(failure或error),则根据提示进行修改,如果只是告警(warning)

则不必理会。成功编译之后,查看.map 文件中“output section”那一列,那些长度

(length)非0 的段,就是你的项目真正会产生的段;那些长度为0 的段,基本都可以从

CMD 文件中删除。有时也存在这样的情况:某些长度为0 的段,即使开发人员并没有在

CMD文件中作出声明,仍然会在.map 文件里出现,这对我们的开发并没有影响。

我们仍然通过前面的CMD 例子,来看这些段都是什么意思,为了方便读者理解,我把说明的顺序调整了一下。另外,开发过MCS51 或其他单片机的人,应当边看边想,

想想单片机的程序,去体会与这些段相对应的东西。

“.text” ,就是编译后生成的二进制指令代码段。我们甚至可以用手工把C 程序或

汇编程序,翻译成二进制指令代码,所以,它显然属于“已初始化的”段。我们编写的

main 主函数,“子”函数或子程序,中断服务函数或程序,它们都会产生指令代码,也都

属于这个段。通过#11 行的声明

.text : > PROG PAGE 0 编译器就知道设计师的意图了,是要把所有的二进制代码,按顺序串行地汇集起来,一起

编入PROG区域,即#4行已经声明的,程序空间PAGE 0的0x0100h ~ 0x7FFF 地址范

围内。每个函数的代码块的首地址,长度等信息,都记录在.map 文件中。至于这些代码

最终写入哪个物理存储器,是片内的FLASH,还是片外扩展的程序SRAM,是由MP/MC

管脚决定的(对于2407芯片),已经不是CMD文件的责任了。

“.vectors” ,表示“中断向量段”,也就是中断服务程序的入口地址段。很显然,

这个段要求物理存储器必须能够掉电保存数据。我们在编写用户程序的时候,普通的函数

完全按照标准C语言的语法,比如void main(void) { …… } ,但所有的硬件中断服务

函数,必须在前面加一个关键字“interrupt” ,比如某个服务函数abc( )是这样写的:interrupt

void abc( ) { …… } 。对于2407,这些还不够,源程序还必须包含一个vectors.asm 文

件,其中的一句声明,把中断服务函数abc ( ) 与具体的硬件中断对应起来:int1: b _abc

有了这些声明,编译器就会把函数abc ( ) 的代码块的首地址,编排到与int1中断对应的

向量中,写入#3行定义的0x0000h ~ 0x0040处,中断向量的地址空间里。这个首地址,

编译器当然是知道的,所以“.vectors”也属于“已初始化的”段。用户如果想知道中断

服务程序的入口地址,只能去查看.map 文件。对于2812,情况基本相同,不同之处是

用C 语句代替vectors.asm 文件:PieVectTable.TINT0 = &abc; 或者PieVectTable.XINT1 = &xint1_int; 之类。

“.cinit” 段,定义比较模糊,有文章解释为“对全局变量和静态变量初始化的常数” 。按笔者理解,我们经常用到的数表,比如七段显示器的代码表、液晶的显示字符代码

表、正弦数表等,都属于这个段。那么,还包括哪些内容呢?笔者也不是很确定。但有一

点是肯定的:它属于“已初始化的”段,必须作为代码,存储在程序空间里,而且必须能

够掉电保存。

“.stack” ,就是我们常说的堆栈,我们根本不可能知道堆栈内部数据的变化情况,

所以,它属于“未初始化的”段,定位在数据空间。在调用函数、保存现场时,一定要用

到这个段,但笔者怀疑,还会有其他的用途,比如用堆栈来批量交换数据。显然,堆栈内

部的数据,没有掉电保存的必要。在上面作为例子的CMD文件中,#1行是用户对堆栈空

间的大小所作的声明,是按照TI 公司规定的语法,200h表示512 个单元;如果用户没有

作出#1行的声明,编译器将按照默认的数量来分配空间。一般来说,如果你无法确定程序

运行究竟需要多大的堆栈,就尽量设置大一点。例子中把整个B0B1 存储器块,都作为堆

栈使用。“.bss” ,定义同样比较模糊,但很容易意会。有文章介绍为“保存全局变量和静

态变量” 。很显然,它属于“未初始化的”段,要定位在数据空间。前面 C 程序例子中,

变量i 就定位在这里。这个段,同样不要求掉电保存数据。

“.extdata” ,是笔者自行定义的段,属于“未初始化的” ,专门用来保存一个20000

个元素的数组xyz[20000] ,数据定位在外扩的SRAM 中,不需要掉电保存。这是TI 为

用户设计的,把某些内容从bss段里分出来,进行特殊定位的方法。具体作法是:a、在CMD文件中作出#15行的声明

.extdata : >ExtSRAM PAGE 1

“extdata”是用户自行定义的名称。

b、在源程序中包含如下的语句:

unsigned int xyz[20000];

#pragma DATA_SECTION (xyz,".extdata")

其中,#pragma、DATA_SECTION和小括号,都是规定的关键字符。

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 将一个软盘的内容复制到另一个软盘。

CMD文件管理

对文件的管理通常只是新建文件,删除文件,查找文件,通过目录将相应的文件归档管理。通常用到最多的还有就是复制粘贴,也有可能的时候只可能想得某个字符串,而不记得是哪个文件,所以在应该的时候也可能会考虑到这种查找方法 说明:这里应用的cmd6.1 1、新建文件一般不是shell的工作,这都是由相应的编辑器去完成的 可以新建目录 创建目录。 MKDIR[drive:]path MD[drive:]path 如果命令扩展被启用,MKDIR会如下改变: 如果需要,MKDIR会在路径中创建中级目录。例如:假设\a不 存在,那么: mkdir\a\b\c\d 与: mkdir\a chdir\a mkdir b chdir b mkdir c chdir c mkdir d 相同。如果扩展被停用,则需要键入mkdir\a\b\c\d。 2、删除文件,这里有两条命令可以使用,请看下面的说明 可以删除一个或数个文件。 DEL[/P][/F][/S][/Q][/A[[:]attributes]]names ERASE[/P][/F][/S][/Q][/A[[:]attributes]]names names指定一个或多个文件或者目录列表。 通配符可用来删除多个文件。 如果指定了一个目录,该目录中的所 有文件都会被删除。 /P删除每一个文件之前提示确认。 /F强制删除只读文件。 /S删除所有子目录中的指定的文件。 /Q安静模式。删除全局通配符时,不要求确认

/A根据属性选择要删除的文件 属性R只读文件S系统文件 H隐藏文件A存档文件 I无内容索引文件L重分析点 -表示“否”的前缀 如果命令扩展被启用,DEL和ERASE更改如下: /S开关的显示句法会颠倒,即只显示已经 删除的文件,而不显示找不到的文件。 删除目录: 删除一个目录。 RMDIR[/S][/Q][drive:]path RD[/S][/Q][drive:]path /S除目录本身外,还将删除指定目录下的所有子目录和 文件。用于删除目录树。 /Q安静模式,带/S删除目录树时不要求确认 3、复制文件,当然复制文件是原来的文件还是存在的,不能对目录一起复制 1、将一份或多份文件复制到另一个位置。 COPY[/D][/V][/N][/Y|/-Y][/Z][/L][/A|/B]source[/A|/B] [+source[/A|/B][+...]][destination[/A|/B]] source指定要复制的文件。 /A表示一个ASCII文本文件。 /B表示一个二进位文件。 /D允许解密要创建的目标文件 destination为新文件指定目录和/或文件名。 /V验证新文件写入是否正确。 /N复制带有非8dot3名称的文件时, 尽可能使用短文件名。 /Y不使用确认是否要覆盖现有目标文件 的提示。 /-Y使用确认是否要覆盖现有目标文件 的提示。 /Z用可重新启动模式复制已联网的文件。 /L如果源是符号链接,请将链接复制 到目标而不是源链接指向的实际文件。

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

第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文件详解

开发 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:保留空 间大小。

CMD语言

ASSOC 显示或修改文件扩展名关联。 ATTRIB 显示或更改文件属性。 BREAK 设置或清除扩展式 CTRL+C 检查。 BOOTCFG 设置 boot.ini 文件的属性以便控制启动加载。 CACLS 显示或修改文件的访问控制列表(ACL)。 CALL 从另一个批处理程序调用这一个。 CD 显示当前目录的名称或将其更改。 CHCP 显示或设置活动代码页数。 CHDIR 显示当前目录的名称或将其更改。 CHKDSK 检查磁盘并显示状态报告。 CHKNTFS 显示或修改启动时间磁盘检查。 CLS 清除屏幕。 CMD 打开另一个 Windows 命令解释程序窗口。 COLOR 设置默认控制台前景和背景颜色。 COMP 比较两个或两套文件的内容。 COMPACT 显示或更改 NTFS 分区上文件的压缩。 CONVERT 将 FAT 卷转换成 NTFS。您不能转换当前驱动器。 COPY 将至少一个文件复制到另一个位置。 DATE 显示或设置日期。 DEL 删除至少一个文件。 DIR 显示一个目录中的文件和子目录。 DISKCOMP 比较两个软盘的内容。 DISKCOPY 将一个软盘的内容复制到另一个软盘。 DISKPART 显示或配置磁盘分区属性。 DOSKEY 编辑命令行、调用 Windows 命令并创建宏。DRIVERQUERY 显示当前设备驱动程序状态和属性。 ECHO 显示消息,或将命令回显打开或关上。 ENDLOCAL 结束批文件中环境更改的本地化。 ERASE 删除一个或多个文件。 EVENTQUERY 显示指定准则的事件日志项目。 EXIT 退出 CMD.EXE 程序(命令解释程序)。 FC 比较两个文件或两个文件集并显示它们之间的不同。 FIND 在一个或多个文件中搜索一个文字字符串。 FINDSTR 在多个文件中搜索字符串。 FOR 为一套文件中的每个文件运行一个指定的命令。 FORMAT 格式化磁盘,以便跟 Windows 使用。 FSUTIL 显示或配置文件系统的属性。 FTYPE 显示或修改用在文件扩展名关联的文件类型。 GOTO 将 Windows 命令解释程序指向批处理程序中某个带标签的行。GPRESULT 显示机器或用户的组策略信息。 GRAFTABL 启用 Windows 在图形模式显示扩展字符集。 HELP 提供 Windows 命令的帮助信息。 IF 在批处理程序中执行有条件的处理过程。 LABEL 创建、更改或删除磁盘的卷标。 MD 创建一个目录。 MKDIR 创建一个目录。 MODE 配置系统设备。 MORE 逐屏显示输出。 MOVE 将一个或多个文件从一个目录移动到另一个目录。

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初始化库前,未初始化的段并没有真实的内容。

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

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()等函数开辟一些动态内存区,这些动态内存区称为堆。

关于CMD文件

DSP的CMD文件写法综述 DSP的存储器的地址范围,CMD是主要是根据那个来编的。 CMD 它是用来分配rom和ram空间用的,告诉链接程序怎样计算地址和分配空间。不同的芯片就有不同大小的rom和ram.放用户程序的地方也不尽相同。所以要根据芯片进行修改.分两部分.MEMORY和SECTIONS。 MEMORY { PAGE 0 .......... PAGE 1......... } SECTIONS {SECTIONS { .vectors ................. .reset ................. ................ } MEMORY是用来指定芯片的rom和ram的大小和划分出几个区间. PAGE 0 对应rom;PAGE 1对应ram PAGE 里包含的区间名字与其后面的参数反映了该区间的起始地址和长度. SECTIONS:(在程序里添加下面的段名如.vectors.用来指定该段名以下,另一个段名以上的程序(属于PAGE0)或数据(属于PAGE1)放到“>”符号后的空间名字所在的地方。 SECTIONS { .vectors : { } > VECS PAGE 0 /* Interrupt vector table */ .reset : { } > VECS PAGE 0 /* Reset code */ ............ ............ .......... } 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

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文件

相关文档