STM32(Cortex-M3)启动过程+IAR中xcl及icf文件详解

一: STM32(Cortex-M3)启动过程(入口地址)

ARM7和ARM9启动时从绝对地址0X00000000开始执行复位中断程序,即固定了复位后的起始地址,但中断向量表的位置是可变的。 

Cortex-M3内核规定中断向量表中第一个32位数据内容为栈顶地址,第二个32位数据内容则是复位中断向量的入口地址。

这样CPU复位后会自动从中断向量表中第二个32位数据中取出复位中断向量的入口地址,PC就跳转到中断服务程序。这也就是为什么调试的时候程序会直接跳到0x08000144(中断向量表中第二个32位数据为0x08000145),而不是停在0x08000000。

Cortex-M3的中断向量表的结构是固定的,而位置的地址是可变的。 

 

Cortex-M3的初始中断向量表有三个位置,通过BOOT引脚进行启动设置。

BOOT1=x BOOT0=0 从用户闪存启动,这是正常的工作模式。中断向量表定位于FLASH区,复位后PC=0x80000000.  

BOOT1=0 BOOT0=1 从系统存储器启动(相当于厂家在存储器中固化了BOOTLOADER),这种模式启动的程序功能由厂家设置。 

BOOT1=1 BOOT0=1从内置SRAM启动,这种模式可以用于调试。这种模式下,中断向量表位于SRAM区,起始地址为0x20000000.复位为PC=0x20000000.

当STM32复位完成后,可通过设置VECTOR_TABLE,将中断向量表放置在任何地方。

IAR中xcl及icf文件详解
已经用STVD+cosmic完成了IAP功能,但想试着在STM8上跑上官的UCOS,不得不用IAR编译,但编译后代码的生成地址怎么再从0X9000开始生成呢,找遍全网,也没有发现三言两语直接的表白,又对IAR环境不熟,看过了IAR下的工程设置的全部选项,都没有发现怎么修改这个地址,IAR的这个地址的修改,并不象KEIL及STVD下那么直接,它必须通过IAR的根目录下有个CONFIG的文件夹,里面有各种单片机的*.icf的文件,我看着有两处0x8000改为0x9000,然后编译文件,呵呵,果然有效,在STVP下,发现HEX文件就是从0x9000开始生成代码了。找的好辛苦,又不太懂英文看帮助,唉,只能受此罪!
ICF修改的是以下三项:
define region NearFuncCode = [from 0x9000 to 0xFFFF];
define region FarFuncCode = [from 0x9000 to 0xFFFF];
define region HugeFuncCode = [from 0x9000 to 0xFFFF];
以下是摘抄的有关ICF文件部分


IAR xcl icf 文件详解
链接器和链接器的配置
2.1 EWARM 4.xx 的链接器 XLINK 及其配置文件 .xcl
XLINK 链接器可以把 IAR 汇编器或编译器所产生的可重定位的 UBROF 目标文件转换成针对目标处理器的机器码。 XLINK 一般通过外部链接器命令文件( *.xcl )来配置,当然也可以在命令行中直接在 xlink 命令之后输入链接选项,或者也可以在 XLINK_ENVPAR 环境变量中设置链接选项。下面介绍 XCL 文件中常用的链接选项,以便在版本迁移之前,确切地了解 XCL 文件的含义。
2.2 XLINK 选项
下面介绍几个 XCL 文件中常见的链接器配置选项。更详细的内容请查阅 XLINK 的参考手册: IAR Linker and Library Tools Reference Guide
-D -Dsymbol=value
作用:
使用 -D 选项可以定义一些纯粹的符号,一般用于声明常数。
参数:
symbol 是未在其它地方定义过的外部符号, value symbol 所代表的值。例如:
就定义了 2 个标识了 ROM 起始和结束地址的符号,这样以后关于 ROM 地址的配置都可以直接使用这 2 个符号,使得配置文件的可读性增强。
-Z -Z [@] [(SPLIT-)type] segments [=|#] range [, range] …
作用:
使用 -Z 命令的目的是规定 segments 在存储空间中占据的位置和区间。如果链接器发现某个 segment 没有使用 -Z -b 或者 -P 中的任何一个命令进行定义,则会报错。
参数:
使用 @ 参数,表示为 segments 分配空间时不考虑任何已经被使用的地址空间。这适用于当某些 segments 的地址空间需要发生重叠的情形。
type  参数 type 规定了 segments 的存储类型,默认为 UNTYPED 。表 1 列举了 IAR ARM C/C++ 编译器所支持的 segments 类型。
-Q -Q segment = initializer_segment
作用:
自动设置 segment 的拷贝初始化。链接器会产生一个新的 initializer_segment (如 CODE_ID ),其内容与 segment (如 CODE_I )完全一致。相关的符号表和调试信息都会和 segment 相关联(如 CODE_I )。 initializer_segment 的内容(通常在 ROM 中)必须在初始化阶段被复制到 segment (通常在 RAM 中)。
-c -cprocessor
作用:
规定目标处理器的类型。如 -carm
.3 EWARM 5.xx 的链接器 ILINK 及其配置文件 .icf
EWARM 5.xx 中的链接器称为 ILINK ILINK 可以从 ELF/DWARF 格式的目标文件中提取代码和数据,并生成可执行映像。在 EWARM 4.xx 中,基本的代码和数据链接单元是 segment ,而对于 ELF/DWARF 格式而言,基本链接单元是 section ILINK 根据 ILINK Configuration File *.icf )来分配这些 sections 。由于 XLINK ILINK 是两个完全不同的链接器,所以 XCL ICF 也是两种完全不同的配置文件。下面简要介绍 ICF 文件的格式和内容,以协助用户完成版本迁移。
2.4 ICF 格式浅析
sections 在地址空间中的存放是由 ILINK 链接器来实现的,而 ILINK 链接器是按照用户在 ICF 文件中的规定来放置 sections 的,所以理解 ICF 文件的内容尤其重要。
一个标准的 ICF 文件可包括下面这些内容:
1.        可编址的存储空间( memory
2.        不同的存储器地址区域( region
3.        不同的地址块( block
4.       Section 的初始化与否
5.       Section 在存储空间中的放置
下面介绍了几条 ICF 文件中常见的指令,详细内容请参考 ILINK 相关说明文档( EWARM_DevelopmentGuide.pdf ):
define [ exported ] symbol name = expr;
作用:
指定某个符号的值。
参数:
exported  导出该 symbol ,使其对可执行镜像可用
name  符号名
expr  符号值
举例:
define symbol RAM_START_ADDRESS = 0x40000000;
define symbol RAM_END_ADDRESS = 0x4000FFFF;
define memory name with size = expr [, unit-size];
作用:
定义一个可编址的存储地址空间( memory )。
参数:
name memory 的名称
expr  地址空间的大小
unit-size expr 的单位,可以是位( unitbitsize ),缺省是字节( unitbytesize
举例:
define memory MEM with size = 4G;
define region name = region-expr;
作用:
定义一个存储地址区域( region )。一个区域可由一个或多个范围组成,每个范围内地址必须连续,但几个范围之间不必是连续的。
参数:
name region 的名称
region-expr memory:[from expr { to expr | size expr}] ,可以定义起止范围,也可以定义起始地址和 region 的大小
举例:
define region ROM = MEM:[from 0x0 size 0x10000];
define region ROM = MEM:[from 0x0 to 0xFFFF];
define block name[ with param, param... ]
{
extended-selectors
};
作用:
定义一个地址块( block );它可以是个空块,比如栈、堆;也可以包含一系列 sections
参数:
name block 的名称
param  可以是:  size = expr  (块的大小)
maximum size = expr  (块大小的上限)
alignment = expr  (最小对齐字节数)
fixed order  (按照固定顺序放置 sections
extended-selector [ first | last ] { section-selector | block name | overlay name }
first  最先存放
last  最后存放
section-selector [ section-attribute ][ section sectionname ][object filename ]
section-attribute [ readonly [ code | data ] | readwrite [ code | data ] | zeroinit ]
sectionname section 的名称
filename  目标文件的名称
即可以按照 section 的属性,名称及其所在目标文件的名称这三个过滤条件中,任意选取一个条件,或选取多个条件进行组合,来圈定所要求的 sections
name block overlay 的名称
举例:
define block HEAP with size = 0x1000, alignment = 4 { };
define block MYBLOCK1 = { section mysection1, section mysection2, readwrite };
define block MYBLOCK2 = { readonly object myfile2.o };
initialize { by copy | manually } [ with param, param... ]
{
section-selectors
};
作用:
初始化 sections
参数:
by copy  在程序启动时自动执行初始化。
manually  在程序启动时不自动执行初始化。
param  可以是:  packing = { none | compress1 | compress2 | auto }
copy routine = functionname
packing 表示是否压缩数据,缺省是 auto
functionname 表示是否使用自己的拷贝函数来取代缺省函数。
section-selector  同上
举例:
initialize by copy { rw };
do not initialize
{
section-selectors
};
作用:
规定在程序启动时不需要初始化的 sections 。一般用于 __no_init 声明的变量段( .noinit )。
参数:
section-selector  同上
举例:
do not initialize { .noinit };
place at { address memory[: expr] | start of region_expr | end of region_expr }
{
extended-selectors
};
作用:
把一系列 sections blocks 放置在某个具体的地址,或者一个 region 的开始或者结束处。
参数:
memory memory 的名称
expr  地址值,该地址必须在 memory 所定义的范围内
region_expr region 的名称
extended-selector  同上
举例:
place at start of ROM { section .cstart }; place at end of ROM { section .checksum }; place at address MEM:0x0 { section .intvec };
place in region-expr
{
extended-selectors
};
作用:
把一系列 sections blocks 放置在某个 region 中。 sections blocks 将按任意顺序放置。
参数:
region-expr region 的名称
extended-selector  同上
举例:
place in ROM { readonly };  place in RAM { readwrite };
place in RAM { block HEAP, block CSTACK, block IRQ_STACK }; place in ROM { section .text object myfile.o };  place in ROM { readonly object myfile.o };  place in ROM { readonly data object myfile.o };

IAR ICF 文件分析与应用
sections 在地址空间中的存放是由 ILINK 链接器来实现的,而 ILINK 链接器是按照用户在 ICF 文件中的规定来放置 sections 的,所以理 解 ICF 文件的内容尤其重要。

一个标准的 ICF 文件可包括下面这些内容:

1.        可编址的存储空间( memory
2.        不同的存储器地址区域( region
3.        不同的地址块( block
4.       Section 的初始化与否
5.       Section 在存储空间中的放置

下 面介绍了几条 ICF 文件中常见的指令,详细内容请参考 ILINK 相关说明文档( EWARM_DevelopmentGuide.pdf ):

1.    define [ exported ] symbol name = expr;
作用:    指定某个符号的值。

参数:     exported  导出该 symbol ,使其对可执行镜像可用
name     -- 符号名
expr     -- 符号值

举例:
define symbol RAM_START_ADDRESS = 0x40000000;
define symbol RAM_END_ADDRESS = 0x4000FFFF;   

2.    define memory name with size = expr [, unit-size];

作用:    定义一个可编址的存储地址空间( memory )。

参数:     name     --memory 的名称
expr     -- 地址空间的大小
unit-size --expr 的单位,可以是位( unitbitsize ),缺省是字节( unitbytesize

举例:
define memory MEM with size = 4G;

3.    define region name = region-expr;

作用:    定义一个存储地址区域( region )。一个区域可由一个或多个范围组成,每个范围内地址必须连续,但几个范围之间不必是连续的。

参数:     name region 的名称
region-expr memory:[from expr { to expr | size expr}] ,可以定义起止范围,也可以定义起始地址和 region 的大小

举例:
define region ROM = MEM:[from 0x0 size 0x10000];
define region ROM = MEM:[from 0x0 to 0xFFFF];

4.    define block name[ with param, param... ]

{

extended-selectors

};

作用:    定义一个地址块( block );它可以是个空块,比如栈、堆;也可以包含一系列 sections

参数:     name     block 的名称
param  可以是:      size = expr  (块的大小)
maximum size = expr  (块大小的上限)
alignment = expr  (最小对齐字节数)
fixed order  (按照固定顺序放置 sections

extended-selector [ first | last ] { section-selector | block name | overlay name }
first  最先存放
last  最后存放
section-selector [ section-attribute ][ section sectionname ][object filename ]
section-attribute [ readonly [ code | data ] | readwrite [ code | data ] | zeroinit ]
sectionname section 的名称
filename  目标文件的名称
即可以按照 section 的属性,名称及其所在目标文件的名称这三个过滤条件中,任意选取一个条件,或选取多个条件进行组合,来圈定所要求的  sections
name block overlay 的名称

举例:
define block HEAP with size = 0x1000, alignment = 4 { };
define block MYBLOCK1 = { section mysection1, section mysection2, readwrite };
define block MYBLOCK2 = { readonly object myfile2.o };

5.    initialize { by copy | manually } [ with param, param... ]
{
section-selectors
};

作用:    初始化 sections

参数:     by copy  在程序启动时自动执行初始化。
manually  在程序启动时不自动执行初始化。
param  可以是:  packing = { none | compress1 | compress2 | auto }
copy routine = functionname
packing 表示是否压缩数据,缺省是 auto
functionname 表示是否使用自己的拷贝函数来取代缺省函数。
section-selector  同上

举例:
initialize by copy { rw };

6.    do not initialize
{
section-selectors
};

作用:    规定在程序启动时不需要初始化的 sections 。一般用于 __no_init 声明的变量段( .noinit )。

参数:     section-selector  同上

举例:
do not initialize { .noinit };

7.    place at { address memory[: expr] | start of region_expr | end of region_expr }
{
extended-selectors
};

作用:    把一系列 sections blocks 放置在某个具体的地址,或者一个 region 的开始或者结束处。

参数:     memory memory 的名称
expr  地址值,该地址必须在 memory 所定义的范围内
region_expr region 的名称
extended-selector  同上

举例:
place at start of ROM { section .cstart }; place at end of ROM { section .checksum }; place at address MEM:0x0 { section .intvec };

8.    place in region-expr
{
extended-selectors
};

作用:    把一系列 sections blocks 放置在某个 region 中。 sections blocks 将按任意顺序放置。

参数:     region-expr region 的名称
extended-selector  同上

举例:
place in ROM { readonly };         
place in RAM { readwrite };         
place in RAM { block HEAP, block CSTACK, block IRQ_STACK };
place in ROM { section .text object myfile.o };      
place in ROM { readonly object myfile.o };         
place in ROM { readonly data object myfile.o };     

IAR ICF 文件中宏给程序使用

如果想定在 rom 空间

icf 中:

place at address mem:0x08090000 { readonly section .test };

C: 中:

#pragma location = ".test"
const u32 uiData[512];// const  切不可省略

如果想定在 ram 空间

icf 中:

place at address mem:0x08090000 { readwrite section .test };

C: 中:

#pragma location = ".test"
u32 uiData[512];

可发现 uiData 的值为 0x08090000

该法可方便通过 ICF 指定某变量的地址。

程序也可以。写法类似 .vector

如果用 block 的方。类似

define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };

C 中:

#pragma language="extended"
#pragma segment="CSTACK"

ptr = __sfe( "CSTACK" ) ;可得到 CSTACK 的高端地址 +1

__sfe :  Returns last address of segment.

从事电子技术工作这么多年一直想写点东西,但以限于本人文笔与技术水平一直没写。今天有空写点请多多指教。


define symbol NVNC_Start = 0x08000000; //  中断起始地址
define symbol NVNC_size_cstack   = 0x400; // 中断堆栈尺寸
define symbol PROEG_size_heap    = 0x400;// 程序堆栈尺寸

define symbol USB_SRAM_start  = 0x40006000; //USB  专用 SRAM 起始与结束地址
define symbol USB_SRAM_end    = 0x400063FF;

define symbol SyS_SRAM_start   = 0x20000000;  // 定议 RAM 起始与结束地址
define symbol SyS_SRAM_end     = 0x2000FFFF; // 64K

define symbol SyS_Flash_start   = 0x08000800 ; // 定议 FLASH 起始与结束地址
define symbol SyS_Flash_end     = 0x0801FFFF;  //512K

//define symbol SyS_Flash_P1 = (SyS_Flash_start+(0x800*0));



define memory mem with size = 4G;


define region USB_RAM = mem:[from USB_SRAM_start to USB_SRAM_end];
define region RAM_region = mem:[from SyS_SRAM_start to SyS_SRAM_end];
define region ROM_region = mem:[from SyS_Flash_start to SyS_Flash_end];
define region SysT_RAM = mem:[from 0x0801F800 to 0x0801FFFF];


define block CSTACK with alignment = 8, size = NVNC_size_cstack { };
define block HEAP   with alignment = 8, size = PROEG_size_heap  { };


initialize by copy { readwrite };


do not initialize  { section .noinit };


place at address mem:NVNC_Start { readonly section .intvec };

place in RAM_region { readwrite,block CSTACK, block HEAP }; //  堆栈指针存放
place in ROM_region   { readonly }; //  没有定议的 C 文件存放在此
// 定议相关文件存储空间


以上文件只参考 IAR 目录下的:《 EWARM_DevelopmentGuide.ENU.pdf
以上有错或本人理解不对请指出。

IAR ICF 文件中宏给程序使用
如果想定在 rom 空间

icf 中:

place at address mem:0x08090000 { readonly section .test };

C: 中:

#pragma location = ".test"

const u32 uiData[512];// const  切不可省略

如果想定在 ram 空间

icf 中:

place at address mem:0x08090000 { readwrite section .test };

C: 中:

#pragma location = ".test"

u32 uiData[512];

可发现 uiData 的值为 0x08090000

该法可方便通过 ICF 指定某变量的地址。

程序也可以。写法类似 .vector

如果用 block 的方。类似

define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };

C 中:

#pragma language="extended"

#pragma segment="CSTACK"

ptr = __sfe( "CSTACK" ) ;可得到 CSTACK 的高端地址 +1
__sfe :  Returns last address of segment.
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 成长之路 设计师:Amelia_0503 返回首页