对于用MCU的人来讲,不必定要明白HCS12(x) memory map的机制和联系。由于若是没有系统地学习操做系统和编译原理之类的课程,确实有些难度。而且,对于DG128 XS128这样的MCU,默认的memory分配方式已经够用了。从这个意义上讲,搞清楚memory map彷佛没必要要。
编程
可是,你有没有RAM不够用的状况?有没有想定义变量到FLASH ROM的状况?有没有由于欲提升寻址效率而定义变量到非分页区的状况?有没有写EEPROM但没写成功的状况?
飞思卡尔的memory很是灵活,经过地址映射来提升效率是芯片制造商的一惯做风(固然,首先这个CPU要有这种寻址和内存映射转换机制),可是,纵观HCS12(x) memory map的东西,真是作到极限了。用我之前的话讲是,用有限的资源得到无限的好处了。看看DG128,64K的逻辑空间,映射以后RAM EEPROM FALSH ROM,均可以充分发挥做用,并且扩展FLASH也方便。而XS128更高级一筹,有专门的MMC管理HCS12(x) memory map。
我大致上了解这两个片子的HCS12(x) memory map,所以就此谈谈理解和见解,若有错误,请你们不吝指出
首先,说说6个概念。
1 memory map 地址映射,不要理解成内存映射,内存是RAM。
2 为何要映射?由于CPU的寻址是对物理地址操做,可是单片机的RESET以后只有相对地址。相对地址,我理解为是一块一块的,不是连断的。相对地址,顾名思义,是个相对的,没有映射以前,CPU是找不到他的,也用不了相对地址的数据。 粘一句百度上的解释:为了保证CPU执行指令时可正确访问存储单元,需将用户程序中的逻辑地址转换为运行时由机器直接寻址的物理地址,这一过程称为地址映射。
3 RAM,这个很少说,是存变量和栈的东西,高速,掉电即失。
4 EEPROM,这个是一种特别的FLASH。通常用来保存少许数据,掉电不会丢失。FLASH也是非易失的,SD卡就是一种FLASH。EEPROM和普通FLASH的区别,在于读写时的字节操做上。这个我基本上没有体会,由于是至关底层的东西。
5 FLASH和ROM,在HCS12(X)里,建议把FLASH和ROM等同起来理解。你们的程序就是放在这里面的。还有一个const变量和中断向量也是存在这里面的。ROM可能有个误区,只能读不能写,一次性的,不错。可是,有加个前提,应该是可控的ROM。
6 还有一个重要的register 空间,这个是存放I/0地址和单片机可编程寄存器的空间,是厂家定义的。在头文件里能够看到。如extern volatile PORTABSTR _PORTAB @(REG_BASE + 0x00000000)就是典型的register 空间映射。
我把memory map理解成为3个内容:一个是映射管理,一个是分页机制,一个是寻址的问题。映射管理,就是单片机RESET以后,逻辑地址和物理地址之间的关系。分页机制的产生主要因为16位寻址能力有限,须要分页解决,另外在虚拟内存管理上能够得到更多的优点。 至于,CPU寻址的问题,这个就不深纠了。
此次以DG128的为例,XS128的稍复杂一些。理解了DG128的,XS128的问题就不大。
先说一说映射管理:DG128里经过设置INITRG、INITRM、INITEE来实现映射。具体的设置看DS吧。默认状况下:register 空间映射到0X0000到0x03FF,这个优先级最高。RAM空间映射到0x0400-0X1FFF,看到没有,实际上只有7K,也就是说能用的RAM只有7K。可是,DG128的RAM有8K的逻辑空间啊。因此,能够改INITRG、INITRM、INITEE重映射以提升RAM的实际可用空间。怎么改,看须要了。WJ在这里逻嗦一句,能够看看PE是怎么改的。而FLASH映射了3个,有两个非分页地址0x4000-0x7FFF和0xC000-0xFEFF。还有一个分页地址,这一个分页地址有6个页面。6个页面占用一个分页窗,用一个逻辑空间,如何让这6个页面协做工做并让CPU能找到他们呢?
这就是分页管理机制的内容。这6个页面分别是:
PAGE_38 = READ_ONLY 0x388000 TO 0x38BFFF;
PAGE_39 = READ_ONLY 0x398000 TO 0x39BFFF;
PAGE_3A = READ_ONLY 0x3A8000 TO 0x3ABFFF;
PAGE_3B = READ_ONLY 0x3B8000 TO 0x3BBFFF;
PAGE_3C = READ_ONLY 0x3C8000 TO 0x3CBFFF;
PAGE_3D = READ_ONLY 0x3D8000 TO 0x3DBFFF;
上面说的你们能够新建一个DG128工程,到PRM文件里看。
再看看分页管理机制:DG128里只有FLASH空间能够分页,而XS128里,分页的东西太多了。DG128里FLASH分页是经过PPAGE寄存器搞定的。PPAGE是5位寄存器,CPU12内核规位每页只能有16KB。所以DG128的FLASH寻址空间就是2^5*16KB=512KB了。
中断函数为何要加:#pragma CODE_SEG __NEAR_SEG NON_BANKED 这个声明?这个声明是干什么用的?
这要仍是要从FLASH分页和非分页的区别提及。
下面详细说一说,FLASH里非分页和分页的使用。 要明白一点,分页是不可见的,要用的时候PPAGE参与寻址。
1 FLASH里非分页工做机制
FLASH一共为128K,一页是16K,那么应该有8页才是,可是实际只有6个分页。有2个非分页放在4000-7FFF,和C000-FFFF两个逻辑地址窗里。那么,当程序的寻址在64K以内(2^16=64K,16位机的寻址能力是64K)时,就不用分页了,直接使用那两个非分页的数据。实际上,3E页 3F页是可见的,其实他们就是那2个非分页的映射。所以,使用非分页FLASH,就不须设置PPAGE寄存器,直接使用逻辑地址便可。见图1。
这点咱们能够从如下看出:
/* non-paged FLASHs */
ROM_4000 = READ_ONLY 0x4000 TO 0x7FFF;
ROM_C000 = READ_ONLY 0xC000 TO 0xFEFF;
PLACEMENT
NON_BANKED, INTO ROM_C000/*, ROM_4000*/;
很直观地看出,把这两个能够直接使用逻辑地址的页面设为NON_BANKED, 那么中断函数放在NON_BANKED里,就能够把函数放在64K的寻址程序段中。这么一来,进中断就方便多了,效率也高不少。这就是对本文开篇的解释。
你们记住这一点,在XS128里也有相似的一招。
2 FLASH里分页工做机制
好了,上面是3E页 3F页是可见的分页区,还有3D 3C 3B 3A 39 38不可见的分页区。当你的程序要寻址64K之外的空间,即不是是可见的3E页 3F页时,就要涉及分页了。
PPAGE是MMC模块的东西,我搞了个图片你们看看,如图2。每一页在DG128中的逻辑地址都是由PPAGE中的页号和重叠窗口内地址组成的24位绝对地址。经过设置寄存器PPAGE,可使用所有的FLASH空间。例如:程序要将数据存入$3D页,设置PPAGE的值为$3D,那么逻辑地址范围说是$3D8000-$3DBFFF。有一点要注意:为了分页描述的完整性,能够以下理解:对于3E页 3F页有两个逻辑地址映射到物理地址。拿3E页来讲,有$004000-$007FFF和$3E8000-$3EBFFF。
对于程序是如何寻址,这个是内核的东西,你们能够看看CPU这个文档。
经过分析,相信你们知道地址这个东西是很是有用的吧。下次说说XS128,XS128的RAM FLASH EEPROM均可以分页。更高级,更主动,编程弹性更大。
图1
了解XS128的MEMORY map和core,对充分榨取他的现有资源,合理分配RAM颇有帮助。上次讨论到cpu12内核的DG系列单片机,基本上该涉及的东西都有所说起。包括:
1 MEMORY map的缘由,为何要搞这个概念出来。
2 MEMORY map包含的内容,有那三点...
3 一些相关的概念性的东西。
若是不明白,看看前面几篇文章就会明白一些的。
此次再补充三个概念,但愿能引发你们的注意和进一步讨论:
1 在PRM里设置了映射以后,怎么把程序或变量放在那个地址区呢?好比:我就想把int a;这个a分配到未分页的RAM1区,怎么办?
这个说来话太长。
简单地说用:#pragma DATA_SEG [xxxx] <segment_name>。若是没有#pragma DATA_SEG,全局变量将会被放到DEFAULT_RAM段中。固然,若是这个变量频率引用的话,放在非分页RAM1区能够提升他的读取效率,毕竟他不须要RPAGE参与寻址,是near寻址,而不是far,用简单的指令就能够搞定。
一样,若是反复调用一个函数,把这个函数放在非分页flash里也有异曲同同之妙。
关于这个问题的详细讨论,张教主有一篇文章,还有一个DP512的PPT都有讲解。你们能够网上下载看看,若是须要,也能够向我email要.
2 建程序里的SAMLL BANKED LARGE是什么做用?
SMALL平面的64K的地址空间。全部的函数都是near。BANKED采用分页地址。全部的用户的函数都被默认为far。far类型的数据指针能够在SMALL和BANKED中使用LARGE, 默认为数据和代码均为分页模式。全部的函数和数据指针都是far类型。这种内存模型运行时间比较长,所以不多使用.用LARGE基本上浪费了16位机寻址64K的优点。
所以,用SMALL和BANKED模式的较多。你们能够看看建工程时SMALL和BANKED模式下有什么不一样?映射是同样的,只是DEFAULT_ROM和NON_BANKED有无分开的区别。
3 分页明白了,可是分页映射以后怎么用分页里面的数据?
好比 const int a;我把他放在PAGE_3C里面,我如何经过计算PPAGE找到这个a呢?
咱们用C语言的过程当中,把这些东西都忽略了,这个是内核的东西。简单地说,由于内核会自动调用不一样的指令去把你C语言译成机器码。机器码就指令集的表示了。所以,内核的先进性和编译优化过程让你不要管了了。
这样说是由于,随后的博文里将更进一步讨论XS128的memory部分。xs128有128KP-FLASH(ROM) 8KRAM 8KD-FLASH( EEPROM) ,有某些分页用不到,好比RAM分页,由于逻辑地址是$2000-$4000,有8K空间,无需分页。可是大一点的RAM的话,就必需要分页了。这么多分页(还有FLASH确定是要分页了,不分页程序就装不
下去),怎么管理呢?总得有个东西来统筹一下吧.