分享

MC9S12HY64局部地址、全局地址与逻辑地址的理解

 堆泄露栈溢出 2018-05-13
    一直以来被S12HY64的局部地址与全局地址的对应关系所困扰,今天通过看Datasheet貌似有了进一步的理解,记录下来以备参考,当然这些理解也不一定都对。
    S12系列单片机总线宽度为16位,从总线宽度来看其最大寻址空间为2^16=64KB,但是这个系列的单片机最大有256KB全局地址空间,那么是如何用16位的总线寻址这么大的地址空间呢?这里就涉及到局部地址和全局地址的概念了。所谓的局部地址可以理解为寻址寄存器的值(例如51单片机的程序计数器PC是用于ROM寻址的寄存器),范围为0x0000~0xffff,共64KB;全局地址包括RAM、DFlash、PFlash、寄存器等所占用的地址空间,范围为0x0000~0x3ffff,共256KB。
    S12的全局地址分为所谓的Paged Address和Unpaged Address,即通过页映射访问的和非页映射访问的。先拿比较容易理解的Unpaged Address来说,例如寻址寄存器的值处于0x4000~0x7fff范围时,等同访问全局地址0x34000~0x37fff中的某个字节,也就是说对于Unpaged Address,局部地址的某个固定范围是和全局地址的某个固定范围是对应的。下面说下比较复杂一点的Paged Address是如何访问到的。
    对于Paged Address,则需要通过页映射的方式来访问了,这里涉及到全局地址的页的概念页映射寄存器PPAGE局部地址中用于页映射的地址范围0x8000~0xbfff。全局地址最大可达256KB,分为16个Page,每个Page的大小为16KB,页号为0x00~0x0f(当然对于PFlash较小的单片机,全局地址的某些范围是无法访问的,通俗理解就是S12单片机的全局地址范围是0x0000~0x3ffff,根据PFlash的大小适当将其放置于全局地址的某些范围中。这里特别注意的是并不是PFlash的放置一定是从低地址开始的,有可能是从高地址开始放置的,例如HY64就是从高地址开始放置PFlash,占用了页号为0x0c~0x0f的地址空间)。全局地址中页号为0x02~0x0b的PFlash页是需要通过页映射的方式来访问的。寄存器PPAGE用于设置需要访问的页号,例如设置PPAGE的值为0x02,则说明要访问的是全局地址中的页号0x02。举个例子,若寻址寄存器的值为0x8000,PPAGE的值为0x02,说明访问的全局地址是0x02 * 16K + (0x8000 - 0x8000) = 0x8000,通俗理解就是此时局部地址范围0x8000~0xbfff与页号为0x02的全局地址范围是对应的。如果把局部地址0x8000看做用于页映射的基地址LOCAL_BASE_ADDR_FOR_PAGE,寻址寄存器的值为LOCAL_ADDR,PPAGE寄存器的值为PPAGE_VALUE(不为0),则要访问的全局地址是PPAGE_VALUE * 16K + (LOCAL_ADDR - LOCAL_BASE_ADDR_FOR_PAGE)
    以上简要说了局部地址与全局地址的关系,其实CodeWarrior用于链接设置的Project.prm文件中还涉及到逻辑地址(暂且叫逻辑地址)的概念。全局地址最大为0x37fff,用18个BIT就可以表示出来,但是若看一下Project.prm文件中的地址,发现有些值已经超过了0x37fff,例如HY64 Project.prm中页号为0x0c的地址范围为0x0C8000 TO 0x0C93FF,可见其值已经超过了0x37fff,这是什么鬼?其实这就是所谓的逻辑地址表示方法,拿0x0c8000来说,8000表示寻址寄存器的值,0x0c表示页号。逻辑地址就是把Paged Address表示成页号+(页内偏移量+LOCAL_BASE_ADDR_FOR_PAGE)的形式。
    为了不至于将局部地址、全局地址、逻辑地址的概念相混淆,可以这样理解:局部地址是寻址寄存器可以访问的地址(受总线位数限制),但是通过Paged和Unpaged两种映射方式可以访问到全部全局地址;逻辑地址只是编译器使用的用于链接设置的,我们在编程时较少使用(若遇到使用逻辑地址的情况将扩充这一部分内容,例如在开发BootLoader时)。
    

 

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多