打印
[ZLG-MCU]

关于bit-band的效率(内有例子)??

[复制链接]
4104|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
bigflower|  楼主 | 2008-10-18 12:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
变量定义如下:
#define false 0
#define true  1
#define flag_timer0_a_1ms 0
extern volatile INT16U timer0_a_Flags;
使用HWREGBITW和直接操作两种方式对timer0_a_Flags的最低位置1和置0

产生汇编如下,请问BIT-BAND有什么优势??


    HWREGBITW(&timer0_a_Flags, flag_timer0_a_1ms)= true;//1ms 
0x000001A2 2001      MOVS     r0,#0x01
0x000001A4 492C      LDR      r1,[pc,#176]  ; @0x00000258
0x000001A6 F0014170  AND      r1,r1,#0xF0000000
0x000001AA F0417100  ORR      r1,r1,#0x2000000
0x000001AE 4A2A      LDR      r2,[pc,#168]  ; @0x00000258
0x000001B0 F3C20213  UBFX     r2,r2,#0,#20
0x000001B4 EA411142  ORR      r1,r1,r2,LSL #5
0x000001B8 6008      STR      r0,[r1,#0x00]
    HWREGBITW(&timer0_a_Flags, flag_timer0_a_1ms)= false;//1ms 
0x000001BA 2000      MOVS     r0,#0x00
0x000001BC 4926      LDR      r1,[pc,#152]  ; @0x00000258
0x000001BE F0014170  AND      r1,r1,#0xF0000000
0x000001C2 F0417100  ORR      r1,r1,#0x2000000
0x000001C6 4A24      LDR      r2,[pc,#144]  ; @0x00000258
0x000001C8 F3C20213  UBFX     r2,r2,#0,#20
0x000001CC EA411142  ORR      r1,r1,r2,LSL #5
0x000001D0 6008      STR      r0,[r1,#0x00]
    timer0_a_Flags&=~(1<<flag_timer0_a_1ms); 
0x000001D2 4821      LDR      r0,[pc,#132]  ; @0x00000258
0x000001D4 8800      LDRH     r0,[r0,#0x00]
0x000001D6 F0200001  BIC      r0,r0,#0x01
0x000001DA 491F      LDR      r1,[pc,#124]  ; @0x00000258
0x000001DC 8008      STRH     r0,[r1,#0x00]
    timer0_a_Flags|=(1<<flag_timer0_a_1ms); 
0x000001DE 4608      MOV      r0,r1
0x000001E0 8800      LDRH     r0,[r0,#0x00]
0x000001E2 F0400001  ORR      r0,r0,#0x01
0x000001E6 8008      STRH     r0,[r1,#0x00]

相关帖子

沙发
bigflower|  楼主 | 2008-10-18 12:22 | 只看该作者

另外对于I/O的置位和反转,可以使用BIT-BAND吗?

使用特权

评论回复
板凳
seeokok| | 2008-10-19 15:22 | 只看该作者

bit-band有效率,但无法用

    关键在timer0_a_Flags编译前无法确定地址,程序运行时需要计算出别名地址,因此无效率可言。
    如果确定地址,编译后的结果就不同了:
#define FlagBase 0x20001000
#define Testb0 HWREGBITW(FlagBase, 0)
#define Testb1 HWREGBITW(FlagBase, 1)
#define Testb2 HWREGBITW(FlagBase, 2)

#define false 0
#define true  1

   149              Testb0=true;
      00000040   1748               LDR.N    R0,??jtagWait_0+0xC  ;; 0x22020000
      00000042   0121               MOVS     R1,#+1
      00000044   0160               STR      R1,[R0, #+0]

问题是,如此定义的地址,不能保证不会被别的变量覆盖,试过用
__no_init uint8 Test_bit @ FlagBase;
指定变量位置,也还是会被别的变量覆盖,我用的是IAR,现在我还没找出一个行之有效的办法。谁有办法请不吝赐教 :-P

二楼的问题:操作I/O, 实际是操作GPIODATA寄存器,它采用地址线屏蔽的方式操作,比BIT-BAND的效率还要高,它可以几个位同时操作而不影响其他位,功能调用GPIOPinWrite就是这样操作的。如果你想要更高的效率,你可以直接对寄存器进行操作:
HWREG(ulPort + (ucPins << 2)) = ucVal;
这样最少也省了调用函数所花的时间。

使用特权

评论回复
地板
bigflower|  楼主 | 2008-10-19 21:07 | 只看该作者

谢谢,seeokok的答复!!

看来编译器对M3核的支持还有待提高啊!!


使用特权

评论回复
5
zlgmcu| | 2008-10-20 15:50 | 只看该作者

测试方法直接影响测试结果,楼主的测试手段说明不了什么

请看下面这个例程,位操作仅需一条指令:

#include  <hw_types.h>

#define  SYSCTL_BASE        0x400FE000                      //  定义系统控制模块的基址
#define  RCGC2              (SYSCTL_BASE + 0x108)           //  定义时钟选通控制寄存器2

int main(void)
{
    HWREGBITW(RCGC2, 1) = 1;                                //  选通GPIOB模块的时钟
    for (;;);
}

使用特权

评论回复
6
bigflower|  楼主 | 2008-10-22 10:33 | 只看该作者

请ZLGMCU留电话,我详细请教,我的mail:bigflower@eyou.com,谢谢!

请ZLGMCU留电话,我详细请教,我的mail:bigflower@eyou.com,谢谢!

使用特权

评论回复
7
AIRWILL| | 2008-11-7 17:12 | 只看该作者

干吗又要电话

楼主的效率很差, 你给个高效率的例子出来给他看看, 他一定很聪明, 马上就学会的, 这问题, 电话说不清楚的吧

使用特权

评论回复
8
AIRWILL| | 2008-11-7 17:26 | 只看该作者

看看我的位变量

下面是一段编译结果, 其中 ifcwrite,flushem,ifcflash 是定义的SRAM 中的位变量


;;;612    if ((ifcwrite)|| ((!flushem) && ((ifcflash))))  { //en
000748  f892f892          LDRB     r0,[r2,#0x78];ifcwrite
00074c  b930              CBNZ     r0,|L1.1884|
00074e  7918              LDRB     r0,[r3,#4]  ; flushem
000750  2800              CMP      r0,#0
000752  d150              BNE      |L1.2038|
000754  f892f892          LDRB     r0,[r2,#0x7c] ; ifcflash
000758  2800              CMP      r0,#0
00075a  d04c              BEQ      |L1.2038|


;;;635    if (ifbready) { ifwriteq = 64; ifcwrite = 0; ifcflash = 0; }//en
0007e4  f892f892          LDRB     r0,[r2,#0x68]
0007e8  2800              CMP      r0,#0
0007ea  d004              BEQ      |L1.2038|
0007ec  2040              MOVS     r0,#0x40
0007ee  70d8              STRB     r0,[r3,#3]  ; ifwriteq
0007f0  f802f802          STRB     r5,[r2,#0x78]!; ifcwrite
0007f4  7115              STRB     r5,[r2,#4]  ; ifcflash

使用特权

评论回复
9
AIRWILL| | 2008-11-7 17:48 | 只看该作者

我的位变量定义

#define IFCWRITF 30
#define IFCFLASH 31


#define ifcwrite (*((unsigned char *)(SRAM_BITBASE + IFCWRITF *4))) 
#define ifcflash (*((unsigned char *)(SRAM_BITBASE + IFCFLASH *4))) 

使用特权

评论回复
10
zlgmcu| | 2008-11-10 15:53 | 只看该作者

bit-band效率确实要高些,不过要看你怎么用、怎么认为

bit-band的效率跟编译器有直接的关系,大家都知道
如果目标地址是立即数则效率较高,如果是变量则效率低
另外要同等条件下比较,如果条件不等同很容易得出相反结论
总之,不要冤枉了高效的bit-band操作

使用特权

评论回复
11
AIRWILL| | 2008-11-10 21:35 | 只看该作者

是的

这只能怪编译器

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

124

帖子

2

粉丝