本篇介绍飞思卡尔MC9S12系列芯片基本内存映射知识,主要是其特有的分页机制。一般的小型项目可能很多人都不会去专门了解这些内容,但是对于大型项目(代码超过16KB 或 内部变量过多超过4KB),势必要在默认设置下修改能适配项目的配置,以便于能灵活使用。另外BootLoader的编写也是要了解这方面的内容才能进行。
MC9S12(X)有2个大的系列,区别是带不带XGATE(有X后缀的是带有XGATE的),XGATE是一个辅核,可以处理中断,不能作为主要业务逻辑处理,也就是说,XGATE只能通过中断触发执行,而不能在main循环中跳入。XGATE的中断处理速度远超S12主核(相同时间内数据自增数值更大),因此某些中断响应可以放在XGATE中,既可以提高处理速度,又能减轻主核负担,XGATE与S12主核共享Flash与RAM,因此需要在共享区域使用前加锁,使用完毕解锁。
以下主要以MC9S12XEP100系列为例,内部P-Flash大小为1MB,RAM为64KB,D-FLASH(模拟EEPROM)大小36KB。如此大的空间,MCU是如何知道去哪个地方找数据呢?当然是通过地址寻找了。但是MC9S12系列所有单片机都是16位,总寻址范围为 2^16 = 65536,也就是64KB,为了解决寻址问题,Freescale提供了分页的概念,通过页地址+页内地址来访问,有点像是将中国分成几十个省,通过省名+省内地址来具体定位到某个特定地址,例如 河北+廊坊(实际上地名比这个复杂,此处仅作范例)。
Freescale将64KB寻址空间分成4段,寄存器段(2KB)、EEPROM段(1*2KB)、RAM段(4*3KB)、Flash段(16*3KB)。
可直接寻址的区域叫做非分页区(Non-Banked);对于不能直接寻址的区域,要通过修改页寄存器值来定位的叫做分页区(Banked),非分页区也可以通过页寄存器设置来访问(但是属于多次一举,相对于直接寻址会浪费时间)。
需要注意的是,分页寄存器的值并非是从0开始。在该块前部分的,从0x00开始往后,在该块后部分的,从0xFF往前。具体与实际Memory Map有关,这个会在后面体现(Global Memory Map 内标注有),EEPROM就分成2大段,中间是断开的,前面从0x00起始,后面的从0xFF往前。
寄存器2KB可以直接覆盖,不需要分页;
EEPROM有36KB,但是分配的寻址范围只有2KB,1KB可以直接访问,1KB作为EEPROM窗口,通过设置EPAGE寄存器的值(36个值,可直接寻址的1KB,也可以在这个窗口内访问,与直接寻址效果相同,只是耗时较长,这1KB一般不在窗口访问),可以在这个窗口中访问到所有36KB内容;
RAM有64KB,2个4KB可直接访问,剩下的(总16,可直接寻址的有2个,实际使用14个)可通过一个4KB窗口访问,通过RPAGE来选择不同的RAM块;
Flash有1MB,2个16KB可直接访问,还有个16KB作为窗口,通过设置PPAGE来选择不同分页区。
以下为实际地址顺序:
0x0000-0x07FF Registers (2KB)
//total 36KB
//total 64KB
//total 1024KB |
通过以上描述,我们对于分页有了一个基本的认识,但是我们发现,RAM、EEPROM、Flash、各自有不同的分页寄存器,使用起来比较麻烦,而且对整个地址空间描述还是不够理想,是否有更好的方法呢?当然有,Freescale早就想到了这一点,因此推出了GPAGE寄存器,统一管理所有空间地址,Global Memory Address。
全局地址分布于两个寄存器的设置有关ROMHM和RAMHM,此处我们不做过多解释,以免大家感到更困惑。这两个寄存器值一般默认即可,无需特别设置。在默认情况下,Global Memory Map如下(需要注意各个寄存器的值,与prm文件配置有关):
默认情况下(ROMHM=0 RAMHM=0)Global Memory Map 如下:
|
Flash及EEPROM读写就是通过全局地址来进行的。
GPAGE并非