sct文件编写与使用

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_region
  ER_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)  匹配任意文件的代码段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值