
1、你的平台都有什么存储器资源?
2、哪些存储器安排在程序空间,哪些在数据空间?
3、你的平台会造成什么大“状况”和小“状况”?
4、哪些情况属于程序空间,哪些属于数据空间?
5、程序空间的“状况”如何安排在程序空间的资源里,数据空间的“状况”如何
安排在数据空间的资源里?
笔者想从事情的起源入手,逐步引导初学者自己去发现“资源要分配给谁?有什么
东东应该占用存储器?”这个难题的答案,所以使用了一些不正规的用语,比如“状况”
这个词。
让我们从一个实际使用过的 2407 芯片的 CMD文件来展开说明, 其他 DSP芯片的
CMD文件与此大同小异:
-stack 200h
MEMORY
{
PAGE 0 :
VECS : origin = 0000h ,length = 0040h
PROG : origin = 0100h ,length = 7F00h
PAGE 1 :
B2 : origin = 0060h ,length = 0020h
B0B1 : origin = 0200h ,length = 0200h
SARAM : origin = 0800h , length = 0800h
ExtSRAM : origin = 8000h , length = 8000h
}
SECTIONS
{
.vectors : > VECSPAGE 0
.text :> PROG PAGE 0
.cinit :> PROG PAGE 0
.bss :> SARAM PAGE 1
.stack :> B0B1 PAGE 1
.extdata : > ExtSRAMPAGE 1 }

下图是 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单元开始(Usercode
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 三块存储区.ifly是什么格式,
是 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.ifly是什么格式, 全称 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,一定要用到这些伪指令,也会对他们有较深刻的理解。
段分为两类:已初始化段(InitializedSections)和未初始化段(Uninitialized
Sections) 。所谓“已初始化” ,具有两个特点:a、只要客户程序编写完成,这些“数据”
就早已是可知的、可预期的,是由用户编写的程序代码和编译器共同决定的;b、在系统
运行过程中,这些数据的内容不会发生任何差异,只会被读取,不会被设置,下次再通电,
这些数据仍然存在。显然,指令码就属于“已初始化的” ,但“已初始化”并非只包括指令
码,指令码也是“段”的一种而已,一般都会有其它的“段” 。所谓“未初始化” ,就是上
文所说的, “设计师自己也很难确切了解,在某一时刻,这些数据的详细的数值是哪个”的
意思,上面看到的变量 i 就属于“未初始化的” ,同样地,“未初始化”还包含其它段。这
里的“初始化” ,是从编译器的视角来考量的,是“可预知、可预期”的意思,并不是我们
通常说的,给某个变量赋予初始值的哪个“初始化” 。
当芯片机型不同,甚至用户源程序不同时,编译产生的“段”也是不同的;反之,
产生什么段,是由芯片机型和用户的源程序共同决定的。
那么,我们如何了解,我的工程项目会造成什么“段”呢?工程项目在编译以后,
会在项目文件夹内形成一个 .map 文件,用随意一个文本编辑器就可以开启,内容也很容
易理解。初学者可以先找一个现成的 CMD 文件,稍作修改以及不设置,加入项目中进行
编译,如果编译失败(failure或error) ,则按照提醒进行设置,如果也是告警(warning)
则不必理会。成功编译期间,查看 .map 文件中“outputsection”那一列,那些长度
(length)非 0 的段,就是你的项目真正会造成的段;那些长度为 0 的段,基本都可以从
CMD 文件中删除。有时也存在这种的状况:某些长度为 0 的段,即使开发人员并没有在
CMD文件中做出声明,仍然会在 .map文件里发生,这对我们的开发并没有影响。
我们一直借助上面的 CMD 例子,来看这种段都是什么含义,为了便于读者理解,
我把表明的顺序调整了一下。另外,开发过 MCS51 或其它单片机的人,应当边看边想,
想想单片机的程序,去感受与那些段相对应的东西。
“.text” ,就是编译后生成的二进制指令代码段。我们或者可以用手工把 C 程序或
汇编程序,翻译成二进制指令代码,所以,它虽然属于“已初始化的”段。我们编写的
main 主函数, “子”函数或子程序,中断服务函数或程序,它们就会造成指令代码,也都
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/shouji/article-128052-1.html
今年头发颜色好正常