[Cortex-M3]-3-分散加载文件解析(.sct)
- [Cortex-M3]-1-启动流程-启动文件
- [Cortex-M3]-2-map文件解析
- [Cortex-M3]-3-分散加载文件解析(.sct)
- [Cortex-M3]-4-如何在内嵌RAM中运行程序
目录
1 分散加载文件.sct
2 如何生成.sct文件
3 *(InRoot$$Sections) 说明
4 如何修改分散加载文件
5 已经初始化变量的初值,存储位置
6 +RW +ZI和+RO如何执行
1 分散加载文件.sct
MDK的分散加载主要是通过.sct文件实现的,链接器根据.sct文件的配置分配各个节区地址,生成分散加载代码,因此通过修改该文件可以定制具体节区的存储位置。
那为什么需要分散加载文件呢?不用可以吗?
一般情况下,可以不独自编写分散加载文件,ARM链接器直接按照默认的方式来生成映像文件即可,但是在某些场合,希望将某些数据放在指定的位置,此时分散加载文件就发挥了非常发的作用。比如在下面几种情况:
- 复杂内存映射:如果必须将代码和数据放在多个不同的内存区域中,则需要使用详细指令指定将哪些数据放在哪个内存空间中。
- 不同类型的内存:许多系统都包含多种不同的物理内存设备,如闪存、 ROM、 SDRAM 和快速 SRAM。分散加载描述可以将代码和数据与最适合的内存类型相匹配。例如,可以将中断代码放在快速 SRAM 中以缩短中断等待时间,而将不经常使用的配置信息放在较慢的闪存中。
- 位于固定位置的函数:可以将函数放在内存中的固定位置,即使已修改并重新编译周围的应用程序。
- 使用符号标识堆和堆栈:链接应用程序时,可以为堆和堆栈位置定义一些符号。
2 如何生成.sct文件
在Options->Targets->Linker界面下面去掉默认选项,然后edit... 就可以在编辑界面中看到.sct文件了。
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************LR_IROM1 0x08000000 0x00020000 { //定义一个加载域,域地址0x08000000,域大小为0x00020000//load region size_region 所有代码需要下载到0x08000000 开始的区域中,且这个区域大小只有0x00010000 ER_IROM1 0x08000000 0x00020000 { //load address = execution address 第一个运行时域必须和加载域起始地址相同,其大小一般也相同//只能是只读的代码段和只读数据段*.o (RESET, +First) //启动代码的首次执行地址,RO执行域名称为ER_IROM1, //将 RESET 段最先加载到本域的起始地址外//首次执行的地址为RESET标号所表示的地址,RESET 存储的是向量表//对应启动文件中的AREA RESET, CODE, READONLY*(InRoot$$Sections) //稍后文件中会单独讲到.ANY (+RO)//加载所有匹配目标文件的只读属性数据,包含:Code、 RW-Code、 RO-Data。}RW_IRAM1 0x20000000 0x00005000 { //再定义一个运行时域,域基址0x20000000 //RW data 执行域是以0x20000000 开始的长度为0x00004000 一段区域.ANY (+RW +ZI) //其中包括的是哪些文件}
}
3 *(InRoot$$Sections) 说明
.sct本身并不能对映像实现“解压缩”,编译器读入.sct文件之后,会根据其中的各种地址生成启动代码,实现对映像的加载,而这一段代码就是*(InRoot$$Sections)它是__main()的一部分。这就是在汇编启动代码的最后跳转到__main()而不是跳向main()的原因之一。
起始地址与加载域重合的执行域称为root region,*(InRootSections)必须放在这个执行域中,否则链接的时候会报错。
4 如何修改分散加载文件
如果需要修改分散加载文件,并使其生效可以通过以下步骤操作进行:
- 修改Options->Targets->Target 的onchip 的rom或者ram,容量地址必须和选择的芯片一致
- 修改某个文件的存储属性,在工程窗口中右击文件名字 Options for file ,然后出现窗口可以修改文件的存储属性
- 修改完,重新编译,点开.sct文件就可以看到.sct已经被修改了,然后可以看map文件可以看到相关变量函数地址信息已经改变。
5 已经初始化变量的初值,存储位置
int tick = 20; 会放在哪里呢?
编译完成
已经初始化的变量,是被放入RW属性的输入节中,而这些变量的初值,是被放入ROM/Flash中的。
那这些初值是谁在何时将它们恢复到RAM中的?
ZI属性输入节中的变量所在RAM又是谁在何时给用零初始化的呢?
接下来继续下一个章节来继续梳理《7 +RW +ZI和+RO如何执行》
6 +RW +ZI和+RO如何执行
- 硬件复位后,第一步是执行复位处理程序,程序的入口在启动代码里(启动代码里面讲过);
- 初始化堆栈指针、执行完用户定义的底层初始化代码(SystemInit函数)后,接下来的代码调用了__main函数;
- __main函数会调用一些列的C库函数,完成代码和数据的复制、解压缩以及ZI数据的零初始化,数据的解压缩和复制,其中就包括将储存在ROM/Flash中的已初始化变量的初值复制到相应的RAM中去。(解释了上一章节的问题:那这些初值是谁在何时将它们恢复到RAM中的?)
- 对于一个变量,它可能有三种属性,用const修饰符修饰的变量最可能放在RO属性区,已经初始化的变量会放在RW属性区,那么剩下的变量就要放到ZI属性区。默认情况下,ZI数据的零初始化会将所有ZI数据区初始化为零,这是每次复位后程序执行C代码的main函数之前,由编译器自主完成。
- 要在C代码中设置一些变量在复位后不被零初始化,那一定不能任由编译器“自主完成”,要用一些规则,约束一下编译器。这时候我们的.sct的作用就显示出来了。在分散加载文件中,使用UNINIT来修饰一个运行时域。可以避免__main对该区节的ZI数据进行零初始化。(解释了上一章节的问题:ZI属性输入节中的变量所在RAM又是谁在何时给用零初始化的呢?);
[Cortex-M3]-3-分散加载文件解析(.sct)相关推荐
- 小猫爪:嵌入式小知识06-KEIL scf分散加载文件解析-链接代码至RAM
小猫爪:嵌入式小知识06-KEIL scf分散加载文件解析-链接代码至RAM 1 前言 2 执行域和加载域 2 相关语法解析 3 实例解说 4 链接代码至RAM运行 4.1 链接单个section至R ...
- IMXRT 分散加载文件 修改OCRAM,DTCM、ITCM大小
分散加载 MXRT1052/1064芯片的RAM空间分为四种类型:ITCM,DTCM,OCRAM以及外部SDRAM,其中前面三个属于芯片内部RAM,RT1052有512KB,RT1064为1MB,支持 ...
- 【转载】ADS分散加载文件使用总结(lpc23xx)
有如下分散加载文件: ROM_LOAD 0x00000000 ;// Origination Point of Code (Code in Flash) { ROM_ ...
- 从MDK分散加载文件学习STM32启动流程
一直在用ARM的Cortex-M系列做产品开发,也陆陆续续学习了ARM的启动流程.汇编启动文件,但是总感觉没有连贯的把全部知识串起来,不知道某些汇编语句为什么要这么写,没法按照自己的情况进行修改.今天 ...
- keil的sct文件_keil .sct分散加载文件及其应用(重点必看)
(3)分散加载文件语法 load_region_name start_address | "+"offset [attributes] [max_size] { executi ...
- keil STM32中sct 分散加载文件学习
sct 分散加载文件简介 MDK 生成一个以工程名命名的后缀为 *.sct 的分散加载文件 (Linker Control File,scatter loading),链接器根据该文件的配置分配各个节 ...
- 浅析keil的scf分散加载文件-基于STM32的例程
浅析keil的scf分散加载文件-基于STM32的例程 关于分散加载文件 分散加载文件.sct 关于分散加载文件 keil编译器在链接的时候,是根据分散加载(.scf后缀的文件)来确定程序的加载域和运 ...
- Scatterfile分散加载文件和 mem.scf
今天仔细学习周立功的模板的过程中,发现了几个.scf文件,自己不知道这是什么东西,所以学习了下: (一) 这是一位网友写的关于mem_a.scf,mem_b.scf,mem_c.scf文件的见解 ...
- [STM32] 分散加载文件 之一 (初探)
转载自: http://bbs.21ic.com/icview-2579020-1-1.html 本帖最后由 千岁寒 于 2018-11-5 13:00 编辑 1.什么是分散加载 ...
最新文章
- 据说是腾讯php程序员面试题目 蛋疼..要是提供PHP手册就HI了..
- 让你的JS代码更具可读性
- PHP安装wamp设置虚拟目录后,无法访问localhost问题
- C语言经典算法100例-031-判断星期几
- 兴图视频指挥系统如何配置服务器,兴图新科指挥调度终端
- 所有的shadow map的名称
- android 闪屏页处理_Android应用闪屏页延迟跳转的三种写法
- Java CXF介绍与实例
- 使用SQL Server Management Studio 创建数据库备份作业
- Oracle USE_LARGE_PAGES初始化参数
- linux安装番茄时钟,Tomato Pie番茄钟
- java修改头像代码_用户修改头像功能
- ubuntu虚拟机联网配置
- 图像中的Exif信息及其处理
- MIT License探讨
- Java微信SDK方式进行网页授权
- zyt-python
- 蓝桥杯刷题冲刺 | 倒计时14天
- js身份证号码带*号处理
- linux 显示bin 文件格式,bin文件扩展名,bin文件怎么打开?
热门文章
- 员工管理系统实现方案
- 【十五】 VVC/H.266 | 帧内帧间联合预测技术CIIP详解
- 网络发现自动关闭不能启用、无法启用文件和打印共享的解决办法
- B站网页视频加速设置
- 数据库的备份和恢复(笔记)
- “入门大数据分析:探索海量数据的奥秘“
- 批量修改视频尺寸,如此操作简单又专业
- linux_系统帮助propos/whatis/which/whereis/man/info/help...)/bashzsh/build-in command帮助/wildcard/regex
- Linux中vmstat命令详解
- Mask Scoring R-CNN