KEIL MDK链接脚本-分散加载文件sct
在了解keil的链接脚本之前需要了解几个重要概念:
RO(ReadOnly):表示程序中的指令和常量
RW(Read/Write):表示程序中已初始化的变量
ZI(Zero):表示程序中未初始化的变量
我们在编译keil中的工程项目时生成的目标文件时叫做镜像文件(Image)或bin文件,image文件中只包含RO,RW段,这是因为ZI数据段都是零,没有必要包含,只需要把ZI所在的区域清零即可。而其他两个数据段是被赋值了的,所以image文件需要包含已初始化变量的初值。如果我们将image文件烧录到ROM中,那么其必须包含有将RW段移动到RAM中以及将ZI段所在的地址清零的功能。这是保证烧录程序能运行起来的基本要求。
知道基本的定义后,我们来了解链接脚本,也叫程序加载文件。在生成image文件时如何来分配相关数据的存放基址呢?这个就有链接脚本决定,如果不指定特定的链接脚本,连接器就会自动采用默认的链接脚本来生成镜像。本文主要讲解分散加载文件:分散加载文件主要由一个加载时域,多个运行时域组成。
加载时域格式如下所示:
load_region_name base_address max_size
{
execution_region_description+
}
load_region_name为加载时域的名字,长度不超过31个字节
base_address为加载时域的起始地址,即从该地址开始加载相关代码
max_size为加载时域的最大范围,若实际大小超过该大小,链接器将会报错
execution_region_description+是对执行时域的描述
同理,运行时域格式如下:
exec_region_name base_address max_size
{
input_section_description*
}
相关应用实例:
LR_IROM1 0x00000000 0x00040000 { ; 定义一个加载时域,域基址:0x00000000,域大; 小为 0x00040000,对应实际 Flash 的大小ER_IROM1 0x00000000 0x00040000 { ; 定义一个运行时域,第一个运行时域必须和加载; 时域起始地址相同,否则库不能加载到该时域的; 错误,其域大小一般也和加载时域大小相同*.o (RESET, +First) ; 将 RESET 段最先加载到本域的起始地址外,即; RESET 的起始地址为 0,RESET 存储的是向量表.ANY (+RO) ; 加载所有匹配目标文件的只读属性数据,包含:; Code、RW-Code、RO-Data。}RW_IRAM1 0x10000000 0x00008000 { ; 定义一个运行时域,域基址:0x10000000,域大; 小为 0x00008000,对应实际 RAM 大小* (+RW +ZI) ; 加载所有区配目标文件的 RW-Data、ZI-Data; 这里也可以用.ANY 替代*号}
}
————————————————
sct文件的编写与使用
参考资源
1. 分散加载文件浅释.pdf。(周立功工程技术笔记)
1. DUI0377G_02_mdk_armlink_user_guide.pdf(在keil的帮助文档中可以找到)
我们都知道,编译器在生成可执行文件时,先将每个.c文件编译成.o文件(此过程叫编译),然后将很多个.o文件链接成可执行文件(此过程叫链接)。在链接的过程中,会用到一个描述文件,用来指定链接时的行为。这个描述文件叫做链接文件,如linux下的.ld文件,keil中的分散加载文件(.sct文件)。这篇文章就是介绍.sct文件的使用。
keil 中使用自定义的.sct文件
默认的,在keil中编译程序时,会自动的生成.sct文件(默认在生成.o、.hex文件的目录下)。但是,默认的.sct文件很多时候不能满足我们的编程需求。比如在STM32F429上,有两个RAM区域。其中0x10000000起始的64k是CCM内存,DMA不能访问。如果直接使用这片区域(也就是在魔术棒->target选项->IRAM中勾选了它),当DMA访问的内存在这片区域时,那么会遇到程序进入硬件错误中断。这时候就应该使用自定义的.sct文件进行链接修饰,从而达到目的。
魔术棒(option for target)->linker选项
去掉Use Memory Layout from Target Dialog选项。
此时下面的Scatter File部分便可以操作。选择自己的.sct文件或者点击Edit对已有文件进行操作。
编辑完此文件,需要重新编译程序。
下面是笔者的sct文件
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************LR_IROM1 0x08020000 0x000E0000 { ; load region size_regionER_IROM1 0x08020000 0x000E0000 { ; load address = execution address*.o (RESET, +First)*(InRoot$$Sections).ANY (+RO)}RW_IRAM1 0x20000000 0x00020000 { ; RW data.ANY (+RW +ZI)}RW_IRAM2 0x10000000 0x00010000 {main.o (+RW +ZI) ;笔者修改的,将main.c中的所有变量放到ccm中config.o (+RW +ZI) ;笔者修改的,将config.c中的所有变量放到ccm中}
}
分散加载文件.sct语法
一个分散加载文件由一个或者多个加载域(load regions)组成。每个加载域由一个或者多个执行域(execution regions)组成。执行域中又包含很多个输入段描述(Input section description)。关系图如下.
上图中的sct文件包含两个加载域。每个加载域中又都包含两个执行域。每个执行域中包含一个输入段描述。
分散加载文件使用;作为注释符。
什么是加载域
加载域的组成如下:
语法格式
load_region_name (base_address | (+offset)) [attribute_list] [max_size]
{
execution_region
}
名称(name): 加载域的名称,用户自定义。
起始地址: 本加载域的起始地址。分两种表达格式
base_address:直接指明本加载域的起始地址。
+offset:表示此加载域的起始地址为前一个加载域的结束地址+offset字节。offset必须字对齐。
属性(attribute_list)(可选): 用于指定加载域的特征。具体值如下
ABSOLUTE: 绝对地址。默认属性。
PI: 与位置无关。
RELOC: 可重定位。
OVERLAY: 覆盖。
NOCOMPRESS: 不能进行压缩。
加载域大小(max_size)(可选)
指定加载域的最大范围。默认取值0xFFFFFFFF.
一个或者多个执行域.
执行域的组成见执行域的介绍。
example
LR_IROM1 0x08020000 0x000E0000 { ;加载域ER_IROM1 0x08020000 0x000E0000 {;执行域1*.o (RESET, +First).ANY (+RO)}RW_IRAM1 0x20000000 0x00020000 {;执行域2.ANY (+RW +ZI)}
}
什么是执行域
执行域描述了可执行文件在执行时内存(RAM+ROM)的分配。
执行域的组成类似加载域,如下:
语法格式
exec_region_name (base_address | (+offset)) [attribute_list] [max_size | Length]
{
input section descriptions
}
名称(name): 执行域的名称,用户自定义。
起始地址: 本执行域的起始地址。分两种表达格式
base_address:直接指明本执行域的起始地址。
+offset:表示此执行域的起始地址为前一个执行域的结束地址+offset字节。offset必须字对齐。
属性(attribute_list)(可选): 用于指定加载域的特征。具体值如下
ABSOLUTE: 绝对地址。默认属性。
PI: 与位置无关。
RELOC: 可重定位。
OVERLAY: 覆盖。
NOCOMPRESS: 不能进行压缩。
加载域大小(max_size)(可选)
指定加载域的最大范围。默认取值0xFFFFFFFF.
一个或者多个输入段描述.
输入段描述的组成见输入段描述的介绍。
什么是输入段描述
语法格式
目标文件过滤器 [+属性]
输入段描述的组成如下:
目标文件过滤器。
支持通配符*、?。不区分大小写。如main.o,user*.o等。可匹配的文件可以为目标文件名、库名(不带前导路径名)、库完整路径名。
可以使用*.o匹配所有的目标文件。用*匹配所有文件,包括目标文件和库。
可以使用.ANY进行任意的匹配。它的优先级低于*.
属性,不区分大小写:
RO-CODE,同义词有CODE
RO-DATA,同义词有CONST
RO 即RO-CODE + RO-DATA,同义词有TEXT
RW-DATA
RW-CODE
RW 即RW-DATA + RW-CODE,同义词有DATA
ZI,同义词有BSS
ENTRY 即包含ENTRY的段。
FIRST
LAST
example:
*.o (RESET, +First) 任何目标文件中的RESET段放在起始位置。
.ANY (+RW +ZI)匹配任意文件的数据段。
.ANY (+RO) 匹配任意文件的代码段。
————————————————
KEIL MDK链接脚本-分散加载文件sct相关推荐
- 【C语言常识】Keil MDK的分散加载文件.sct
https://blog.csdn.net/wuhenyouyuyouyu/article/details/71171546?ops_request_misc=%257B%2522request%25 ...
- keil的sct文件_STM32 分散加载文件 .sct 解析
1.STM32 启动文件与 .sct 文件分析 1) 定义STACK段,{NOINIT,读写}:分配一段内存大小为0.5K; 2) 定义HEAP段, {NOINIT,读写}:分配一段内存大小为1K; ...
- keil分散加载文件sct写法
//-------------------------------------------------------------------------------------------------- ...
- 【IoT】STM32 分散加载文件 .sct 解析
1.STM32 启动文件与 .sct 文件分析 1) 定义STACK段,{NOINIT,读写}:分配一段内存大小为0.5K; 2) 定义HEAP段, {NOINIT,读写}:分配一段内存大小为1K; ...
- keil的sct文件_Keil sct分散加载文件
博主是个还没入门的弱菜,老师让查资料所以我把自己找的资料整理一下搁在这里方便以后查阅用的,自己并没有试过. 如有错误,欢迎指正. 参考资料: 首先介绍几个概念: 1.ARM映像文件 ARM映像文件是一 ...
- STM32之MDK分析,分散加载
STM32分散加载 我们知道MDK的分散加载主要是通过.sct文件实现的,链接器根据.sct文件的配置分配各个节区地址,生成分散加载代码,因此我们通过修改该文件可以定制具体节区的存储位置. 如何打开. ...
- H750移植rt_thread操作系统完整工程分享,包括外部FLASH分散加载文件
一.移植注意事项 1.在运行外部FLASH存储的代码之前首先要初始化QSPI进入内存映射模式,参考代码: //QSPI进入内存映射模式(执行QSPI代码必备前提,为了减少引入的文件, //除了GPIO ...
- app与bootloader共享内存的方法(分散加载文件)
app要升级时要通知bootloader,然后进入bootloader模式,app要如何通知bootloader呢?以前用了写入升级标志到eeprom的方式,然后bootloader再去读取,这是一种 ...
- KEIl工具之scatter file分散加载文件1
KEIl工具之scatter file分散加载文件 转自:http://blog.csdn.net/zhoujiaxq/article/details/8102587 **************** ...
最新文章
- Xbox One 初始化-2 激活(百视通)和配置账户
- GNU make manual 翻译( 一百五十五)
- 用 as with ,和 ROW_NUMBER() 做分页查询
- MoviePy - 中文文档1-下载与安装
- HTML 表格滚动锁定表头,实现固定行列
- 如何在 Windows 10 上完全禁用 UAC
- HTML基础学习(菜鸟教程和W3school参考手册)
- 使用Grafana搭建监控系统
- 用缠论做量化(买卖点/品种机会/策略应用全解读)
- nfc卡模式与标准模式_手机NFC卡模式功能是什么意思
- 微信小程序如何做触底加载分页功能
- 数据可视化第八章使用matplotlib绘制高级图表
- MySQL数据库高级面试题(2)
- C++中抽象类的简单使用
- 刘东明微信营销二十五式初探(一)
- 单向链表和双向链表的优缺点及使用场景
- 物联网开发笔记(62)- 使用Micropython开发ESP32开发板之控制ILI9341 3.2寸TFT-LCD触摸屏进行LVGL图形化编程:环境搭建
- switch语句的执行顺序
- 【差分约束+spfa优化】P3084 [USACO13OPEN]Photo G
- 每日一句 英文好句