ARM处理器架构——内存管理

一、内存映射

1.什么是内存映射
内存映射指的是在ARM存储系统中,使用内存管理单元(MMU)实现虚拟地址到实际物理地址的映射,如下图所示。
ARM处理器架构——内存管理_第1张图片
【注】图中的地址转化器即MMU,CPU操作的称为虚拟地址MMU操作的为实际的物理地址

2、为什么要内存映射
ARM的地址总线为32位,故CPU可寻址范围为0x00000000~0xffffffff寻址空间为4GB,所有的内部和外部存储或者外设单元都需要通过对应的地址来操作,他不同的的芯片外设的种类数量寻址空间都不一样,为了能让内核更方便的管理不同的芯片设计,ARM内核会先给出预定义的存储映射,如下图所示
ARM处理器架构——内存管理_第2张图片
芯片设计公司需要根据内核提供的预定义的存储器映射来定义芯片内部外设和外部的保留接口,这样做的好处是极大地减少了同一内核不同芯片间地址转化的麻烦(cpu操作统一的虚拟地址,实际物理地址交由MMU管理)。

二、位带操作

1、什么是位带操作
举个简单的例子,在使用51单片机操作P1.0为低电平时我们知道这背后实际上就是往某个寄存器某个比特位中写1或0的过程,但在CPU操作的过程中每一个地址所对应的都是一个8位字节,怎么实现对其中某一位的直接操作,这就需要位带操作的帮助。
2、那些地址可以进行位带操作
上图中有两个区中实现了位带。其中一个是 SRAM 区的最低 1MB 范围(Bit band region),第二个则是片内外设区的最低 1MB 范围。这两个区中的地址除了可以像普通的 RAM 一样使用外,它们还都有自己的“位带别名区”,位带别名区把每个比特膨胀成一个 32 位的字。位带操作所使用的膨胀地址原本位于位带别名区(Bit band Alias),由于现在都指向了位带区的特殊位,这些膨胀地址都不能在指向一个8位的空间。

三、具体寄存器的地址计算

在ARM中所有的外设地址基本都是挂载在AHP或者APBx总线上,因此我们往往采用基地址+偏移地址+结构体的方式,来快速明了计算某一外设具体寄存器的地址,如下图所示。
ARM处理器架构——内存管理_第3张图片
举个例子,当我们想要操作GPIOA模块中的ODR寄存器时只需要直接操作GPIO->ODR即可,该寄存器的的实际地址已经通过外设基地址 PERIPHA_BASE(内核预定义地址)+AHB1总线偏移地址(具体芯片设计公司决定)+GPIOA的偏移地址(具体芯片设计公司决定)+GPIO模块的寄存器分布结构体决定。再将模块的寄存器分布结构体指针指向模块基地址(#define GPIOA ((GPIO_TypeDef *)GPIOA_BASE)),这样做的好处是我们在调用GPIOA时直接就定位到了该模块的基地址及内部个寄存器的地址偏移。

【注】当你使用位带功能时,要访问的变量必须用 volatile 来定义。因为 C 编译器并不知道同一个比特可以有两个地址。所以就要通过 volatile,使得编译器每次都把新的数值写入寄存器,而不会进行优化操作。

四、堆和栈作用

一般情况下,一个程序本质上都是由 bss段、data段、text段三个组成的
.bss段:(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称.bss段属于静态内存分配。
.data段 :数据段(data segment)通常是指用来存放程序中 已初始化 的 全局变量 的一块内存区域。数据段属于静态内存分配。
.text/.code段: 代码段(code segment/text segment)通常是指用来存放 程序执行代码 的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于 只读 , 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些 只读的常数变量 ,例如字符串常量等。程序段为程序代码在内存中的映射.一个程序可以在内存中多有个副本.
在单片机上RAM存放data段,bss段,堆栈段;ROM(EPROM,EEPROM,Flash等非易失性存储设备)存放代码,只读数据段。
对单片机编程后,程序的代码段.data段.bss段.rodata段等都存放在Flash中。当单片机上电后,初始化汇编代码将data段,bss段,复制到RAM中,并建立好堆栈,开始调用程序的main函数。

一个由C/C++编译的程序占用的内存分为以下几个部分
1>栈区(stack)——由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2>堆区(heap)——一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3>全局区(静态区)(static)——全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放
4>文字常量区——常量字符串就是放在这里的(不可修改)。 程序结束后由系统释放
5>程序代码区——存放函数体的二进制代码。
其中堆区和栈区存放在RAM中,而全局区、文字常量区、程序代码区存放在ROM(Flash)中。

你可能感兴趣的:(ARM )