从STM32的位带操作重谈嵌入式中寻址与对齐的理解
初接触STM32的人一定花了不少时间用于理解其位带操作(bit banding)的原理与步骤。位带操作允许编程人员以字的单位读/写单一bit位。回想我们平时对于一个bit位的操作比如:↓
@-> PIN0 |= (1<3);
@-> PIN0 &= ~(1<5);
虽然这只是一行代码,但是实际上这一行做了好几步的工作。比如第一行,首先读出当前PIN0的值放到缓存区,将1左移三位放入缓存区,将二者进行“或”操作,即将当前PIN0的第三位置位1,将结果存入到实际PIN0所在的地址,即更新了PIN0的值。当然实际写成汇编后可能步骤不见得一定一样,但是这几步工作是一定得做的。
而对于位带操作,STM32中将上述PIN0(假设它处于允许重新映射的区域,即位带区->Bit Band Region)的每一个bit位重新映射到了一个单独的地址,只需对这一个新的地址进行写操作,则原PIN0值的对应位自动置位或清零。假设刚才我们PIN0的第3bit位重新映射的地址我们用变量PIN0BIT3表示,则刚才的操作可以写作如下↓
@-> PIN0BIT3 = 1; //等同于PIN0 |= (1<3), 这是由地址重映射保证的。
这一行的操作是,将1写入到PIN0BIT3所在的地址,即更新了PIN0BIT3的值,结束。由于地址重映射,将保证PIN0的第三bit位被置一了。可以看出,操作步骤比之前简单,因此同样的操作处理的速度更快了。
好,以上就是位带操作的原理,全部介绍完了,是不是很简单。接下来我们自然就想问了,这个PIN0第三bit位重新映射的地址在哪?这样地址重映射不是把内存扩大了么,允许重映射的地址会不会有限制?原地址跟重映射的地址之间有没有个换算公式将他们对应上?
我们自然而然会去寻找STM32的官方手册的说明。在STM32F1系列的的编程参考以及官方手册里均有提到位带操作的感念,那份编程参考里更是提到了计算二者联系的公式。
在编程参考P25页可以找到,允许bit位重新映射的位带区只有两处,一处是SRAM区,一处是片内的外设区Peripheral,均有1M大小。熟悉的人一眼就看出来了,SRAM区里存放的是堆栈(heap, stack)、全局变量等,外设区Peripheral区就是我们操作这块CPU经常打交道的GPIO, TIMER, PWM, A/D等各个功能的寄存器的所在地址。重新映射的区域叫位带别名区(Bit band alias),均有32MB大小。也就是说,我们最终操作的地址都仅仅是1MB,那扩充出来的32MB空间无外乎是为了操作方便快速而设定的,最终还是得影响到那1MB空间才能起作用。编程参考的P30页以SRAM区介绍了这一对应关系↓
以0x20000000(1MB的开头)这SRAM最低地址为例,其第一bit位重新映射到了0x22000000(32MB的开头)地址上,第7bit位映射到了0x2200001C地址上,以此类推,到SRAM最高地址0x200FFFF(1MB的结尾)F的第7bit位映射到了0x23FFFFFC(32MB的结尾)。注意到上面跟下面的区域之间每个方格的地址增长区别,下面(bit-band region)每块方格地址增长1,而上面(alias region)地址增长4,因此有了编程参考的第P30页的关系转换计算公式↓
好了,对于基础扎实熟悉的人来说到这里已经可以了,但是对于我,或者现在隐隐觉得有点疑问的人来说,可能对于这个换算的结果(1MB对应32MB)有点想进一步搞清楚这是为什么。为什么一会是字偏移(word_offset),一会是字节偏移(byte_offset),等等,字,bit,字节,是怎么对应的?等等,不是说寄存器都是32位的,怎么上面的对应图都是8bit(一字节)一对应的?晕了。所以这里有必要巩固一下这方面的基础知识。
首先回顾最基本概念。
在二进制中,从单纯数学上讲我们知道有
@-> 2^10=1024=1K
@-> 2^20=1024*1024=1M
@-> 2^30=1024*1024*1024=1G
最小二进制单位为比特(bit),即单纯的0,1,0,1,等等。对于音乐、图像等模拟信号我们进行压缩时通常采用的单位为比特率(bps),比如MP3最大比特率320Kbps,即每秒有320K个bit位,也就是每秒采样后的数字0,1的个数有320K个。一般CD的采样率为1411.2Kbps,因此音质就好很多了。普通VCD为1.25Mbps,DVD视频为5Mbps,标准蓝光为40Mbps,所以采用蓝光光盘的PS3游戏机的内部通信带宽比普通PC大很多也就是这个道理,因为每秒需要吞吐很大的数据量才能保证画面的清晰。
一个字节(Byte)等于8个bit,按照惯例我手写的B大写了。字节是通常的计算机存储的基本单位。我们通常所说的500GB硬盘、2GB内存就是指500个G的字节(Byte)和2个G的字节(Byte)。通常我们所说的32位处理器(比如ARM)的内存寻址范围为4GB就很好理解了。从单纯数学上讲↓
@-> 2^32= 4 * 2^30=4*1G=4G
最后,4GB的后面加了个B,即字
STM32位带操作寻址与对 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)