硬件环境:STM32F103C8T6
1、内核架构
从这个宏观的内部结构图可以看到,内核和外设、存储器、时钟与复位和IO口都是通过内部总线来实现数据的获取。
从这个系统结构图中,可以看到,Cortex-M3内核芯片的内部结构非常的复杂,有四个驱动单元和四个被动单元组成,四个驱动单元为Cortex-M3的数据总线和系统总线,两个DMA(直接存储器访问单元);四个被动单元为单片机的内存flash、闪存SRAM、可变的静态存储器控制器FSMC(用于给单片机扩展静态内存)、外设(片载资源)
四个驱动单元 | |
Cortex-M3 | 数据总线(Dcode)、系统总线(System) |
DMA | 两个DMA总线(绕过内核直接访问内核和I/O设备) |
四个被动单元 | |
内存Flash | 用于存储系统数据(代码、常量数据) |
闪存SRAM | 用于存储临时数据 |
可变静态存储控制器FSMC | 用于扩展静态内存 |
外设 | 用于访问片载资源 |
从Cortex-M3内核出来三根线总线,ICode、DCode、System。
Icode :指令总线->指令读取操作总线;默认映射到0x00000000-0x1FFFFFFF内存地址段
Dcode :数据总线->数据读取操作总线;默认映射到0x00000000~0x1FFFFFFF内存地址段
System:系统总线->访问系统级的寄存器和配置总线;默认映射到0x20000000~0xDFFFFFFF和0xE0100000~0xFFFFFFFF两个内存地址段
1、Cortex-M3内核通过Icode总线获取内部Flash中的程序代码。
2、Dcode数据总线(处理所有与数据有关的操作),从内部Flash中获取常量数据,访问各种外设寄存器、SRAM以及程序运行时的变量和临时数据。
3、System系统总线,用于访问和配置系统级的寄存器和控制单元,确保系统正常运行和管理。(配置和管理:时钟、电源、中断优先级、系统寄存器)
系统寄存器:
地址范围:通常位于特定的地址空间,如 0xE000E000 - 0xE000EFFF
具体寄存器:系统控制寄存器(SCB)、中断控制寄存器(NVIC)、系统定时器寄存器(SysTick)、调试寄存器(DWT)
外设寄存器:
地址范围:通常位于特定的地址空间,如 0x40000000 - 0x4001FFFF
具体外设:GPIO寄存器、定时器寄存器、SPI寄存器、USART寄存器
时钟管理(CMU):
具体任务:1.配置和管理外设的时钟源、2.配置和管理CPU的时钟、3.配置和管理系统时钟的分频和倍频
电源管理单元:
具体任务:1.配置和管理外设电源状态、2.配置和管理CPU的电源状态、3.配置和管理系统的低功耗模式
例如:在STM32F103C8T6中
Flash:
地址范围:0x08000000 - 0x0800FFFF
用途: 存储代码和常量数据
总线: Icode总线、Dcode总线
SRAM:
地址范围:0x20000000 - 0x20004FFF
用途: 存储程序运行时的变量和临时数据
总线: Dcode总线#include "stm32f10x.h"
// 定义一个存储在 Flash 中的常量
const uint32_t flash_data[] __attribute__((section(".flash"))) = {0x12345678, 0x87654321};
// 定义一个存储在 SRAM 中的变量
uint32_t sram_data = 0xAAAAAAAA;
int main(void) {
// 使能备份寄存器时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
// 读取 Flash 中的常量数据(通过 DCode 总线)
uint32_t read_flash_data = flash_data[0];
// 读取 SRAM 中的变量数据(通过 DCode 总线)
uint32_t read_sram_data = sram_data;
// 打印数据
printf("Flash Data: 0x%08X\n", read_flash_data);
printf("SRAM Data: 0x%08X\n", read_sram_data);
while (1) {
// 主循环
}
}
1.1 Cortex-M3
对于内核本身而言,其内部结构图如图所示
Register Bank(寄存器组) :用于存储CPU运行时的指令指针,状态标志等
ALU(算术逻辑单元) :用于执行算术和逻辑运行
Decoder(解码器) :用于解析指令,确保指令被CPU正确理解
Instruction Fetch Unit(指令获取单元):用于从指令存储器中读取指令
NVIC(中断嵌套控制寄存器) :用于管理中断和异常,处理中断请求、优先级管理、中断使能和禁止,以及中断服务服务例程的调度
Memory interface(内存接口) :与内存和外设进行数据交互,内存接口负责处理CPU内与内存(flash、SRAM)、外设(GPIO、SPI)之间的数据读写操作
Memory Protection Unit(存储保护单元) :用于存储器保护单元
Debug System(跟踪系统) :
Bus Interconnect(总线矩阵) :用于连接各个外设和片载寄存器
Debug interface(调试接口) :用于调试
1.2 DMA
从DMA出来只有DMA总线,这两个DMA有着与内核同等的地位,它的作用就是在硬件上绕过内核,直接访问内存和I/O设备之间开辟一条数据传输的通路。目的是降低内核开销,提高效率。
STM32F103C8T6内置两个DMA,DMA1有7个通道、DMA2有5个通道。没有给DMA通道可以独立配置,处理特定外设数据传输任务
通道0:用于SPI1的接收和发送
通道1:用于I2C1的接收和发送
通道2:用于USART1的接收和发送
通道3:用于ADC的数据传输
通道4:用于SPI2的接收和发送
通道5:用于I2C2的接收和发送
通道6:用于USART2的接收和发送DMA用在:SPI1、2;I2C1、2;ADC和USART1、2(四钟类型可用DMA功能)
2、寄存器组
2.1 通用寄存器
Cortex-M3拥有R0-R15一共16个寄存器,其中R0-R12是通用寄存器、R13-R15是特殊寄存器。(每个寄存器是32位)
通用寄存器用于数据操作,绝大多数16位thumb指令只能访问R0-R7寄存器,32位Thumb指令可以访问所有寄存器。
R13分为两个堆栈寄存器,分别是主堆栈指针MSP和进程堆栈指针PSP,同一时刻只能使用其中一个,堆栈指针的低两位永远是0,堆栈总是4字节对齐。
MSP和PSP都是完整的32位寄存器,各自独立。
MSP:用于操作系统和中断处理程序
PSP:用于用户模式下的线程
内核通过状态寄存器xPSR中的栈指针选择位(SPSEL)来选择当前使用堆栈指针:
当SPSEL为0时,使用MSP
当SPSEL为1时,使用PSP
R14连接寄存器LR:当调用一个函数时,LR记录调用函数返回的地址,调用关系超过两层时,则会一级一级将函数的返回值压入栈中
R15程序计数寄存器PC:指向下一个要执行的指令的地址
2.2 特殊功能寄存器
寄存器 | 功能 |
---|---|
xPSR | 记录ALU标志(0标志,进位标志,负数标志,益出标志),执行状态,以及当前服务的中断号 |
PRIMAKS | 除能所有的中断。当为1时,表示仅允许NMI和Hard fault异常,其它所有的中断和异常都会被屏蔽,默认为0。中断屏蔽寄存器 |
FAULTMASK | 当为1时,表示仅允许NMI异常,其它所有中断和错误处理异常都会被屏蔽。默认为0。中断屏蔽寄存器 |
BASEPRI | 最多8位(却决于芯片应用的优先级数),表示屏蔽优先级的等级,屏蔽所有比改优先级低和相同的中断(中断优先级,数字越大约低),默认为0。中断屏蔽寄存器 |
CONTROL | 控制寄存器,定义特权状态,决定使用哪一个堆栈指针 |
2.2.1 xPSR
xPSR寄存器是程序状态寄存器的意思,x有三个小的寄存器构成:APSR、IPSR、EPSR。
APSR(应用程序状态寄存器):存储应用程序相关的状态信息,主要用于条件执行和状态标志
IPSR(中断程序状态寄存器):存储与中断相关的状态信息,主要用于中断处理
EPSR(执行程序状态寄存器):存储与执行相关的状态信息,主要用于指令流水线和异常处理
2.2.2 PRIMASK
这是一个1bit的寄存器,当为1时,表示仅允许NMI和Hard fault异常可以响应,其它所有的中断和异常都会被屏蔽,默认为0。中断屏蔽寄存器
2.2.3 FAULTMASK
这是一个1bit的寄存器,当为1时,表示仅允许NMI异常,其它所有中断和错误处理异常都会被屏蔽。默认为0。中断屏蔽寄存器
2.2.4 BASEPRI
这个寄存器最多有 8 bit(由表达优先级的位数决定)。它定义了被屏蔽优先级的阈值;换言之,当这个寄存器被设置某个数值后,所有优先级号大于等于该值的中断都被关闭(优先级号越大,优先级越低);默认值是0,也就是不关闭任何中断
2.2.5 CONTROL
控制寄存器由2个bit构成,
CONTROL[0]:用来指明运行的CPU的特权级别
CONTROL[1]:用来指明使用的堆栈类型
3、存储空间分配
Cortex-M3,最大支持4GB存储空间
3.1 System Level空间
这个512MB空间又叫系统区,0xE000_0000 - 0xFFFF_FFFF,用于私有外设和供应商指定功能区,不可执行代码。
Vendor-specific:系统/供应商定义
Private peripheral bus-External:外部私有外设总线
Private peripheral bus-Internal:内部私有外设总线
ROM Table(ROM表):一个查找表,存储了配置信息
External PPB:外部私有外设总线
ETM:嵌入式跟踪单元,调试用,用于处理程序跟踪
TPIU:跟踪单元的接口单元,所有跟踪单元发出的调试信息都要先送给他,他在转发给外部跟踪捕获硬件
NVIC:嵌套向量中断控制器
FPB :Flash地址重载及断点单元
DWT :数据观察及跟踪单元,调试用
ITM :仪器化跟踪宏单元
3.2 External Device
外部设备区,1GB内存,用于连接外部设备。
0xA000_0000 - 0xBFFF_FFFF:不可缓存,不可执行指令
0xC000_0000 - 0xDFFF_FFFF:不可缓存,不可执行指令
3.3 External RAM
外部RAM区 ,1GB内存,用于连接外部 RAM。
前半部0x6000_0000 - 0x7FFF_FFFF 可缓存
0x8000_0000 - 0x9FFF_FFFF 不可缓存
3.4 Peripherals(片上外设)
片上外设,0x4000_0000 - 0x5FFF_FFFF,512MB,用于片上外设的寄存器。32MB 的位带别名区,便于快捷访问外设寄存器。
片上外设区低1MB范围:0x40000000-0x400FFFFF,对于的位带别名区:0x42000000-0x43FFFFFF
3.5 SRAM
内部SRAM,0x2000_0000 - 0x3FFF_FFFF,512MB,用于连接片上 SRAM,通过系统总线访问。1MB 的位带区,对应 32MB 的位带别名区。位带别名区中的每个字对应位带区的一个比特,支持原子操作。
SRAM区低1MB范围:0x20000000-0x200FFFFF,对于的位带别名区:0x22000000-0x23FFFFFF
3.6 Code
代码区,0x0000_0000 - 0x1FFF_FFFF,512MB
4 存储映射
0x0000 0000 - 0x0800 0000 根据Boot引脚配置,映射Flash/Sysmem/SRAM当中的128MB空间
0x0800 0000 - 0x0801 FFFF Flash Memory闪存存储空间128KB
0x1FFF F800 - 0x1FFF F7FE System Memory系统存储空间2KB
0x2000 0000 - 0x3FFF FFFF SRAM 存储区