小猫爪:嵌入式小知识04-IAR icf链接文件解析

1 前言

前一章我们提到了源文件最后变成了代码的过程,这一节我们详细得介绍一下在IAR中链接过程以及如何在IAR中自定义链接地址。

2 Section、Block、Region

介绍正题之前,我们得先了解一下Section、Block、Region的概念。

2.1 Section

《小猫爪:嵌入式小知识03-程序的组成、存储与运行(转自野火教程)》中我们说到了程序中的内容按照性质可以分成一下几个域:
在这里插入图片描述
所以代码在编译后就会按照上面的域分成一个个的块,也就是section,链接器链接过程中操作的基本单位就是section。IAR为了让操作更加简单和人性化,就按照以下性质:
在这里插入图片描述
以及程序功能作用规定了以下section:

Section Description
.bss Holds zero-initialized static and global variables.
CSTACK Holds the stack used by C or C++ programs.
.data Holds static and global initialized variables.
.data_init Holds initial values for .data sections when the linker directive initialize is used.
.exc.text Holds exception-related code.
HEAP Holds the heap used for dynamically allocated data.
_ _iar_tls.$$ DATA Holds initial values for TLS variables.
.iar.dynexit Holds the atexit table.
.init_array Holds a table of dynamic initialization functions.
.intvec Holds the reset vector table
IRQ_STACK Holds the stack for interrupt requests, IRQ, and exceptions.
.noinit Holds _ _no_init static and global variables.
.preinit_array Holds a table of dynamic initialization functions.
.prepreinit_array Holds a table of dynamic initialization functions.
.rodata Holds constant data.
.text Holds the program code.
.textrw Holds _ _ramfunc declared program code.
.textrw_init Holds initializers for the .textrw declared section.
Veneer$$CMSE Holds secure gateway veneers.

当然我们也可以自定义section,我们在IAR的c代码中可以使用以下语法定义自己的section:

#pragma location = "name" content

name为section名, content则为具体的变量或者函数。
具体操作后面会举例说明。

2.2 Block

Block是IAR为了更加方便的管理Section而定义出的一个概念,用户可以在链接文件中定义一个Block空间,指定对齐方式和大小。下面举个常见的操作例子:

/*这一部分则是定义一个__size_cstack__大小的block,8字节对齐, 其实这就是栈的大小*/
define block CSTACK    with alignment = 8, size = __size_cstack__   {
    };
/*这一部分则是定义了一个RW Block,并将 readwrite 和  m_usb_dma_init_data 这两个section放入 */
define block RW        {
    first readwrite, section m_usb_dma_init_data };

后面还会对其详细介绍。

2.3 Region

IAR使用Region来表示实际的存储区,通常需要通过实际的芯片映射存储地址来定义,我们则可以通过以下语法来定义Region。

define region 名字 = mem:[from 起始地址 to 终止地址];

3 IAR 链接文件

介绍完上面三个概念,接下里来介绍链接文件。

3.1 IAR链接过程

首先我们介绍一下IAR链接文件的流程:

①决定哪些模块需要包含到应用程序中。

②选择链接目标文件用到的标准库文件。

③决定目标文件哪些section需要包含进来。

④完成RAM中的代码和变量的初始化。初始化指令可以让链接器产生额外的代码能够copy ROM中的内容到RAM中。每个通过copy完成初始化的段被分成了两个段,一个在ROM,一个在RAM。如果没有人工初始化的话,链接器回自动产生启动代码来完成初始化。

⑤通过链接文件的放置指令来决定每个section存放的位置。

⑥生成最终的包含可执行映像和调试信息的最终文件。

⑦最后生成map文件,包括了各个section的的在存储器中的最终地址,global symbol的地址和用到的存储器和库汇总。

其实除了第五步,我们经常要人为干预外(可以灵活的配置相关数据的运行区域,比如有段程序需要其非常快的执行或者有段数据需要经常得访问,那么我们则可以将其放置在RAM中,提供执行速度),其他的部分一般都是IAR自动完成的。

3.2 链接文件的组成

在第五步中,链接器会根据链接文件中的内容来决定每一个section的位置,那么一个链接文件中具体会包含下面这些内容:

  • 定义可用的可编址空间(memory)
  • 定义ROM或RAM的可用内存区域(region)
  • 定义Block 定义应用程序初始化
  • 放置section
  • 使用symbols, expressions, and numbers

3.3 链接文件的常见指令

(这是我直接抄过来的:《解析IAR的ILINK链接器icf配置文件》

下面让我们了解一下基本指令:

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

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

举例:

define symbol RAM_START_ADDRESS = 0x40000000;  /*  定义 RAM 起始地址  */ 
define symbol RAM_END_ADDRESS  = 0x4000FFFF;  /*  定义 RAM 结束地址  */

(2)define memory name with size = expr [, unit-size];
作用:定义一个可编址的存储地址空间(memory)。

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

举例:

define memory MEM with size = 4</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小猫爪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值