|
<><BR>通过项目模板建立的新项目中都有一个名字为project.prm的文件,位于图1-8<BR>所示项目文件列表的Linker Files一栏。一个标准的prm文件起始内容如下:<BR>例4.1 prm 文件内容实例<BR>/* This is a linker parameter file for the AW32 */<BR>NAMES END /* CodeWarrior will pass all the needed files to the linker by command line. But here you may add your own<BR>files too. */<BR>SEGMENTS /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */<BR>ROM = READ_ONLY 0x8000 TO 0xFFAF;<BR>Z_RAM = READ_WRITE 0x0070 TO 0x00FF;<BR>RAM = READ_WRITE 0x0100 TO 0x086F;<BR>ROM1 = READ_ONLY 0xFFC0 TO 0xFFCB;<BR>END<BR>PLACEMENT /* Here all predefined and user segments are placed into the SEGMENTS defined above. */<BR>DEFAULT_RAM INTO RAM;<BR>DEFAULT_ROM, ROM_VAR, STRINGS INTO ROM;<BR>_DATA_ZEROPAGE, MY_ZEROPAGE INTO Z_RAM;<BR>END<BR>STACKSIZE 0x50<BR>VECTOR 0 _Startup /* Reset vector: this is the default entry point for an application. */<BR>4.1 prm 文件组成结构<BR>按所含的信息prm 文件有五个组成部分构成:<BR> NAMES END部分用以指定在连接时加入除本项目文件列表之外的额<BR>外的目标代码模块文件,这些文件都是事先经C 编译器或汇编器编译好的<BR>机器码目标文件而不是源代码文件。不过这种用法比较少见,因为我们可<BR>以在图1-8 所示项目文件列表的Libs一栏中添加这些目标代码文件来<BR>实现同样的任务,而且由项目列表管理这些模块文件比较直观方便。<BR> SEGMENTS END部分定义和划分芯片所有可用的内存资源,包括程<BR>序空间和数据空间。一般我们将程序空间定义成ROM,把数据空间划<BR>分成第0 页的Z_RAM和普通区域的RAM,但实际上这些名字都不<BR>是系统保留的关键词,可以由用户随意修改。用户也可以把内存空间按地<BR>址和属性随意分割成大小不同的块,每块可以自由命名。关于内存划分的<BR>具体方法在后面详解。<BR> PLACEMENT END部分将指派源程序中所定义的各种段,例如数据<BR>段DATA_SEG、CONST_SEG 和代码段CODE_SEG 被具体放置到哪一个内<BR>存块中。它是将源程序中的定义描述和实际物理内存挂钩的桥梁。<BR> STACKSIZE定义系统堆栈长度,其后给出的长度字节数可以根据实际<BR>应用需要进行修改。堆栈的实际定位取决于RAM 内存的划分和使用情况。</P><P>在常见的RAM 线性划分变量连续分配的情况下,堆栈将紧挨在用户所定义<BR>的所有变量区域的高端。但如果你将RAM 区分成几个不同的块,请确保其<BR>中至少有一个块能容纳已经定义的堆栈长度。<BR> VECTOR定义所有矢量入口地址。模板在生成prm 文件时已经定义了<BR>复位矢量的入口地址。对于各类中断矢量用户必须自己按矢量编号和中断<BR>服务函数名相关联,请参考3.4.2 中代码范例。如果中断函数的定义是用<BR>interrupt加上矢量号,则无需在这里重复定义。<BR>prm 文件中可以添加注释,语法和C语言相同,可以是/*
*/或//。<BR>4.2 内存划分的具体方式<BR>由SEGMENTS开始到END为止,中间可以添加任意多行内存划分的定义,<BR>每一行用分号;结尾。定义行的语法型式为:<BR>[块名] = [属性] [起始地址 ] TO [结束地址];<BR>其中,<BR> 块名的定义和C 语言变量定义相同,是以英文字母开头的一个字符<BR>串。<BR> 属性可以有三种不同的类型。对于只读的Flash-ROM 区属性一定是<BR>READ_ONLY,对于可读写的RAM 区属性可以是READ_WRITE,<BR>也可以是NO_INIT。它们两者的关键区别是ANSI-C 的初始化代码会<BR>把定位在READ_WRITE块中的所有全局和静态变量自动清零,而<BR>NO_INIT块中的变量将不会被自动清零。对于单片机系统,变量在复<BR>位时不被自动清零这一特性有时是很关键的。<BR> 起始地址和结束地址决定了一内存块的物理位置,用16进制表示。<BR>下面举几个例子来进一步说明:<BR>例4.2 划分Flash-ROM 区,定义512 字节EEPROM 模拟区<BR>SEGMENTS<BR>EEPROM = READ_ONLY 0x8000 TO 0x81FF;<BR>ROM = READ_ONLY 0x8200 TO 0xFFAF;<BR>Z_RAM = READ_WRITE 0x0070 TO 0x00FF;<BR>RAM = READ_WRITE 0x0100 TO 0x086F;<BR>END<BR>例4.3 划分RAM 区,定义16 字节非自动清零的数据保留区<BR>SEGMENTS<BR>ROM = READ_ONLY 0x8000 TO 0xFFAF;<BR>Z_RAM = READ_WRITE 0x0070 TO 0x00FF;<BR>RAM_KEEP = NO_INIT 0x0100 TO 0x010F;<BR>RAM = READ_WRITE 0x0110 TO 0x086F;<BR>END</P><P>PLACEMENT - END内所描述的信息是告诉连接器源程序中所定义的各类段<BR>应该被具体放置到哪一个内存块中去。其语法型式为:<BR>[段名1], [段名2],... [段名n] INTO [内存块名];<BR>其中<BR> 段名就是在源程序中用#pragma声明的数据段、常数段或代码段的名<BR>字。如果用缺省名 DEFAULT , 则默认的数据段名为<BR>DEFAULT_RAM,代码段和常数段名为DEFAULT_ROM。若程序中<BR>定义的段名没有在PLACEMENT 中提及,则将被视同为DEFAULT。几个相<BR>同性质但不同名字的段可以被放置到同一个内存块中,相互之间用逗号<BR>,分隔。<BR> INTO 是系统保留的关键词,在这里为放入的意思。<BR> 内存块名就是前面介绍的用SEGMENTS划分好的不同的内存块名字。<BR>利用这样直观的定位描述文本可以方便灵活的将你的数据或代码定位到芯片内存任<BR>意可能的位置,实现某些特殊目的的应用。下面举几个例子,注意各种段名、<BR>PLACEMENT 和SEGMENTS 之间的对应关系。<BR>例4.4 定义并保留512 字节Flash 字节作为EEPROM 模拟<BR>//prm 文件SEGMENTS 定义:<BR>SEGMENTS<BR>EEPROM = READ_ONLY 0x8000 TO 0x81FF;<BR>ROM = READ_ONLY 0x8200 TO 0xFFAF;<BR>Z_RAM = READ_WRITE 0x0070 TO 0x00FF;<BR>RAM = READ_WRITE 0x0100 TO 0x086F;<BR>END<BR>//prm 文件PLACEMENT 定义:<BR>PLACEMENT<BR>DEFAULT_RAM INTO RAM;<BR>DEFAULT_ROM, ROM_VAR, STRINGS INTO ROM;<BR>_DATA_ZEROPAGE, MY_ZEROPAGE INTO Z_RAM;<BR>EE_DATA INTO EEPROM;<BR>END<BR>//源程序编写:<BR>#pragma CONST_SEG EE_DATA<BR>const byte eeDataBuff[512]="123456";</P><P>张明峰 2007年10月 于上海<BR>例4.5 将不同的代码段分别放置于不同的程序区<BR>//prm 文件SEGMENTS 定义:<BR>SEGMENTS<BR>BOOT_SECTOR = READ_ONLY 0x8000 TO 0x87FF; //2KB 作为加载引导专用区<BR>ROM = READ_ONLY 0x8800 TO 0xFFAF;<BR>Z_RAM = READ_WRITE 0x0070 TO 0x00FF;<BR>RAM = READ_WRITE 0x0100 TO 0x086F;<BR>END<BR>//prm 文件PLACEMENT 定义:<BR>PLACEMENT<BR>DEFAULT_RAM INTO RAM;<BR>DEFAULT_ROM, ROM_VAR, STRINGS INTO ROM;<BR>_DATA_ZEROPAGE, MY_ZEROPAGE INTO Z_RAM;<BR>BOOT_LOADER INTO BOOT_SECTOR;<BR>END<BR>//源程序编写:<BR>#pragma CODE_SEG BOOT_LOADER //定义专用的加载引导代码段<BR>void CodeLoader(void)<BR>{<BR>...<BR>}<BR>#pragma CODE_SEG DEFAULT //普通代码段<BR>void main(void)<BR>{<BR>...<BR>}<BR>例4.6 定义非自动清零的数据段<BR>//prm 文件SEGMENTS 定义:<BR>SEGMENTS<BR>ROM = READ_ONLY 0x8000 TO 0xFFAF;<BR>Z_RAM = READ_WRITE 0x0070 TO 0x00FF;<BR>RAM_KEEP = NO_INIT 0x0100 TO 0x011F; //32 字节非自动清零数据段<BR>RAM = READ_WRITE 0x0120 TO 0x086F;<BR>END<BR>//prm 文件PLACEMENT 定义:<BR>PLACEMENT<BR>DEFAULT_RAM INTO RAM;<BR>DEFAULT_ROM, ROM_VAR, STRINGS INTO ROM;<BR>_DATA_ZEROPAGE, MY_ZEROPAGE INTO Z_RAM;<BR>DATA_PERSISTENT INTO RAM_KEEP;<BR>END<BR>//源程序编写:<BR>#pragma DATA_SEG DATA_PERSISTENT //定义复位时非自定清零数据段<BR>byte sysState;<BR>word pulseCounter;</P><P> </P> |
|