一、前言
本篇介绍STM32芯片的存储结构,ARM公司负责提供设计内核,而其他外设则为芯片商设计并使用,ARM收取其专利费用而不参与其他经济活动,半导体芯片厂商拿到内核授权后,根据产品需求,添加各类组件,生产芯片售卖。图1为STM32的组成示意图,其中Cortex-M3内核、调试系统都是ARM公司设计,内部总线、外设、存储、时钟复位等都由ST公司开发。可以明显看出总线是cpu、内存、外设传递信息的公用通道,芯片上的各个部件通过总线相连接。
图1 STM32芯片简要结构图
内核通过总线访问各个外设,现在通往外设的“路”已经铺好,还需要规定各个外设的“门牌号”,以便精准控制每个外设。ARM Cortex-M3系列的处理器,采用存储器与I/O设备(外设)统一编址的方式,将部分存储器地址范围用于外设,这种通过存储器地址访问外设的方式,称为存储器地址映射。
二、内核存储结构
图2 存储结构框架
以Cortex‐M3内核为例,对于32位的处理器,可寻址的范围为2^32字节,即2^32= 4 × 1024 × 1024 × 1024 = 4GB,也就是0x00000000至0xFFFFFFFF。ARM将这4G空间从低地址到高地址依次划分为代码区(Code)、片上SRAM区(SRAM)、片上外设(Peripheral)、片外RAM(External RAM)、片外外设(External Device)和系统级(System level),程序存储器、数据存储器、寄存器和 I/O 端口排列在同一个顺序的 4 GB 地址空间内。各字节按小端格式在存储器中编码。字中编号最低的字节被视为该字的最低有效字节,而编号最高的字节被视为最高有效字节。
图3 Cortex‐M3存储结构
从图3中可见,不像其它的 ARM 架构,它们的存储器映射由半导体厂家说了算,Cortex‐M3 预先定义好了“粗线条的”存储器映射。通过把片上外设的寄存器映射到外设区,就可以简单地以访问内存的方式来访问这些外设的寄存器,从而控制外设的工作。结果,片上外设可以使用C语言来操作。这种预定义的映射关系,也使得对访问速度可以做高度的优化,而且对于片上系统的设计而言 更易集成(还有一个重要的,不用每学一种不同的单片机就要熟悉一种新的存储器映射)。
Cortex‐M3的内部拥有一个总线基础设施,专用于优化对这种存储器结构的使用。在此之上, Cortex‐M3甚至还允许这些区域之间“越权使用”。比如说,数据存储器也可以被放到代码区,而且代码也能够在外部 RAM 区中执行。
处于最高地址的系统级存储区,是Cortex‐M3用于藏“私房钱”的——包括中断控制器、MPU 以及各种调试组件。 所有这些设备均使用固定的地址。 通过把基础设施的地址定死,就至少在内核水平上,为应用程序的移植扫清了障碍。 因此使用该内核的设计者必须按照这个进行各自芯片的存储器结构设计。 这一点极大地方便了软件在各种Cortex‐M3 单片机间的移植。 举个简单的例子,各款 Cortex‐M3单片机的NVIC 和 MPU 都在相同的位置布设寄存器,使得它们变得通用。 尽管如此,Cortex‐M3定出的条条框框是粗线条的,它依然允许芯片制造商灵活地分配存储器空间,以制造出各具特色的单片机产品。
存储空间的一些位置用于调试组件等私有外设,这个地址段被称为“私有外设区”。 私有外设区的组件包括:闪存地址重载及断点单元(FPB)、数据观察点单元(DWT)、指令跟踪宏单元(ITM)、嵌入式跟踪宏单元(ETM)、跟踪端口接口单元(TPIU) 、ROM 表。
Cortex‐M3的地址空间是 4GB, 程序可以在代码区,内部 SRAM 区以及外部 RAM 区中执行。 但是因为指令总线与数据总线是分开的,最理想的是把程序放到代码区,从而使取指和数据访问各自使用自己的总线,并行不悖。
让我们先看一看这 4GB 的粗线条划分:
图4 Cortex‐M3预定义的存储映射
内部 SRAM 区的大小是 512MB,用于让芯片制造商连接片上的 SRAM,这个区通过系统总线来访问。 在这个区的下部,有一个 1MB 的位带区,位带区就是可以按bit去访问存储的字节地址的内容。 该位带区还有一个对应的32MB 的“位带别名(alias)区”,容纳了 8M 个“位变量”(对比 8051 的只有 128 个位)。 位带区对应的是最低的 1MB 地址范围,而位带别名区里面的每个字对应位带区的一个比特。 位带操作只适用于数据访问,不适用于取指。 通过位带的功能,可以把多个布尔型数据打包在单一的字中,却依然可以从位带别名区中,像访问普通内存一样地使用它们,位带别名区中的访问操作是原子的。
地址空间的另一个 512MB 范围由片上外设(的寄存器)使用。 这个区中也有一条32MB的位带别名,以便于快捷地访问外设寄存器。 例如,可以方便地访问各种控制位和状态位。
要注意的是,外设内不允许执行指令。 还有两个 1GB的范围,分别用于连接外部 RAM 和外部设备,它们之中没有位带。 两者的区别在于外部 RAM 区允许执行指令,而外部设备区则不允许。
最后还剩下 0.5GB 的私有空间,Cortex‐M3内核的专有外设就在这里面,包括了系统级组件,内部私有外设总线,外部私有外设总线,以及由内核提供者定义的系统外设。
三、芯片存储映射
ARM公司只是大概的规定了存储器空间的映射,允许各芯片厂商在指定范围内自行定义和使用这些存储空间,未分配的空间为保留的地址空间。
STM32的存储器结构和Cortex-M3的很相似,不同的是,STM32加入了很多实际的东西,如:Flash、SRAM,片上外设等。 只有加入了这些东西,才能成为一个拥有实际意义的、可以工作的处理芯片。 可寻址的存储空间分为 8 个主要块,每个块为 512 MB。 未分配给片上存储器和外设的所有存储区域均视为“保留区”。
我们对比一下Cortex-M3存储器结构和STM32存储器结构:
图5 Cortex‐M3和STM32存储结构对比
STM32在ARM规定的基础上,将4G空间分为了Block0、Block1、Block2、……、Block7,共8块,每块大小为512MB。
图6 STM32的存储映射
0x0000 0000 ~ 0x1FFF FFFF(512MB):作为代码区,存默认的向量表,用于存放下载的代码。 系统上电后,将从该部分读取代码;
0x2000 0000 ~ 0x3FFF FFFF(512MB):作为SRAM区,用于存放运行代码。 系统上电后,将从Flash读取代码,放到SRAM里,CPU再从SRAM读取代码运行;
0x4000 0000 ~ 0x5FFF FFFF(512MB):作为片上外设区,用于存放厂商外设寄存器。 如USART,I2C等,要操作外设,即修改这里对应的外设寄存器;
0x6000 0000 ~ 0x9FFF FFFF(1GB):作为片外RAM,用于扩展RAM。 当SRAM或者Flash不够用时,MCU通过FSMC外接其它IC芯片,则在这个地址范围读写IC芯片数据;
0xA000 0000 ~ 0xDFFF FFFF(1GB):作为片外外设区,用于读写扩展IC芯片的寄存器。 ST只用了这里的一半空间,另外一空间未使用;
0xE000 0000 ~ 0xFFFF FFFF(512MB):作为内核外设区,用于存放Cortex-M3内核的内部外设。 CortexM3内核的内部外设有NVIC、Systick等;
SRAM的理解比较简单,其作用是用来存取各种动态的输入输出数据、中间计算结果以及与外部存储器交换的数据和暂存数据。 设备断电后,SRAM中存储的数据就会丢失。 不同类型的STM32单片机的SRAM大小是不一样的,但是它们的起始地址都是0x2000 0000,终止地址都是0x2000 0000+其固定的容量大小。
我们的程序和常量是存储在Flash中的,调试模式下也可以看出PC指针始终指向0x0800 0000后面的Flash区域。
四、总结
本篇对STM32芯片内部的存储结构框架进行了整体的概述,主要是要对STM32芯片大致的存储结构有一个初步的了解,重点是明确片上的FLASH和RAM地址,有助于理解实际代码存储和运行的空间位置。 而诸如STM32的片上外设各个寄存器地址,可以详细的去参考具体的芯片手册获取各个外设具体的寄存器相关内容。
相关文章