内存划分包括 Flash存储器、SRAM 和 外设寄存器
STM32F407VETx 的内存划分包括 Flash存储器、SRAM 和 外设寄存器 三大部分。以下是详细的划分说明,并附上典型应用示例。
1. Flash 存储器(512KB)
地址范围:0x0800 0000 - 0x0807 FFFF
用途:存储程序代码(固件)、常量数据、配置参数等。
扇区划分(STM32F407VETx 只有 Sector 0~7):
扇区 | 起始地址 | 结束地址 | 大小 | 典型用途 |
---|---|---|---|---|
Sector 0 | 0x0800 0000 | 0x0800 3FFF | 16KB | 中断向量表 + 启动代码 |
Sector 1 | 0x0800 4000 | 0x0800 7FFF | 16KB | 核心固件(RTOS/Kernel) |
Sector 2 | 0x0800 8000 | 0x0800 BFFF | 16KB | 应用程序代码 |
Sector 3 | 0x0800 C000 | 0x0800 FFFF | 16KB | 应用程序代码 |
Sector 4 | 0x0801 0000 | 0x0801 FFFF | 64KB | 文件系统(FatFS/LittleFS) |
Sector 5 | 0x0802 0000 | 0x0803 FFFF | 128KB | 固件备份(OTA 备用区) |
Sector 6 | 0x0804 0000 | 0x0805 FFFF | 128KB | 用户数据(日志/配置) |
Sector 7 | 0x0806 0000 | 0x0807 FFFF | 128KB | 用户数据(大块存储) |
关键点:
- Sector 0 必须放中断向量表(Cortex-M4 强制要求)。
- Sector 5 可用于 OTA 升级,存放新固件,校验后跳转执行。
- Sector 6/7 适合存储配置数据(如 Wi-Fi 密码、校准参数)。
2. SRAM(192KB)
地址范围:0x2000 0000 - 0x2002 FFFF
用途:运行时变量、堆栈、动态内存分配。
SRAM 划分:
区域 | 地址范围 | 大小 | 用途 |
---|---|---|---|
SRAM1 | 0x2000 0000 - 0x2001 FFFF | 128KB | 主堆栈、全局变量、RTOS任务栈 |
SRAM2 | 0x2002 0000 - 0x2002 FFFF | 64KB | 高速缓存、DMA缓冲区 |
CCM RAM | 0x1000 0000 - 0x1000 FFFF | 64KB | 核心专用(无 DMA 访问) |
关键点:
- SRAM1:默认存储
.data
(已初始化变量)、.bss
(未初始化变量)、heap
(动态内存)、stack
(主堆栈)。 - SRAM2:适合 DMA 操作(如串口接收缓冲、SD卡读写)。
- CCM RAM:仅 CPU 可访问,适合实时性要求高的任务(如 PID 控制)。
示例链接脚本(GCC):
MEMORY {FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512KSRAM1 (rwx) : ORIGIN = 0x20000000, LENGTH = 128KSRAM2 (rwx) : ORIGIN = 0x20020000, LENGTH = 64KCCMRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K
}
3. 外设寄存器
地址范围:0x4000 0000 - 0x5003 FFFF
用途:控制 GPIO、USART、SPI、TIM 等外设。
典型外设地址:
- GPIOA:
0x4002 0000
- USART1:
0x4001 1000
- SPI1:
0x4001 3000
- TIM2:
0x4000 0000
访问方式(HAL 库示例):
GPIOA->MODER |= GPIO_MODER_MODER5_0; // 设置 PA5 为输出
USART1->BRR = 0x0683; // 设置波特率 115200
4. 内存管理策略
(1) Flash 管理
- 中断向量表 必须放在
0x0800 0000
(Sector 0)。 - OTA 升级:
- 新固件写入 Sector 5(128KB)。
- 校验成功后,修改向量表跳转地址。
- 配置存储:
#define CONFIG_ADDR 0x08060000 // Sector 6 起始地址 void Save_Config(void *data, uint32_t size) {HAL_FLASH_Unlock();FLASH_Erase_Sector(FLASH_SECTOR_6);for (int i = 0; i < size; i += 4) {HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, CONFIG_ADDR + i, *(uint32_t*)(data + i));}HAL_FLASH_Lock(); }
(2) SRAM 管理
- 堆栈分配(启动文件
startup_stm32f407xx.s
):_estack = 0x20020000; /* 栈顶 = SRAM1 末尾 */ Heap_Size EQU 0x2000; /* 8KB 堆 */ Stack_Size EQU 0x1000; /* 4KB 栈 */
- 动态内存管理(FreeRTOS 示例):
#define configTOTAL_HEAP_SIZE ((size_t)64 * 1024) // 64KB 给 FreeRTOS
(3) CCM RAM 优化
- 将高频访问的数据(如 PID 计算变量)放入 CCM:
__attribute__((section(".ccmram"))) float pid_error[100];
5. 典型内存布局(Keil 工程)
FLASH (512KB)
├─ 0x08000000:中断向量表(16KB)
├─ 0x08004000:RTOS 内核(16KB)
├─ 0x08008000:应用程序(32KB)
├─ 0x08010000:文件系统(64KB)
└─ 0x08060000:配置数据(128KB)SRAM (192KB)
├─ 0x20000000:全局变量 + 堆(128KB)
├─ 0x20020000:DMA 缓冲区(64KB)
└─ 0x10000000:核心数据(64KB,CCM)
总结
存储区 | 地址范围 | 大小 | 主要用途 |
---|---|---|---|
Flash | 0x0800 0000 - 0x0807 FFFF | 512KB | 程序代码、配置数据 |
SRAM1 | 0x2000 0000 - 0x2001 FFFF | 128KB | 堆、栈、全局变量 |
SRAM2 | 0x2002 0000 - 0x2002 FFFF | 64KB | DMA 缓冲区 |
CCM | 0x1000 0000 - 0x1000 FFFF | 64KB | 实时任务数据 |
推荐策略:
- Flash:前 16KB 放向量表,最后 128KB 存配置。
- SRAM:默认变量放 SRAM1,DMA 用 SRAM2,关键数据放 CCM。
- 外设:直接通过 HAL 库或寄存器操作。