位带操作理解

为什么有位带别名区

位带别名区的设计主要是为了方便对单个比特位进行读写操作。在某些应用场景下,需要频繁地对某个特定的比特位进行读写操作,但是由于处理器架构中并没有提供直接读写单个比特位的指令,因此需要使用一定的位运算来实现。但是,这样会使得代码复杂且容易出错。

位带别名区的出现,就是为了解决这个问题。它通过为每个比特位分配一个独立的物理地址,以便能够直接对某个特定的比特位进行读写操作,从而避免了手动进行位运算的麻烦和出错风险。实际上,位带别名区就是在内存中专门开辟出来的一段空间,其中的每4个字节都与原始内存中的某个特定的比特位相映射,从而可以直接对该比特位进行读写操作。

由于对单个比特位进行读写操作的需求非常普遍,因此,在一些处理器架构中,设计者就提供了位带别名区的功能。例如,ARM架构中就支持这个特性,通过使用位带别名区,可以大大简化一些应用程序的编写,提高代码的可读性和可维护性。

 

STM32本身只支持8、16、32位的操作,而不支持单独的位操作,但实际对单个位有相应单独操作的需求。所以读出整个的32位,然后对其中一位做操作再整体写回去。因为无法在寄存器中对位进行操作,常说的读改写三部曲,但是效率低。
位带别名区的出现,就是为了解决这个问题。它通过为每个比特位分配一个独立的物理地址,以便能够直接对某个特定的比特位进行读写操作,从而避免了手动进行位运算的麻烦和出错风险。实际上,位带别名区就是在内存中专门开辟出来的一段空间,其中的每个字节都与原始内存中的某个特定的比特位相映射,从而可以直接对该比特位进行读写操作

在位带别名区中,每个比特对应一个32位的数据存储单元,只要对这个32位的数据存储单元最低位赋值位零或者一就可以改变对应的位

在 ARM Cortex-M3 和 Cortex-M4 中,每个比特位被映射到一个位带寄存器中,其物理地址的计算方式为:0x22000000 + (byte_offset * 32) + (bit_number * 4)。其中,byte_offset 表示该比特位在位带别名区中的偏移量,bit_number 则是该比特位在所在字节中的位偏移量。

这里的物理地址 0x22000000 实际上是位带寄存器区(Bit-band Region)的起始地址,在处理器的内存映射结构中,它位于位带别名区的后半部分,即地址范围为 0x22000000 - 0x23FFFFFF。在这个地址范围内,每个比特位都被映射到了一个位带寄存器中。(这里的位带寄存器区是处理器专门为了支持位带操作而设置的一段内存空间,其中包含了一组特殊的寄存器,每个寄存器都对应着一个比特位。通过读写这些特殊寄存器,可以直接对位带别名区中的某个具体比特位进行读写操作

Q:在位带别名区中,每个比特对应一个32位的数据存储单元为甚么不选择16位

A:在SRAM位带区(1MB)中的一个字节有八个位。其中一个位在位带别名区(32MB)中映射出来32个位,也就是一个字(在32单片机中单片机传输的数据以字为单位进行,因为时间和计算成本,就算少于一个字也会补全到一个字的大小再传输)。所以在把一个字节映射成四个字节方便传输,也提高数据的安全性

为什么位带区的1个字节(8bit)地址对应位带别名区4个字节(32bit)的地址呢?
答;位带区一个bit的地址对应别名区四个bit的地址,位带区一个字节地址对应的是别名区四个字节(32位)的地址。STM32是32位总线的,映射成32位效率更高,也就是四个字节。

那么希望在对SRAM某一位置零或1时,该怎么操作?
例如对SRAM中某一位赋值,首先使用BITBAND_SRAM宏将SRAM地址0x20000000的第2位映射到相应的位带别名地址,然后使用指针方式直接对该位带别名地址中的值进行修改,实现了对SRAM某一位进行赋值的操作。

看懂下面就差不多了 


对位带别名区的访问只对 LSB 有效

Q:在 ARM 芯片中,内存地址空间的映射是怎么做到的

在ARM Cortex-M3处理器中,位带区域和位带寄存器的映射关系都是物理地址映射到物理地址,并不涉及虚拟地址。

具体来说,位带区域是SRAM的一部分,它的地址范围在物理地址空间中是连续的,位于0x20000000 ~ 0x200FFFFF之间。在这个地址范围内,每个比特都可以被映射到一个32位的位带寄存器。

位带寄存器的地址计算方法是将比特的物理地址转换为相应的位带寄存器的物理地址,然后通过该物理地址直接对位带寄存器进行访问。这样就可以实现对单个比特的原子操作,而且无需使用MMU(Memory Management Unit)进行地址转换。

需要注意的是,物理地址映射到物理地址的方式,对操作系统或者RTOS的支持要求较高,因此在使用位带寄存器进行操作时,需要对操作系统和RTOS进行相应的配置和保护。

感觉在内存空间不够的情况可以下映射成8bit,一个字节访问也行。
应该是物理地址映射到物理地址。
SRAM位带区的地址范围是0x20000000-0x20100000,别名区的地址范围是0x22000000-0x23ffffff。所以位带区域和位带寄存器的映射关系都是物理地址映射到物理地址。
而当进程需要访问虚拟地址时,会使用到把自己的虚拟地址传递给MMU,MMU会根据地址映射表将虚拟地址转换为物理地址,并且检查是否有访问别名区的权限,如果有权限,则会把物理地址返回给进程,然后该进程就可以从该地址中读取或写入数据。而进程的虚拟空间地址在程序运行时动态地分配和管理。进程会维护每个一个页表或者页目录表,用于记录该进程的虚拟地址空间与物理地址空间的映射关系。从而能够达到不同进程访问同一段内存区域中的数据,不需要额外的的开销。
总的来说就是进程会动态地分配和管理虚拟空间地址,并通过MMU的地址映射表将其转换为物理地址,使得进程能够访问别名区内的地址。而别名区和位带区的映射在编译器中则通过 #define一个位带别名区的地址进行联系?

也就是编译器其实也不知道0x20000000的bit0和0x22000000其实是同一个地址
为了在程序中使用位带区域和位带寄存器的映射关系,我们需要手动定义一些宏或者函数来将物理地址转化为对应的位带地址,并且使用位带操作指令来访问位带寄存器中的位。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值