在上一篇文章中我们做了对HC9S12系列单片机存储空间的划分,但是相比于整个bootloader的工作而言,这只是非常基础的一步,有很多基础的概念在上一篇的操作中我们并没有涉及到。比如较复杂单片机中单片机的存储空间到底是什么样的,具体怎么用C语言对它进行寻址。因为我们单片机的存储空间一般由如下的构成,RAM,ROM以及EEPROM等等。比如在我在本篇中举例介绍的9S12G128单片机,它的RAM空间有8KB,EEPROM有4KB,FLASH有128KB。如何将这几个存储空间合理的组织起来想必单片机的厂商花费了很大的精力,但是对于我们,我们只需要只要他们的结构是什么样的,如何去使用这些空间就足够了。
首先先要复习一下RAM, EEPROM, FLASH的简单概念。RAM是机器运行时的内存,单片机运行时可读可写,但是断电后所有数据都会丢失。EEPROM是电擦除的可编程存储,单片机运行时可以读可以写,断电后数据不丢失。由于存储空间小而且读取速度快,因此一般作为数据存储器。有很多程序运行时得到的参数希望下次重启后还能够再被使用,还有一些程序调试时的参数我们都可以将它们放在数据存储器,方便程序参数的修改与保存,因此一般也将EEPROM称作D-Flash。Flash也是电擦除的存储设备,单片机运行时可读可写,断电后数据不丢失,存储空间大,但读取速度相对较慢,一般作为程序存储器也称作P-Flash。但EEPROM与Flash比较还有就是一次擦写或者写入的数据量大小,一般EEPROM可以字节擦写与写入,但Flash是字段写入与块擦除。当然了,对于单片机存储程序的开发,我们没有必要涉及到Flash与EEPROM具体的写入擦除控制,在存储媒介上一般都做好了相关的接口,类似于HCS12VR系列的单片机,如图所示是该系列下的Flash存储器的接口架构。对Flash的控制只需要通过操作该Flash的控制器即可,在图中的架构下,操作Flash只是设置好Flash控制器的操作时钟,向单片机的相应寄存器按照命令的要求写入相关数据即可。EEPROM的操作也是同理。
除了基本的存储器的知识外,HCS12的存储空间的结构也是理解的关键。 要理解存储结构,首先需要分清S12系列的逻辑地址与全局地址。所谓逻辑地址,就是单片机在运行时只要不涉及到显式的对存储器进行读写的地址都是逻辑地址,比如程序运行时每条指令存放的位置,在内存中数据的位置,只要不涉及到对存储器内容的显式编写,通通都是逻辑地址。而逻辑地址的必要性也十分明显,那就是相对于几百KB甚至几MB的存储器,地址总线只有16bits,也就是CPU能直接寻址得到的地址只有64KB。为保证程序运行时地址的一致性,就将程序的各个存储器地址分别映射到这64KB中,每次我只需要通过这64KB就可以访问整个内存空间了(当然还有几个寄存器的帮助才行,但这也总好过直接对存储器进行操作了,这样的话也单片机的设计也太不友好了)。前面的逻辑地址实际上可能会将相同物理媒介的地址分块映射,但是全局地址基本上就可以理解为将各种存储空间都统一进行一个编排,比如说将RAM放在一块,EEPROM放在一块,Flash放在一块。可是,这些不同的物理存储器在全局地址的角度看来都有统一的存储格式,典型的S12系列内存映射图如下图所示:
这张图乍一看还是有点懵逼的,我这就带你来理解理解。首先左边就是逻辑地址的排布,逻辑地址就是正常运行时的地址,要是不做到Flash擦写或者EEPROM的擦写,你基本上不会用到全局地址。我们一般程序空间中使用的都是逻辑地址。注意:这里还没有提到全局地址,所以说到的也都是逻辑地址。逻辑地址本身是其他存储器的地址为了方便地址总线直接进行寻址,映射成64KB的地址的。上图所示的逻辑地址起始于0x0000-0xFFFF共64KB。由于寄存器也映射到逻辑地址,而且访问速度最快,逻辑地址0x0000-0x03FFF(共1KB, 如果需要16进制计算器,windows自带计算器的程序员模式就好)如上图为寄存器空间。这里注意,图中的寄存器区结束不是0x0400,此地址已经是下一块的起始地址了。寄存器的逻辑地址表在manual reference中都有,可以很方便的查看。从上图中类似的,我们可以读到,给EEPROM的逻辑地址为0x0400-0x05FF (512 B), RAM的逻辑地址为0x3800-0x3FFF(512B),ROM的逻辑地址为:0x0600-0x37FF(12KB), 0x4000-0x7FFF(16KB),0xC000-0xFFFF,以及有点特殊的0x8000-0xBFFF,可见ROM的逻辑地址已经被分成了好几块。
而全局地址就是右边的了,它将所有存储的空间从0开始一直顺序编码。在右侧我们可以看到,由于统一编码,所以相比较而言就多了四个二进制位来表示。全局地址自0x0_0000-0x3_FFFF(256KB)(这样的编码只是为了将高位分开,实际上0x0_0000就是0x00000,0x3_FFFF就是0x3FFFF)。很显然,这个地址空间完全可以将此单片机的所有物理存储统一编址从而方便对于物理存储空间的定位。从图上,我们也可以看到,寄存器的全局地址为0x0_0000-0x0_03FF(1KB),EEPROM与RAM的全局地址共享0x0_0400-0x0_3FFF(15KB),0x3_0000-0x3-FFFF(64KB)为FLASH 的全局地址。至于中间的那部分全局地址用来做什么,目前可以理解为未分配,在此系列单片机中,没有该全局地址对应的物理存储,所以地址都是无效的。
了解了逻辑地址与全局地址的基本概念后,就要说一下全局地址与逻辑地址是什么关系了。在此之前,就要说一下分页存储的概念了,由于一般而言地址总线不过16位或者8位。因此需要将存储空间较大的Flash像我们的书本一样分成一页一页的,通过页码来索引究竟是那一块存储空间。我们逻辑地址的0x8000到0xBFFF就是负责这样的一个映射作用,通过一个PPAGE寄存器来记录是存储器上的哪一页,再通过0x8000-0xBFFF间的逻辑地址来索引具体的存储内容。在上图右边,Flash的全局地址按16KB为一页分成0xC, 0xD, 0xE与0xF的四页, 这个页码就是PPAGE寄存器的内容。从图中我们可以理一下逻辑地址与全局地址的关联:
逻辑地址范围 全局地址范围
PPAGE: 0xC 0x8000 - 0xCFFF 0x3_0000 - 0x3_3FFF
PPAGE: 0xD 0x8000 - 0xCFFF 0x3_4000 - 0x3_7FFF
其余的页面也都是如此,这里再次重申一下,只有专门读写存储器的时候才会使用全局地址,一般情况下指令跳转,内存中指针读取数据,通通都是逻辑地址。希望大家在操作的时候能够分清楚。Flash中的数据,通过逻辑地址寻址时只能读取,只有编写Flash的擦除写入程序才能读写。
这里也再总结一些本篇文档的内容:
1. 理解逻辑地址与全局地址在HC9S12系列单片机中的具体操作
2. 理解逻辑地址与全局地址的对应关系,分页地址的应用
在有了这些基本的存储概念后,我们才能能正式的进入内存中程序的跳转,Flash的擦写等工作中来。
(未完待续)
注: 本系列文章均为原创,如有转载引用请标明来源
原文地址:https://www.cnblogs.com/15821216114sw/p/9255873.html