首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

realview MDK中连接脚本详细解析

realview MDK中连接脚本详细解析

本帖最后由 look_w 于 2017-10-24 16:26 编辑

使用Realview MDK时不可避免的要涉及到链接脚本文件,特别是编译链接那些大的工程文件时更是如此。在链接脚本中可以指定代码的存储布局,可以将代码段、只读数据段、可读写的数据段分别存放,甚至可以精确地指定代码放置的位置,这一点是很关键的,譬如说启动代码就必须放在可知型文件的开始位置。由于链接脚本重要性,开发者必须掌握其编写的方法。
Realview MDK链接程序使用了两种方式控制程序的链接,即链接控制命令选项链接脚本文
Limit等6个段地址描述符。这6个描述符可以直接在程序中引用。

Limit。下面将结合3个具体的例子说明链接脚本文件的使用。例1 一个加载区域,多个连续的执行区域。
LR_1 0x040000          ; 定义载入区域LR_1的起始地址为0x040000。
{
ER_RO +0            ; 执行区域ER_RO的起始地址紧接载于区域LR_1的起始地址,即为0x040000.
{
* (+RO)         ; 所有的只读代码段都连续地放在这个区域。
}
ER_RW +0        ; 可读写数据段ER_RW紧接ER_RO段的尾地址存放,即0x040000 + ER_RO的容量。
{
* (+RW)      ; 所有的可读写的程序都连续地放在这个区域。
}
ER_ZI +0         ; 清零数据段ER_ZI紧接ER_RW段的尾地址存放。
{
* (+ZI)      ; 所有清零数据都连续地放在这个区域。
}
}

例2 一个加载区域,多个非连续的执行区域。
LR_1 0x010000     ; 定义载入区域LR_1的起始地址为0x010000。
{
ER_RO +0       ;执行区域ER_RO的起始地址紧接载于区域LR_1的起始地址,即为0x010000.
{
* (+RO)    ; 所有的只读代码段都连续地放在这个区域。
}
ER_RW 0x040000 ; 定义可读写数据段ER_RW的起始地址为0x040000.
{
* (+RW)     ; 所有的可读写的程序都连续地放在这个区域。
}
ER_ZI +0; 清零数据段ER_ZI紧接ER_RW段的尾地址存放,即为0x040000 + ER_RW的容量。
{
* (+ZI)    ; 所有清零数据都连续地放在这个区域。
}
}

例3二个加载区域,多个非连续的执行区域。
LR_1 0x010000     ; 载入区域LR_1的起始地址为0x010000。
{
ER_RO +0       ; ER_RO段的起始地址为0x010000.
{
* (+RO)
}
}
LR_2 0x040000     ; 载入区域LR_2的起始地址为0x040000。
{
ER_RW +0       ; ER_RO段的起始地址为0x010000.
{
* (+RW)    ; 所有可读写的数据段都放在这里。
}
ER_ZI +0       ; 清零段ER_Z的起始地址为0x040000 + ER_RW段的容量。
{
* (+ZI)    ; 所有清零段ZI的数据都连续的放在这里。
}
}

6 特殊应用
  6. 1 定位目标外设
  使用分散加载,可以将用户定义的结构体或代码定位到指定物理地址上的外设,这种外设可以是定时器、实时时钟、静态SRAM或者是两个处理器间用于数据和指令通信的双端口存储器等。在程序中不必直接访问相应外设,只需访问相应的内存变量即可实现对指定外设的操作,因为相应的内存变量定位在指定的外设上。这样,对外设的访问看不到相应的指针操作,对结构体成员的访问即可实现对外设相应存储单元的访问,让程序员感觉到仿佛没有外设,只有内存。


  要使用分散加载将上述结构体定位到Ox04000000的物理地址,可以将上述结构体放在一个文件名为timer_regs.c中,并在分散加载文件中指定即可,



  属性UNINIT是避免在应用程序启动时对该执行段的ZI数据段初始化为零。
  在程序连接后,通过Image map文件可查看该ZI数据段的存储器分配情况:
  Execution Region TIMER(Base:Ox04000000,Size:0x00000008,Max:0xffffffff,ABSOLUTE,UNINIT)Base Addr Size Type Attr Idx E Section Name 0bi ectOx04000000 0x00000008 Zero RW 32.bss tlmer_regs.o从Image map文件可以看出,该TIMER执行区定位在物理地址0x04000000,即结构体timer_regs定位在Ox04000000,因此,在程序中对结构体的操作即是对定时器的操作。
返回列表