在线时间1 小时
UID423748
注册时间2013-3-28
NXP金币0
该用户从未签到
高级会员

- 积分
- 653
- 最后登录
- 2018-12-14
|
发表于 2013-8-7 13:14:44
|
显示全部楼层
回复:关于AC128分页的一个疑问
回复第 6 楼 于2013-08-07 10:06:46发表:
回复第 5 楼 于2013-08-06 18:03:26发表:
你要重点看这段:
_PRESTART, /* startup code */
STARTUP, /* startup data structures */
ROM_VAR, /* constant variables */
STRINGS, /* string literals */
VIRTUAL_TABLE_SEGMENT, /* C++ virtual table segment */
NON_BANKED, /* runtime routines which must not be banked */
DEFAULT_ROM,
COPY /* copy down information: how to initialize
variables */
INTO ROM,ROM1; /* ,ROM1: To use "ROM1" as well,
如果不用pragam指定, 编译器就会把程序放到Default ROM里, 在这段里Default ROM 放在了ROM和ROM1里, ROM和ROM1是非分页的。
所以基本上可以确定你的程序是非分页模式。
后面那些PAGED_ROM并没有用来放程序,除非你在程序中用pragam 强行把程序放进去,但那样程序运行很可能会出错,因为之前编译器已经被指定按非分页模式编码。
在分页模式下,编译器会调用长跳转指令LCALL来实现跳转, 这条指令会自动使用PPAGE的值来计算跳转地址。 而在非分页模式下,编译器会使用JSR或JUMP来跳转,PPAGE的值是不用管的。 设想一下如果在非分页模式下,如果我们把程序放到了PPAGE = 4,第4页的某个位置,比如0x48010, JSR或JUMP跳转的时候只会跳到0x8010, 而不会跳到0x48010. 如果使用LCALL,那CPU就知道是第4页的flash地址。
明白你的意思。但是事实还是让我有很多疑问。确实之前的程序我是采用非分页模式,然后用pragam强行将程序放到PAGED_ROM
中,程序开始是无法运行的。但是后来我仿真看原因是main函数被编译器放到ROM中,而将另外的某个函数我放到了PAGED_0中,
如那段注释所说,这两段地址指向了同一片flash,导致main程序被破坏了。所以,我就在PAGED_ROM中注释掉了PAGE0,程序就可以正常运行了。如果这样可以运行的话,说明编译器并没有忽略PPAGE的值。
我按照你的方法生成了一个新的prm文件
/* This is a linker parameter file for the mc9s08dz128 */
NAMES END /* CodeWarrior will pass all the needed files to the linker by command line. But here you may add your own files too. */
SEGMENTS /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */
Z_RAM = READ_WRITE 0x0080 TO 0x00FF;
RAM = READ_WRITE 0x0100 TO 0x17FF;
RAM1 = READ_WRITE 0x1900 TO 0x217F;
/* unbanked FLASH ROM */
ROM = READ_ONLY 0x4000 TO 0x7FFF;
ROM1 = READ_ONLY 0x2180 TO 0x3BFF;
ROM2 = READ_ONLY 0xC000 TO 0xFF7F;
EEPROM = READ_ONLY 0x3C00 TO 0x3FFF;
/* INTVECTS = READ_ONLY 0xFF80 TO 0xFFFF; Reserved for Interrupt Vectors */
/* banked FLASH ROM */
PPAGE_0 = READ_ONLY 0x008000 TO 0x00A17F; /* PAGE partially contained in ROM segment */
PPAGE_0_1 = READ_ONLY 0x00BC00 TO 0x00BFFF;
PPAGE_2 = READ_ONLY 0x028000 TO 0x02BFFF;
PPAGE_4 = READ_ONLY 0x048000 TO 0x04BFFF;
PPAGE_5 = READ_ONLY 0x058000 TO 0x05BFFF;
PPAGE_6 = READ_ONLY 0x068000 TO 0x06BFFF;
PPAGE_7 = READ_ONLY 0x078000 TO 0x07BFFF;
/* PPAGE_1 = READ_ONLY 0x018000 TO 0x01BFFF; PAGE already contained in segment at 0x4000-0x7FFF */
/* PPAGE_3 = READ_ONLY 0x038000 TO 0x03BFFF; PAGE already contained in segment at 0xC000-0xFFFF */
END
PLACEMENT /* Here all predefined and user segments are placed into the SEGMENTS defined above. */
DEFAULT_RAM, /* non-zero page variables */
INTO RAM,RAM1;
_PRESTART, /* startup code */
STARTUP, /* startup data structures */
ROM_VAR, /* constant variables */
STRINGS, /* string literals */
VIRTUAL_TABLE_SEGMENT, /* C++ virtual table segment */
NON_BANKED, /* runtime routines which must not be banked */
COPY /* copy down information: how to initialize variables */
INTO ROM; /* ,ROM1,ROM2: To use "ROM1,ROM2" as well, pass the option -OnB=b to the compiler */
DEFAULT_ROM, PAGED_ROM /* routines which can be banked */
INTO PPAGE_0,PPAGE_0_1,PPAGE_2,PPAGE_4,PPAGE_5,PPAGE_6,PPAGE_7,ROM1,ROM2;
_DATA_ZEROPAGE, /* zero page variables */
MY_ZEROPAGE INTO Z_RAM;
END
STACKSIZE 0x200
VECTOR 0 _Startup /* Reset vector: this is the default entry point for an application. */
我观察了一下,发现区别就在于将DEFAULT_ROM换了位置。就如你前面所说,编译器默认的位置变了。这个效果和我用pragram
来选择存放位置效果一样。
同时/* PAGE partially contained in ROM segment */仍然存在,是不是我在ROM和PAGE0中同时存放程序仍然会出错?
注释中说的部分地址,具体是哪些地址?手册中有说到吗?在那一页?
还有一个问题,在这种分页的MCU中,是不是一定要将中断服务函数放到非分页区?因为我之前用XEP100时,就一定要这么做,
否则编译器都会报错的。
请查看an3730.
另外中断向量是16位地址 要放在非分页区,否则会出错 |
|