1. [Cortex-M3]-1-启动流程-启动文件
  2. [Cortex-M3]-2-map文件解析
  3. [Cortex-M3]-3-分散加载文件解析(.sct)
  4. [Cortex-M3]-4-如何在内嵌RAM中运行程序

目录

1 分散加载文件.sct

2 如何生成.sct文件

3 *(InRoot$$Sections) 说明

4 如何修改分散加载文件

5 已经初始化变量的初值,存储位置

6 +RW +ZI和+RO如何执行


1 分散加载文件.sct

MDK的分散加载主要是通过.sct文件实现的,链接器根据.sct文件的配置分配各个节区地址,生成分散加载代码,因此通过修改该文件可以定制具体节区的存储位置

那为什么需要分散加载文件呢?不用可以吗?

一般情况下,可以不独自编写分散加载文件,ARM链接器直接按照默认的方式来生成映像文件即可,但是在某些场合,希望将某些数据放在指定的位置,此时分散加载文件就发挥了非常发的作用。比如在下面几种情况:

  1. 复杂内存映射:如果必须将代码和数据放在多个不同的内存区域中,则需要使用详细指令指定将哪些数据放在哪个内存空间中。
  2. 不同类型的内存:许多系统都包含多种不同的物理内存设备,如闪存、 ROM、 SDRAM 和快速 SRAM。分散加载描述可以将代码和数据与最适合的内存类型相匹配。例如,可以将中断代码放在快速 SRAM 中以缩短中断等待时间,而将不经常使用的配置信息放在较慢的闪存中。
  3. 位于固定位置的函数:可以将函数放在内存中的固定位置,即使已修改并重新编译周围的应用程序。
  4. 使用符号标识堆和堆栈:链接应用程序时,可以为堆和堆栈位置定义一些符号。

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 如何修改分散加载文件

如果需要修改分散加载文件,并使其生效可以通过以下步骤操作进行:

  1. 修改Options->Targets->Target 的onchip 的rom或者ram,容量地址必须和选择的芯片一致
  2. 修改某个文件的存储属性,在工程窗口中右击文件名字 Options for file ,然后出现窗口可以修改文件的存储属性
  3. 修改完,重新编译,点开.sct文件就可以看到.sct已经被修改了,然后可以看map文件可以看到相关变量函数地址信息已经改变。

5 已经初始化变量的初值,存储位置

int tick = 20;        会放在哪里呢?

编译完成

已经初始化的变量,是被放入RW属性的输入节中,而这些变量的初值,是被放入ROM/Flash中的。

那这些初值是谁在何时将它们恢复到RAM中的?

ZI属性输入节中的变量所在RAM又是谁在何时给用零初始化的呢?

接下来继续下一个章节来继续梳理《7 +RW +ZI和+RO如何执行》

6 +RW +ZI和+RO如何执行

  1. 硬件复位后,第一步是执行复位处理程序,程序的入口在启动代码里(启动代码里面讲过);
  2. 初始化堆栈指针、执行完用户定义的底层初始化代码(SystemInit函数)后,接下来的代码调用了__main函数;
  3. __main函数会调用一些列的C库函数,完成代码和数据的复制、解压缩以及ZI数据的零初始化,数据的解压缩和复制,其中就包括将储存在ROM/Flash中的已初始化变量的初值复制到相应的RAM中去。(解释了上一章节的问题:那这些初值是谁在何时将它们恢复到RAM中的?)
  4. 对于一个变量,它可能有三种属性,用const修饰符修饰的变量最可能放在RO属性区,已经初始化的变量会放在RW属性区,那么剩下的变量就要放到ZI属性区。默认情况下,ZI数据的零初始化会将所有ZI数据区初始化为零,这是每次复位后程序执行C代码的main函数之前,由编译器自主完成。
  5. 要在C代码中设置一些变量在复位后不被零初始化,那一定不能任由编译器“自主完成”,要用一些规则,约束一下编译器。这时候我们的.sct的作用就显示出来了。在分散加载文件中,使用UNINIT来修饰一个运行时域。可以避免__main对该区节的ZI数据进行零初始化。(解释了上一章节的问题:ZI属性输入节中的变量所在RAM又是谁在何时给用零初始化的呢?);

[Cortex-M3]-3-分散加载文件解析(.sct)相关推荐

  1. 小猫爪:嵌入式小知识06-KEIL scf分散加载文件解析-链接代码至RAM

    小猫爪:嵌入式小知识06-KEIL scf分散加载文件解析-链接代码至RAM 1 前言 2 执行域和加载域 2 相关语法解析 3 实例解说 4 链接代码至RAM运行 4.1 链接单个section至R ...

  2. IMXRT 分散加载文件 修改OCRAM,DTCM、ITCM大小

    分散加载 MXRT1052/1064芯片的RAM空间分为四种类型:ITCM,DTCM,OCRAM以及外部SDRAM,其中前面三个属于芯片内部RAM,RT1052有512KB,RT1064为1MB,支持 ...

  3. 【转载】ADS分散加载文件使用总结(lpc23xx)

    有如下分散加载文件: ROM_LOAD 0x00000000              ;// Origination Point of Code (Code in Flash) {     ROM_ ...

  4. 从MDK分散加载文件学习STM32启动流程

    一直在用ARM的Cortex-M系列做产品开发,也陆陆续续学习了ARM的启动流程.汇编启动文件,但是总感觉没有连贯的把全部知识串起来,不知道某些汇编语句为什么要这么写,没法按照自己的情况进行修改.今天 ...

  5. keil的sct文件_keil .sct分散加载文件及其应用(重点必看)

    (3)分散加载文件语法 load_region_name  start_address | "+"offset  [attributes] [max_size] { executi ...

  6. keil STM32中sct 分散加载文件学习

    sct 分散加载文件简介 MDK 生成一个以工程名命名的后缀为 *.sct 的分散加载文件 (Linker Control File,scatter loading),链接器根据该文件的配置分配各个节 ...

  7. 浅析keil的scf分散加载文件-基于STM32的例程

    浅析keil的scf分散加载文件-基于STM32的例程 关于分散加载文件 分散加载文件.sct 关于分散加载文件 keil编译器在链接的时候,是根据分散加载(.scf后缀的文件)来确定程序的加载域和运 ...

  8. Scatterfile分散加载文件和 mem.scf

     今天仔细学习周立功的模板的过程中,发现了几个.scf文件,自己不知道这是什么东西,所以学习了下: (一) 这是一位网友写的关于mem_a.scf,mem_b.scf,mem_c.scf文件的见解 ...

  9. [STM32] 分散加载文件 之一 (初探)

    转载自: http://bbs.21ic.com/icview-2579020-1-1.html 本帖最后由 千岁寒 于 2018-11-5 13:00 编辑 1.什么是分散加载            ...

最新文章

  1. 据说是腾讯php程序员面试题目 蛋疼..要是提供PHP手册就HI了..
  2. 让你的JS代码更具可读性
  3. PHP安装wamp设置虚拟目录后,无法访问localhost问题
  4. C语言经典算法100例-031-判断星期几
  5. 兴图视频指挥系统如何配置服务器,兴图新科指挥调度终端
  6. 所有的shadow map的名称
  7. android 闪屏页处理_Android应用闪屏页延迟跳转的三种写法
  8. Java CXF介绍与实例
  9. 使用SQL Server Management Studio 创建数据库备份作业
  10. Oracle USE_LARGE_PAGES初始化参数
  11. linux安装番茄时钟,Tomato Pie番茄钟
  12. java修改头像代码_用户修改头像功能
  13. ubuntu虚拟机联网配置
  14. 图像中的Exif信息及其处理
  15. MIT License探讨
  16. Java微信SDK方式进行网页授权
  17. zyt-python
  18. 蓝桥杯刷题冲刺 | 倒计时14天
  19. js身份证号码带*号处理
  20. linux 显示bin 文件格式,bin文件扩展名,bin文件怎么打开?

热门文章

  1. 员工管理系统实现方案
  2. 【十五】 VVC/H.266 | 帧内帧间联合预测技术CIIP详解
  3. 网络发现自动关闭不能启用、无法启用文件和打印共享的解决办法
  4. B站网页视频加速设置
  5. 数据库的备份和恢复(笔记)
  6. “入门大数据分析:探索海量数据的奥秘“
  7. 批量修改视频尺寸,如此操作简单又专业
  8. linux_系统帮助propos/whatis/which/whereis/man/info/help...)/bashzsh/build-in command帮助/wildcard/regex
  9. Linux中vmstat命令详解
  10. Mask Scoring R-CNN