Cortex-M MCU 默认的分散加载文件分析

发布于:2025-08-10 ⋅ 阅读:(17) ⋅ 点赞:(0)

你提供的这段代码是一个典型的 ARM Cortex-M MCU 的分散加载文件(Scatter-Loading Description File),通常由 Keil MDK(uVision)自动生成。它定义了程序在 Flash 和 RAM 中的存储布局,用于指导链接器(armlink)如何分配代码和数据段。下面详细解析它的结构和作用:


1. 文件结构解析

(1) 整体结构

LR_IROM1 0x08000000 0x00080000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00080000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x00010000  {  ; RW data
   .ANY (+RW +ZI)
  }
}
  • LR_IROM1:定义了一个 加载区域(Load Region),表示程序在 Flash 中的存储位置和大小。
  • ER_IROM1:定义了一个 执行区域(Execution Region),表示代码和只读数据在 Flash 中的执行地址。
  • RW_IRAM1:定义了一个 读写数据区域(RW Data Region),表示已初始化和未初始化的全局变量在 RAM 中的存储位置。

(2) 关键部分详解

LR_IROM1(加载区域)
LR_IROM1 0x08000000 0x00080000  {    ; load region size_region
  • LR_IROM1:加载区域的名称(可自定义)。
  • 0x08000000:Flash 的起始地址(STM32F1xx/4xx 的默认 Flash 起始地址)。
  • 0x00080000:Flash 的大小(512KB,即 0x80000 字节)。
  • 作用:定义整个程序在 Flash 中的存储范围。
ER_IROM1(执行区域)
  ER_IROM1 0x08000000 0x00080000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  • ER_IROM1:执行区域的名称(通常与加载区域同名,表示代码直接在 Flash 执行)。
  • 0x08000000 0x00080000:执行地址和大小(与加载区域相同,表示代码在 Flash 中运行)。
  • 内容
    • *.o (RESET, +First)
      • *.o:所有目标文件(.o)。
      • (RESET, +First):确保 RESET 段(通常是启动文件中的复位向量表)被放在 Flash 的最前面(地址 0x08000000)。
    • *(InRoot$$Sections)
      • 包含 CMSIS 或 RTOS 等库中的特殊段(如中断向量表、线程局部存储等)。
    • .ANY (+RO)
      • .ANY:匹配所有目标文件的段。
      • (+RO):将所有只读数据(.text.rodata)放入此区域。
    • .ANY (+XO)
      • (+XO):将可执行但不可读的段(如某些 ARM 架构的特殊段)放入此区域(较少使用)。
RW_IRAM1(读写数据区域)
  RW_IRAM1 0x20000000 0x00010000  {  ; RW data
   .ANY (+RW +ZI)
  }
  • RW_IRAM1:读写数据区域的名称。
  • 0x20000000 0x00010000:RAM 的起始地址(STM32F1xx/4xx 的默认 RAM 起始地址)和大小(64KB)。
  • .ANY (+RW +ZI)
    • .ANY:匹配所有目标文件的段。
    • (+RW +ZI):将所有已初始化(.data)和未初始化(.bss)的全局变量放入此区域。

2. 该分散加载文件的作用

(1) 代码存储在 Flash(ER_IROM1

  • RESET:确保复位向量表位于 Flash 起始地址(0x08000000),这是 Cortex-M 的硬件要求。
  • .text.rodata:所有代码和只读数据(如常量字符串)存储在 Flash 中。
  • .data 初始值:已初始化的全局变量初始值也存储在 Flash 中(运行时需拷贝到 RAM)。

(2) 数据存储在 RAM(RW_IRAM1

  • .data:已初始化的全局变量在程序启动时从 Flash 拷贝到 RAM。
  • .bss:未初始化的全局变量在 RAM 中清零。

3. 对比 Keil 默认生成的 .sct 文件

你提供的文件是 Keil MDK 的分散加载描述文件,而之前讨论的 .sct 文件是 ARM-GCC 的分散加载文件。它们的功能类似,但语法不同:

特性 Keil 分散加载描述文件 ARM-GCC .sct 文件
文件格式 文本,但由 Keil 图形界面生成 纯文本,手动编辑
语法 LR_XXXER_XXXRW_XXX MEMORYSECTIONS
适用工具链 Keil MDK(ARMCC) ARM-GCC(arm-none-eabi-gcc
灵活性 较简单,适合快速配置 更灵活,支持复杂内存布局

4. 实际应用中的注意事项

(1) 确保 Flash 和 RAM 地址正确

  • Flash 起始地址:STM32F1xx/4xx 通常是 0x08000000,但不同型号可能不同(如 STM32F7 是 0x08000000 或更高)。
  • RAM 起始地址:STM32F1xx/4xx 通常是 0x20000000,大小需与芯片规格一致(如 STM32F407 有 192KB RAM)。

(2) 特殊段的处理

  • RESET:必须位于 Flash 起始地址,否则 MCU 无法正常启动。
  • 中断向量表:通常由启动文件(startup.s)定义,需确保它在 RESET 段中。

(3) 调试与验证

  • 查看内存映射:使用 Keil 的 Memory Map 功能(Project -> Options for Target -> Linker -> Map File)生成 .map 文件,确认各段地址是否符合预期。
  • 调试时检查变量地址:在 Keil 调试器中查看全局变量的地址,确认它们是否位于 RW_IRAM1 区域。

5. 总结

  • Keil 的分散加载描述文件 定义了程序在 Flash 和 RAM 中的存储布局,确保代码和数据正确分配。
  • 核心部分
    • LR_IROM1:定义 Flash 的存储范围。
    • ER_IROM1:定义代码和只读数据的执行地址(通常直接在 Flash 运行)。
    • RW_IRAM1:定义全局变量和静态变量的 RAM 存储位置。
  • 与 GCC 的 .sct 文件对比:功能类似,但语法和工具链不同。
  • 关键点:确保 RESET 段位于 Flash 起始地址,并正确分配 .data.bss 段到 RAM。

通过合理配置分散加载文件,可以优化 MCU 的内存使用,确保程序正确运行。


网站公告

今日签到

点亮在社区的每一天
去签到