内容简介:ROM可以理解为硬盘,SRAM理解为内存。前者掉电不丢失,但是读写慢,后者掉电丢失,读写快。 ROM中储存了只读(RO-SECTION)段,以及读写段(RW-section)。 显然,RO段是用作bootloader的。而RW段用来存储文件系统的。当工程按默认配置构建时, MDK 会根据我们选择的芯片型号,获知芯片的内部 FLASH 及内部 SRAM 存储器概况,生成一个以工程名命名的后缀为*.sct 的分散加载文件 (Linker Control File, scatter loading)。程序启动后链
1.预处理 gcc -E 2.编译 gcc -S 3.汇编 gcc -C 4.连接 gcc -l 复制代码
- 预处理
- 一般就是处理宏以及头文件
- 编译
- 在这个阶段将 C语言 转化为汇编代码。
- 一般会进行程序的优化
- 汇编
- 将汇编代码转化为机器码
- 连接
- 将所有目标文件按照连接脚本的要求进行链接
- 在这个时候,什么代码段,数据段之类的就可以进行位置的指定了。
- 在这个阶段就出现了位置无关码之类的名词以及动态链接和静态链接
- 最终在链接后生成了可执行文件
程序组件 | 所属类别 |
---|---|
机器代码指令 | Code |
常量 | RO-data |
初值非0的全局变量 | RW-data |
初值为0的全局变量 | ZI-data |
局部变量 | ZI-data栈空间 |
使用malloc动态分配的空间 | ZI-data堆空间 |
ROM可以理解为硬盘,SRAM理解为内存。前者掉电不丢失,但是读写慢,后者掉电丢失,读写快。 ROM中储存了只读(RO-SECTION)段,以及读写段(RW-section)。 显然,RO段是用作bootloader的。而RW段用来存储文件系统的。
程序状态与区域 | 组成 |
---|---|
程序执行时的只读区域(RO) | Code + RO data |
程序执行时的可读写区域(RW) | RW data + ZI data |
程序存储时占用的ROM区 | Code + RO data + RW data |
*.dep,*.d依赖文件
- Dependency file
- 记录的是工程或其它文件的依赖,主要记录了引用的头文件路径,其中*.dep是整个工程的依赖,它以工程名命名,而*.d是单个源文件的依赖,它们以对应的源文件名命名。
*.crf交叉引用文件
- Cross-Reference file
- 它主要包含了浏览信息(browse information),即源代码中的宏定义、变量及函数的定义和声明的位置。
o、axf及elf文件
- *.o、*.elf、*.axf以及前面提到的lib文件都是属于目标文件,它们都是使用ELF格式来存储的。
- Executable and Linking Format
- 目标文件主要有如下三种类型
- 可重定位的文件(Relocatable File),包含基础代码和数据,但它的代码及数据都没有指定绝对地址,因此它适合于与其他目标文件链接来创建可执行文件或者共享目标文件。 这种文件一般由编译器根据源代码生成。
- 可执行文件(Executable File) ,它包含适合于执行的程序,它内部组织的代码数据都有固定的地址(或相对于基地址的偏移),系统可根据这些地址信息把程序加载到内存执行。这种文件一般由链接器根据可重定位文件链接而成,它主要是组织各个可重定位文件,给它们的代码及数据一一打上地址标号,固定其在程序内部的位置,链接后,程序内部各种代码及数据段不可再重定位(即不能再参与链接器的链接)。
- 共享目标文件(Shared Object File), 它的定义比较难理解,我们直接举例,MDK生成的*.lib文件就属于共享目标文件,它可以继续参与链接,加入到可执行文件之中。另外,Linux的.so,如/lib/ glibc-2.5.so,Windows的DLL都属于这一类
常见文件类型
sct 分散加载文件的格式与应用
当工程按默认配置构建时, MDK 会根据我们选择的芯片型号,获知芯片的内部 FLASH 及内部 SRAM 存储器概况,生成一个以工程名命名的后缀为*.sct 的分散加载文件 (Linker Control File, scatter loading)。
程序启动后链接地址和启动地址有可能不一样。会有一段程序将所有的程序自举到链接地址指定的地方。
储存 | 大小(十进制) | 大小(十六进制) | 起始地址 |
---|---|---|---|
片上储存 RAM(ITCM) | 512K | 0x0008 0000 | 0x0000 0000 |
off-chip SDRAM | 32M | 0x0200 0000 | 0x8000 0000 |
QSPI nor Flash | 32M | 0x0200 0000 | 这个是由自己映射的 |
NAND Flash | 128M | 0x8000 0000 | 同样是自己映射的 |
片上 DTCM | 512k | 0x0008 0000 | 0x2000 0000 |
假设使用 QSPI nor flash。将其映射到 0x80000000的地址(SEMC external memories 起始地址)。
#define m_data_start 0x80000000 #define m_data_size 0x01E00000 #define m_ncache_start 0x81E00000 #define m_ncache_size 0x00200000 #define m_data2_start 0x20000000 #define m_data2_size 0x00020000 #define m_data3_start 0x20200000 #define m_data3_size 0x00040000 复制代码
如上,分为了四个段。
- m_data_start 与 m_ncache_start 共同占据所有QSPI nor flash的地址。
- m_data2_start 与 m_data3_start 共同占据部分DTCM区域
- 那么最上面图中IRAM2配置的就是ITCM的区域了。只不过ITCM的大小是可以配置的。猜测是为了兼容以前的芯片。
- 不过以前只是用过arm9。不清楚ITCM的操作,等以后补上。
程序状态与区域 | 组成 |
---|---|
程序执行时的只读区域(RO) | Code + RO Data |
程序执行时的读写区域(RW) | RW Data+ ZI Data |
程序储存时的占用区域(ROM) | Code + RO Data +RW Data |
节区属性描述符 | 说明 |
---|---|
RO code & Code | 只读代码段 |
RO Data & Const | 只读数据段 |
RO & TEXT | 包括RO code 和 RO Data |
RW Data | 读写数据段 |
RW CODE | 读写代码段 |
RW & Data | 包括 RW Data 和 RW Code |
ZI & BSS | 初始为0的段 |
XO | 只可执行的段 |
ENTRY | 节区的入口 |
上面 m_data_start 表示的是片上chip的可读写区域开始地址。
- m_flash_config_start 就是片上flash的起始地址以及大小。
- m_data2_start 就是片外的sdram的起始地址以及大小。
更正
*.sct文件 改成 *.scf 文件。在工程文件中没找到*.sct。兴许是改名字了。但是没找到关于官方文件的解释。暂且先这样。
参考资料
MDK的编译过程及文件类型全解 https://flash-rtd.readthedocs.io/zh_CN/latest/ MDK的帮助手册 《ARM Development Tools》 Keil sct分散加载文件 https://blog.csdn.net/kobesdu/article/details/38258449 KEIL下分散加载文件 *.sct文件 http://www.cnblogs.com/darren-715/p/3457214.html MDK的编译过程及文件类型全解 https://www.cnblogs.com/yangguang-it/p/7697967.html 配置DTCM,ITCM和OCRAM http://forum.armfly.com/forum.php?mod=viewthread&tid=86733 如何让RT1050的代码运行速度飞起来 http://www.eeworld.com.cn/mp/ZLG/a57247.jspx 复制代码
以上所述就是小编给大家介绍的《MDK编译过程及文件类型全解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。