低内存芯片的软件MMU方案

在51单片机编程中,经常出现内存不够用的情况。但是如果使用它的外扩RAM,又必须占用很多引脚,且接线复杂。如何用少量的引脚,对51单片机进行存储器扩展呢?

首先我们可以接一个IIC的EEPROM或者Flash等其他的串口存储器。但光是这样,并不能较好的解决问题:因为这种存储器无法当做RAM使用。一般只适合存储一些参数,文件之类的。所以我们还需要继续做一些研究。

我们知道,51单片机RAM是128Bytes.有的芯片是256Bytes.大了一点点,但终究是杯水车薪。我们可以外接一个1M的Flash存储器。然后,在51内部设计一个虚拟的地址范围,比如address = 0~1M。当address=0~255时,可以直接访问RAM。但是如果address超过了RAM范围,如address = 256,257,怎么办?

当address=256时,我们可以把当前的RAM所有数据保存到Flash存储器的指定区间。然后,又从Flash的另一个指定区间读取256字节的数据,覆盖RAM。此时RAM的数据已经不是原来address = 0~255对应的数据,而是address = 256~511对应的数据。同理,address = 0~1M的地址都可以正确的读写。

1MB的内存,按256Bytes为一页,可以分为4096页。在访问内存时,首先看落在了第几页Pages_rw。如果当前RAM中存储的页Pages_cur,就等于Pages_rw,则仅仅只是进行一个地址转换address_ram = address%256,就直接访问。否则,需要把RAM的内容全部写入Flash的Pages_cur,然后从Flash读取Pages_rw,复制到RAM。

当然,按这样的做法,是最简单的情况。就是直接把RAM的大小Page_Bytes=256当做一个页。但是这样效率很低。如果程序一直在address = 255和address=256循环的访问,会造成单片机需要不断的去拷贝整片Page_Bytes数据。我们可以把RAM划分为8页,那么Page_Bytes = 32。这样,就算发生了需要换页的情况,也仅仅只需要拷贝32字节。事情变得可接受了一些。这样做带来的副作用了增加了换页的次数,连续访问整片RAM需要做8次换页。所以,把Page_Bytes设置得太小也是不适合的。要权衡换页次数和换页效率。

现在,RAM中已经存在了8个页,对应于Flash中的某8个页。当用虚拟地址访问的页不在RAM中时,会选择在RAM中查找使用次数最少的页,将其换成当前需要的新页。

这样一来,可以定义一个用于地址转换的结构体类型page_block,包含的信息有:

1.页与下一级存储器页的绑定关系page_sub。

2.这个页被使用到的次数page_use_times。

3.这个页被使用到的最大内存地址page_mem_max_use,这个变量记录了正在被使用的内存量。

typedef struct page_block

{

   char     page_sub;

   int      page_use_times;

   int      page_mem_max_use; 

}page_block;

有了这个机制之后,我们怎么在C语言中使用它呢?直接定义的变量,编译器不会让它们的地址超过255。所以我们可以自己写一套内存分配函数mem_get,这个内存分配并不是为了进行内存管理,而是为了把超过255的空间运用上来。然后自己做一个内存读写的函数mem_read,mem_write。这样一来,我们就能这样使用很大的内存空间:

char *x;

x= mem_get();//为x指针分配一个字节内存。规定从页面的最低地址内存开始分配。

mem_read(x); //读取x指向的空间一个字节

mem_write(x,10);//对x指向的空间写入一字节数据

有了这三个函数,可以以字节为最小单元进行内存访问。而其他数据类型,只是按字节数大小再封装一层函数即可。

我们需要实现这一套机制(软件MMU),所以芯片的256 RAM需要有一部分用来运行这个MMU。我们可以规定128Bytes的RAM用来运行MMU,其它的用来作为物理内存。这并不影响原理。这里注意,虚拟内存的Page并不一定和物理内存的Page处于同一页序号;物理内存的Page和Flash存储器的Page也不一定同一页序号;但虚拟内存的页序号一定等于Flash存储器的页序号。对于程序而言,RAM是透明的,它一直都是通过虚拟内存地址访问Flash存储器,把Flash存储器当RAM用。此时芯片内这128Bytes的RAM相当于一个衔接虚拟地址和Flash存储器地址的桥梁。

从虚拟地址到物理地址、Flash存储器地址的转换过程大概如下:

 

 

 

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值