搜索
bottom↓
回复: 6

测试:8051的CODE BANK切换,IAR和KEIL哪个更给力。(占个位置)

[复制链接]

出0入0汤圆

发表于 2011-11-27 19:13:54 | 显示全部楼层 |阅读模式
很多51单片机都有超过64KB的CODE区,就要涉及到BANK切换。
我无聊,我蛋疼,我就做了这个比较。
占个位置,端个板凳,排排坐吃果果。
KEIL平台:keil UV3,硬件:CEL ZIC2410  16MHz,软件:IEEE802.15.4 MAC
IAR平台:IAR 7.6,硬件:TI CC2430  32MHz,软件:TIMAC

先卖个关子,ZIC2410的MOVX指令和MOVC指令在1~2个周期,CC2430要3~4个周期。

先去吃饭……

继续:

8051的CODE BANK模式原理:
    CODE区有16位寻址,即64KB,被分成ROOT区和BANK区,通常都是对半分,0000~7FFF是ROOT区,8000~FFFF是BANK区,然后通过一个寄存器,来选择BANK号。
    由于8051的PC只有16位,所以像函数调度,中断函数都是放在ROOT区的,这样的好处是,无论当前程序运行在哪个BANK,他们都能寻址到同一个ROOT区。如果一个函数是在BANK1,它要调度BANK2中的函数,在keil和IAR中,BANK模式下查看一个函数的地址,我们可以看到一个函数的地址有3个字节,比如BANK1的函数fun1()在CODE中的地址是0x01EF23,BANK2中fun2()的地址是0x029145。如果fun1中要调度fun2,通常是要在ROOT区中建立一个fun2的入口,因为指向fun2的函数指针是16位,无法操作BANK切换寄存器。
    这个过程是fun1中调度一个fun2的入口函数,fun2的入口函数则相当于一条指令,位于ROOT区,用于将PC跳转到fun2的实际所在地址。

以上说了这么多,很多人还是觉得抽象,我们先给出IAR的例程,再给出keil的例程。我们今天的主题就是那个编译器在切换BANK的时候速度更快。

首先是IAR,硬件是CC2430,在IAR下,工程的options选项中General Options下,有个code bank的设置,这个是设置bank切换寄存器和bank起始地址,结束地址。CC2430的BANK是8000~FFFF。另外IAR工程中还有个XCL文件的配置,其中有关BANK的配置如下:


-D_CODE_START=0x0000           // Code size = 128k for CC2430-F128
-D_CODE_END=0x7FFF             // Last address for ROOT bank
//
-D_BANK1A=(10000+_CODE_END+1)  // First address for BANK1

-D_NEAR_CODE_END=0x7FFF        // Last address for near code, near code segment is 32KB in banked code model.

-D_BANK1_START=_BANK1A
-D_BANK1_END=0x1FFFF
//
-D_BANK2_START=0x28000
-D_BANK2_END=0x2FFFF
//
-D_BANK3_START=0x38000
-D_BANK3_END=0x3DFFF
//
-P(CODE)BANK1=_BANK1_START-_BANK1_END
-P(CODE)BANK2=_BANK2_START-_BANK2_END
-P(CODE)BANK3=_BANK3_START-_BANK3_END
//-P(CODE)BANK3b=_BANK3b_START-_BANK3b_END

IAR的函数,是编译器自动分配BANK区。
下面我们来看看一个函数是怎么被调度的。
仿真模式下,可以看编译的代码
一个函数MSA_Delay,它的地址是0x19881,但是执行MSA_Delay的时候,是LCALL MSA_Delay::?relay指令。MSA_Delay::?relay又是什么东西?
MSA_Delay::?relay位于0x111D,显然是ROOT区,我们来看看,这里看到的代码是12 01 04 81 98 01,共6个字节,81 98 01就是函数的空间地址0x19881,12 01 04 就是一条跳转指令,跳到0x19881。
12是指令LCALL,调度 01 04地址的函数。
那我们来看看这个函数的真面目。
?BDISPATCH_FF:
000104  D0 83           POP   DPH
000106  D0 82           POP   DPL
000108  C0 9F           PUSH  ?CBANK
00010A  E4              CLR   A
00010B  93              MOVC  A,@A+DPTR
00010C  C0 E0           PUSH  A
00010E  74 01           MOV   A,#0x01
000110  93              MOVC  A,@A+DPTR
000111  C0 E0           PUSH  A
000113  74 02           MOV   A,#0x02
000115  93              MOVC  A,@A+DPTR
000116  F5 9F           MOV   ?CBANK,A
000118  22              RET
对了,还有个东西,叫SP寄存器,都忘了。
假设我们在一个BANK2的函数中,调度MSA_Delay,运行LCALL MSA_Delay::?relay的指令位于0x029813。假如此时SP值为0x23。
当取完这条指令后,由于是3个字节,PC应该变成0x9816,LCALL后,PC被压入堆栈,SP变成0x25。stack中地址0x24,0x25的值为0x16,0x98。
MSA_Delay::?relay位于0x111D,即PC变成0x111D,执行12 01 04指令,即LCALL ?BDISPATCH_FF:后,PC变成先变成0x1120压入堆栈,然后跳转0x0104,SP变成0x27,0x26的值是0x20,0x27的值是0x11。?BDISPATCH_FF:函数下stack中的值为0x16,0x98,0x20,0x11。然后POP DPH,POP DPL后,SP又变成了0x25,DPTR变成了0x1120。
再PUSH ?CBANK,当前BANK还是BANK2,所以SP就成了0x26,stack值为0x16,0x98,0x02,看看,这个是不是就是0x029816,就是函数执行完后需要回到的地方。

CLR   A,MOVC  A,@A+DPTR,PUSH  A,MOV   A,#0x01,MOVC  A,@A+DPTR,PUSH  A,我们看看这几条指令是干嘛的。我们知道0x1120开始的指令是81 98 01,而DPTR的值为0x1120,即对应值是0x81。于是,CLR   A,MOVC  A,@A+DPTR,PUSH  A后,SP就成了0x27,stack中就是0x16,0x98,0x02,0x81;MOV   A,#0x01,MOVC  A,@A+DPTR,PUSH  A,SP就成了0x28,stack中就是0x16,0x98,0x02,0x81,0x98,这时候, MOV   A,#0x02,MOVC  A,@A+DPTR,MOV   ?CBANK,A,就是将BANK寄存器设置成0x01。然后再RET,PC就变成了0x9881,而BANK寄存器又是0x01,当然就是执行0x19881,即函数MSA_Delay。

对于在BANK区的函数,结束时,有个LJMP ?BRET_FF指令代替了原先RET指令的位置,跳转至POP ?CBANK,RET。我们来分析一些堆栈,进函数的时候,SP变成了0x26,stack中是0x16,0x98,0x02。POP ?CBANK后,BANK切换至BANK2,SP变成0x25,stack中是0x16,0x98,一旦RET,PC就会跳回0x29816这个地址,也就是刚才执行函数的地方。

对于CC2430来说,执行bank区的函数,要将近60个周期的跳转时间,如果加上XRAM堆栈保存,消耗的周期更多,所以32MHz的频率对CC2430来说并不算多。

明天我们来分析一下keil上是如何实现的。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2011-11-27 21:15:55 | 显示全部楼层
sdcc撸过占沙发

出0入0汤圆

发表于 2012-2-26 19:40:05 | 显示全部楼层
有点深奥啊,还是多谢楼主!
学习了!

出0入0汤圆

发表于 2012-2-27 09:46:07 | 显示全部楼层
站位

出0入0汤圆

发表于 2012-2-27 18:38:59 | 显示全部楼层
也来占个位

出0入0汤圆

发表于 2012-3-2 08:59:35 | 显示全部楼层
期待后续

出0入0汤圆

发表于 2012-3-2 21:25:25 | 显示全部楼层
mask
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-19 22:32

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表