1. 为什么我们需要理解分散加载文件
第一次接触Keil的sct分散加载文件时,大多数工程师都会感到困惑。我们平时写代码时,变量和函数似乎就在我们定义的位置上,但实际上,MCU的世界远比这复杂得多。编译后的程序会被拆分成各种段(section),这些段最终如何分布在芯片的存储空间中,完全由分散加载文件决定。
想象一下,你正在组装一个复杂的乐高模型。代码就像一个个乐高积木,而分散加载文件就是组装说明书,它决定了每个积木应该放在什么位置。如果没有这份说明书,即使你有再多的积木,也无法拼出想要的模型。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 分散加载文件基础解析
2.1 基本语法结构
分散加载文件的基本语法相对简单,但每个部分都承载着重要信息。一个典型的sct文件结构如下:
c复制; 注释以分号开头
加载域名称 起始地址 [属性] [最大尺寸] {
执行域名称 起始地址 [属性] [最大尺寸] {
输入段描述
}
}
以STM32为例,Flash通常从0x08000000开始,RAM从0x20000000开始。下面是一个最基本的配置示例:
c复制LR_IROM1 0x08000000 0x00100000 { ; 加载域:起始0x08000000,最大1MB
ER_IROM1 0x08000000 0x00100000 { ; 执行域(在Flash中执行)
*.o (RESET, +First) ; 异常向量表放在开头
*(InRoot$$Sections) ; 包含__main等
.ANY (+RO) ; 所有只读段
}
RW_IRAM1 0x20000000 0x00020000 { ; 执行域(RAM)
.ANY (+RW +ZI) ; 所有可读写和零初始化数据
}
}
2.2 关键概念解析
加载域(Load Region):以LR_开头,定义了程序最初被加载到芯片中的区域。对于大多数单片机应用,通常只有一个加载域,即Flash存储器。
执行域(Execution Region):以ER_开头,定义了代码和数据最终运行时的位置。一个加载域可以包含多个执行域,这是分散加载文件最强大的特性之一。
输入段描述:指定了哪些目标文件的哪些段应该被放入特定的执行域。格式通常为"模块名(段名, +属性)",其中:
- 模块名可以是具体的目标文件名或通配符
- 段名可以是通用的段类型(如RO、RW、ZI)或具体的节名(如.text、.data)
- 属性用于特殊控制,如+First表示放在区域开头
