一、为什么要用到BANK?
C51单片机的最大寻址范围为2^16=64K,为了突破64K代码的限制,就需要采用C51的切BANK。
二、切BANK的原理
代码地址空间的上半部 ,以重叠BANK0的物理地址空间 , 硬件设计了 n个存储 器页面来存储程序代码 。在任一时刻 BANK0~n中 , 只能有一个 BANK 处于激 活状态。当BANKi处于激活状态时,其物理地址空间为BankBase Addr ~ 0xFFFF。 只有 当BANK处于激活状态时, BANK 中的程序代码才可以运行 。
逻辑地址范围都是相对的,更像是bank的编号,映射到可寻址的物理地址空间去!
为了寻址任意BANK中的过程代码,C51编译器为过程调用生成了如下的BANK地址:
Base地址是可变的,但为了译码方便,一般选为8000H。当某过程调用任一不在同一BANK中的其它过程时,BANK地址中的Bank-Number被送到切换BANK的译码电路,而16位的偏移地址被送往地址总线,从而实现不同BANK中的过程调用。
三、ROOT BANK的使用
下半部分的代码没有做BANK处理,它被称为ROOT BANK。只是因为C51编译器仅对过程调用产生BANK地址,而对于调用之外的所有其它部分如CONST等不产生BANK地址,ROOT BANK即用来存放这部分代码。除此之外,ROOT BANK一般还用来存放下列代码:C51的库函数、所有的变量初始化数据、中断服务程序代码、CATARTED代码。编译器总是以NON BANK方式对这一类代码进行操作。
而对于其它代码来说,既可以放在BANK中,也可以放在ROOT BANK,但为了提高系统的运行效率,对经常调用的公共程序模块,应尽可能放在ROOT BANK中,以减少BANK的切换,而对于汇编语言编写的程序块,如果将其放在BANK中,则需要人工在汇编程序中添加对BANK切换的操作,非常繁琐,因此用汇编语言编写的程序模块一般也放在ROOTBANK中。
公共区域常常包括那些必须一直需要访问的进程和数据常量,如中断进程、中断和复位向量、字符串常量和块切换进程。因此,公用代码空间的起始位置通常为代码块的0X0000。
四、BANK函数的使用
任一个C程序模块,在编译时都要生成一个CODE段,而Linker不可能把一个模块的CODE分配到多个BANK中。只要不超出BANK的空间,linker可以把多个程序模块的代码放入一个BANK中,将每个程序模块最小化,便可以充分利用BANK的空间资源。
在BANK模式中,当编译器不知道调用与被调用是否在同一个BANK时,就会按照BANK调用方式产生程序代码。函数默认采用__banked_func,如果非BANK的函数,则需要人工加上__near_func字段。
五、其它
1. 当调用与被调用过程在同一个源代码程序模块时,编译器可知道它们在同一个物理BANK中,这时编译器使用NON BANK方式产生函数调用代码。
2. 当过程被说明为static类型时,编译器认为所有对static过程的调用均在本程序模块中,编译器产生NON BANK的调用方式。
3. 对于被说明为interrupt的中断过程,编译器总是产生NON BANK的调用方式对其调用,因为中断过程总是要放在ROOT BANK中。
4. 根据BANK的分配情况,使用non-banked编译条件对源程序中的过程进行说明,人为地控制编译器产生NON BANK方式的调用。