STM32 HAL库开发: 存储器和总线架构

系统结构

STM32 HAL库开发: 存储器和总线架构_第1张图片

驱动单元

ICode

Instruction指令。我们写好的程序经过编译之后都是一条条指令,存放在FLASH 中,内核要读取这些指令来执行程序就必须通过ICode 总线,它几乎每时每刻都需要被使用,它是专门用来取指的。该总线将Cortex™-M3内核的指令总线与闪存Flash指令接口相连接。指令预取在此总线上完成。

DCode

DCode 总线是用来取数的。

  1. 常量就是固定不变的,用C 语言中的const 关键字修饰,是放到内部的FLASH当中的

  2. 变量是可变的,不管是全局变量还是局部变量都放在内部的SRAM。因为数据可以被Dcode 总线和DMA 总线访问,所以为了避免访问冲突,在取数的时候需要经过一个总线矩阵仲裁,决定哪个总线在取数。该总线将Cortex™-M3内核的DCode总线与闪存存储器的数据接口相连接(常量加载和调试访问)。

System bus

系统总线主要是访问外设的寄存器(register),我们通常说的寄存器编程,即读写寄存器都是通过这根系统总线来完成的。此总线连接Cortex™-M3内核的系统总线(外设总线)到总线矩阵,总线矩阵协调着内核和DMA间的访问。

DMA(外设) bus

Direct Memory Access直接存储器访问.
使用DMA,cpu就不用兜圈子,所以DMA不占cpu资源.

DMA 总线也主要是用来传输数据,这个数据可以是在某个外设的数据寄存器,可以在SRAM,可以在内部的FLASH。因为数据可以被Dcode 总线和DMA 总线访问,所以为了避免访问冲突,在取数的时候需要经过总线矩阵来仲裁,决定哪个总线在取数. 此总线将DMA的AHB主控接口与总线矩阵相联,总线矩阵协调着CPU的DCode和DMA到 SRAM、闪存和外设的访问。

总线矩阵

总线矩阵用于主控总线之间的访问仲裁管理,仲裁采用循环调度算法。 有了总线矩阵,就可以让主设备和从设备进行并行访问,提升了访问效率,同时也降低了功耗。 需要注意的是,虽然总线矩阵使得多个主设备可以并行访问不同的从设备,但在一个定义的时间段内,只有一个主设备拥有总线矩阵的控制权,如果有多个主设备同时出现总线请求时就得进行仲裁。

STM32 HAL库开发: 存储器和总线架构_第2张图片

总线矩阵协调内核系统总线和DMA主控总线之间的访问仲裁,仲裁利用轮换算法。在互联型产品中,总线矩阵包含5个驱动部件(CPU的DCode、系统总线、以太网DMA、DMA1总线和DMA2总线)和3个从部件(闪存存储器接口(FLITF)、SRAM和AHB2APB桥)。在其它产品中总线矩阵包含4个驱动部件(CPU的DCode、系统总线、DMA1总线和DMA2总线)和4个被动部件(闪存存储器接口(FLITF)、SRAM、FSMC和AHB2APB桥)。 AHB外设通过总线矩阵与系统总线相连,允许DMA访问。


参考cortex-M3手册

被动单元

AHB/APB桥(APB)

从AHB 总线延伸出来的两条APB2 和APB1 总线,上面挂载着STM32 的外设。我们经常说的GPIO、串口、I2C、SPI 这些外设就挂载在这两条总线上,这个是我们学习STM32 的重点,就是要学会编程这些外设去驱动外部的各种设备。

AHB/APB桥(APB) 两个AHB/APB桥在AHB和2个APB总线间提供同步连接。

APB1操作速度限于36MHzAPB2操作于全速(最高72MHz)。 在每一次复位以后,所有除SRAM和FLITF以外的外设都被关闭,在使用一个外设之前,必须设置寄存器RCC_AHBENR来打开该外设的时钟。

注意: 当对APB寄存器进行8位或者16位访问时,该访问会被自动转换成32位的访问:桥会自动将8位或者32位的数据扩展以配合32位的向量。

内部的闪存存储器

内部的闪存存储器即FLASH,我们编写好的程序就放在这个地方。内核通过ICode 总线来取里面的指令。

内部的SRAM

内部的SRAM,即我们通常说的RAM,程序的变量,堆栈等的开销都是基于内部的SRAM。内核通过DCode 总线来访问它。

FSMC

FSMC 的英文全称是Flexible static memory controller,叫灵活的静态的存储器控制器,是STM32F10xx 中一个很有特色的外设,通过FSMC,我们可以扩展内存,如外部的SRAM,
NANDFLASH(与非门闪存)和NORFLASH(非门闪存)。

注意:FSMC 只能扩展静态的内存,即名称里面的
S:static,不能是动态的内存,比如SDRAM 就不能扩展。

存储器映射 Memory map

存储器本身没有地址,给存储器分配地址的过程叫存储器映射
STM32 HAL库开发: 存储器和总线架构_第3张图片
被控单元的FLASH,RAM,FSMC 和AHB 到APB 的桥(即片上外设),这些功能部件共同排列在一个4GB 的地址空间内。操作时通过C语言访问地址.

存储器映射是指把芯片中或芯片外的FLASH,RAM,外设,BOOTBLOCK等进行统一编址。即用地址来表示对象。用户只能用而不能改。用户只能在挂外部RAM或FLASH的情况下可进行自定义。

如图,是Cortex-M3存储器映射结构图。
STM32 HAL库开发: 存储器和总线架构_第4张图片

Cortex-M3是32位的内核,因此其PC指针可以指向2^32=4G的地址空间,从0x0000_0000到0xFFFF_FFFF空间。
对比一下Cortex-M3存储器结构:
STM32 HAL库开发: 存储器和总线架构_第5张图片

图中可以很清晰的看到,STM32的存储器结构和Cortex-M3的很相似,stm32还添加了flash和SDRAM.
STM32 HAL库开发: 存储器和总线架构_第6张图片
STM32的存储器地址空间被划分为大小相等的8块区域,每块区域大小为512MB。

对STM32存储器知识的掌握,实际上就是对Flash和SRAM这两个区域知识的掌握。因此,下面将重点描述Flash和SRAM的知识。

寄存器映射

存储器本身没有地址,给存储器分配地址的过程叫存储器映射.

在存储器Block2 这块区域为片上外设,它们以四个字节为一个单元,共32bit,每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。我们可以找到每个单元的起始地址,然后通过C 语言指针的操作方式来访问这些单元,如果每次都是通过这种地址的方式来访问,不仅不好记忆还容易出错,这时我们可以根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射

STM32 HAL库开发: 存储器和总线架构_第7张图片
寄存器映射

基地址
在这里插入图片描述
偏移地址

在这里插入图片描述

寄存器地址访问

//常规写法
#define GPIOB_ODR (unsignedint*)(0x40010c0c)
* GPIOB_ODR = 0xFF;
//类似封装的写法
#define GPIOB_ODR *(unsigned int *)(GPIOB_BASE+0x0C)
//指针套一个指针 基地址+偏移地址 = 0xFFFF
GPIOB_ODR = 0xFF;

ODR:output data register

这样编程效率低,所以诞生了库函数,然后又有基于cmsis的HAL库编程.

STM32的SRAM

以下是STM32参考手册RM0008中的一段原话:
请添加图片描述
不同类型的STM32单片机的SRAM大小是不一样的,但是他们的起始地址都是0x2000 0000,终止地址都是0x2000 0000+其固定的容量大小。

SRAM的理解比较简单,其作用是:

用来存取各种动态的输入输出数据、中间计算结果以及与外部存储器交换的数据和暂存数据。

STM32的Flash

STM32的Flash,严格说,应该是Flash模块。
对闪存编程参考STM32F10xxx闪存编程参考手册.
该Flash模块包括:

Flash主存储块(Main memory)
Flash信息块(Information block)
Flash存储接口寄存器块(Flash memory interface)

三个组成部分分别在0x0000 0000到0xFFFF FFFF不同的区域,如图(小容量的STM32)所示:
STM32 HAL库开发: 存储器和总线架构_第8张图片

图中完全可以看出Flash模块中的三个组成部分在整个存储器中的位置。

具体的内部区域的意义及功能请参见编程手册PM0042,里面很详细。

STM32存储器结构总结

STM32 HAL库开发: 存储器和总线架构_第9张图片

Peripherals:外设的存储器映射,对该区域操作,就是对相应的外设进行操作;

SRAM:运行时临时存放代码的地方;

Flash:存放代码的地方;

System Memory:STM32出厂时自带的你只能使用,不能写或擦除;

Option Bytes:可以按照用户的需要进行配置(如配置看门狗为硬件实现还是软件实现);

后面就可以编写代码、程序运行、寄存器设置、ICP、IAP.

你可能感兴趣的:(STM32嵌入式,stm32)