ADS下的分散加载文件应用实例

来源:本站
导读:目前正在解读《ADS下的分散加载文件应用实例》的相关信息,《ADS下的分散加载文件应用实例》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《ADS下的分散加载文件应用实例》的详细说明。
简介:文章简单介绍了ADS下的分散加载文件的应用

ADS下的分散加载文件应用实例

load_region_name start_address | "+"offset [attributes] [max_size]

{

execution_region_name start_address | "+"offset [attributes][max_size]

{

module_select_pattern ["("

("+" input_section_attr | input_section_pattern)

([","] "+" input_section_attr | "," input_section_pattern)) *

")"]

}

}

load_region: 加载区,用来保存永久性数据(程序和只读变量)的区域;

execution_region: 执行区,程序执行时,从加载区域将数据复制到相应执行区后才能被正确执行;

load_region_name: 加载区域名,用于“Linker”区别不同的加载区域,最多31个字符;

start_address: 起始地址,指示区域的首地址;

+offset: 前一个加载区域尾地址+offset 做为当前的起始地址,且“offset”应为“0”或“4”的倍数;

attributes: 区域属性,可设置如下属性:

PI 与地址无关方式存放;

RELOC 重新部署,保留定位信息,以便重新定位该段到新的执行区;

OVERLAY 覆盖,允许多个可执行区域在同一个地址,ADS不支持;

ABSOLUTE 绝对地址(默认);

max_size: 该区域的大小;

execution_region_name:执行区域名;

start_address: 该执行区的首地址,必须字对齐;

+offset: 同上;

attributes: 同上;

PI 与地址无关,该区域的代码可任意移动后执行;

OVERLAY 覆盖;

ABSOLUTE 绝对地址(默认);

FIXED 固定地址;

UNINIT 不用初始化该区域的ZI段;

module_select_pattern: 目标文件滤波器,支持通配符“*”和“?”;

*.o匹配所有目标,* (或“.ANY”)匹配所有目标文件和库。

input_section_attr: 每个input_section_attr必须跟随在“+”后;且大小写不敏感;

RO-CODE 或 CODE

RO-DATA 或 CONST

RO或TEXT, selects both RO-CODE and RO-DATA

RW-DATA

RW-CODE

RW 或 DATA, selects both RW-CODE and RW-DATA

ZI 或 BSS

ENTRY, that is a section containing an ENTRY point.

FIRST,用于指定存放在一个执行区域的第一个或最后一个区域;

LAST,同上;

input_section_pattern: 段名;

汇编中指定段:

AREA vectors, CODE, READONLY

C中指定段:

#pragma arm section [sort_type[[=]"name"]] [,sort_type="name"]*

sort_type: code、rwdata、rodata、zidata

如果“sort_type”指定了但没有指定“name”,那么之前的修改的段名将被恢复成默认值。

#pragma arm section // 恢复所有段名为默认设置。

应用:

#pragma arm section rwdata = "SRAM",zidata = "SRAM"

static OS_STK SecondTaskStk[256]; // “rwdata”“zidata”将定位在“sram”段中。

#pragma arm section // 恢复默认设置

分散加载文件中定义如下:

Exec_Sram 0x80000000 0x40000

{

* (sram)

}

“PI” 属性使用示例:

LR_1 0x010000 PI ; The first load region is at 0x010000.

{

ER_RO +0 ; The PI attribute is inherited from parent.

; The default execution address is 0x010000, but the code can be moved.

{

*(+RO) ; All the RO sections go here.

}

ER_RW +0 ABSOLUTE ; PI attribute is overridden by ABSOLUTE.

{

*(+RW) ; The RW sections are placed next. They cannot be moved.

}

ER_ZI +0 ; ER_ZI region placed after ER_RW region.

{

*(+ZI) ; All the ZI sections are placed consecutively here.

}

}

LR_1 0x010000 ; The first load region is at 0x010000.

{

ER_RO +0 ; Default ABSOLUTE attribute is inherited from parent. The execution address

; is 0x010000. The code and ro data cannot be moved.

{

*(+RO) ; All the RO sections go here.

}

ER_RW 0x018000 PI ; PI attribute overrides ABSOLUTE

{

*(+RW) ; The RW sections are placed at 0x018000 and they can be moved.

}

ER_ZI +0 ; ER_ZI region placed after ER_RW region.

{

*(+ZI) ; All the ZI sections are placed consecutively here.

}

}

程序中对某区域地址等的引用方法:

Load$$region_name$$Base Load address of the region.

Image$$region_name$$Base Execution address of the region.

Image$$region_name$$Length Execution region length in bytes (multiple of 4).

Image$$region_name$$Limit Address of the byte beyond the end of the execution region.

Image$$region_name$$ZI$$Base Execution address of the ZI output section in this region.

Image$$region_name$$ZI$$Length Length of the ZI output section in bytes (multiple of 4).

Image$$region_name$$ZI$$Limit Address of the byte beyond the end of the ZI output sectionin the execution region.

SectionName$$Base Input Address of the start of the consolidated section called SectionName.

SectionName$$Limit Input Address of the byte beyond the end of the consolidated section called SectionName.

Load: 加载区,即存放地址;

Image: 执行区,即运行地址;

Base: 区首地址;

Limit: 区尾地址;

Length: 区长度;

region_name: RO、RW、ZI、load_region_name、execution_region_name;

例如:

“RAM1”区域的首地址: Image$$RAM1$$Base

上例中“sram”段首地址: sram$$Base

汇编引用示例:

IMPORT |Load$$Exec_RAM1$$Base| // Exec_RAM1 为“RW”段

IMPORT |Image$$Exec_RAM1$$Base|

IMPORT |Image$$Exec_RAM1$$Length|

IMPORT |Image$$Exec_RAM1$$Limit|

LDRR0,=|Load$$Exec_RAM1$$Base|

LDRR1,=|Image$$Exec_RAM1$$Base|

LDRR2, =|Image$$Exec_RAM1$$Limit|

0

CMPR1, R2

LDRCCR3, [R0], #4

STRCCR3, [R1], #4

BCC%b0

C 引用:

extern unsigned char Load$$Exec_RAM1$$Base;

extern unsigned char Image$$Exec_RAM1$$Base;

extern unsigned char Image$$Exec_RAM1$$Length;

void MoveRO(void)

{

unsigned char * psrc, *pdst;

unsigned int count;

count = (unsigned int) &Image$$Exec_RAM1$$Length;

psrc = (unsigned char *)&Load$$Exec_RAM1$$Base;

pdst = (unsigned char *)&Image$$Exec_RAM1$$Base;

while (count--) {

*pdst++ = *psrc++;

}

}

加载文件示例一:

起始地址 大小

ROM: 0x00000000 256K ;0x1fc 保留为加密字,程序在ROM中运行;

RAM 0x40000000 16K ;用于全局变量及任务堆栈;

SRAM 0x80000000 512K ;SRAM速度慢,主要用于存放大的数据表;

LOAD_ROM1 0x00000000 0x1f8 ; 指定该加载区域首地址、大小

{

EXEC_ROM1 +0 0x1f8 ; 没有前一加载区域,所以该执行区域首地址为加载去首地址

; 并指定该区域长度

{

Startup.o (vectors, +FIRST) ; 目标文件的“vectors”段放在该执行区域的第一段

irq.o (+RO) ; 目标文件的所有“RO”段放在该执行区域

}

}

LOAD_ROM2 0x00000200 ; 第二个加载区域

{

EXEC_ROM2 +0 0x3e600

{

* (+RO) ; 所有目标文件和库文件中的“RO”段存放在该区域

}

RAM1 0x40000000 0x4000

{

* (+RW, +ZI) ; 所有目标文件和库文件的“RW”和“ZI”段存放在该区域

}

SRAM2 0x80000000 0x80000

{

* (sram) ; 所有目标文件中的“sram”段存放在该区域

}

}

示例二:

“iap.o”定义在“Exec_RAM1”中运行,所以设置“PI”属性;

在调用“iap.c”中函数之前应该将其从“Load$$Exec_IAP$$Base”复制到指定的“Exec_RAM1”区域;

Load_region1 0x00000000 0x1fc

{

EXEC_ROM1 +0

{

Startup.o (vectors, +FIRST)

irq.o (+RO)

}

}

Load_region2 0x00000200 0x3e600

{

EXEC_ROM2 +0

{

* (+RO)

}

Exec_IAP +0 PI // 可能引起链接器未使用该属性警告,忽略

{

iap.o (+RO)

}

Exec_RAM1 0x40000000 0x4000

{

* (+RW, +ZI)

}

Exec_Sram 0x80000000 0x40000

{

* (SRAM)

}

}

// 移动“IAP.o”中的所有函数到“ImageExecIAPBase”加载区,并调用其中的函数

extern unsigned char Load$$Exec_IAP$$Base;

extern unsigned char Image$$Exec_IAP$$Length;

#define ImageExecIAPBase (0x40000000+0x1000)// 加载区首址

void MoveIAPRO(void)

{

unsigned char * psrc, *pdst;

unsigned int count;

count = (unsigned int) &Image$$Exec_IAP$$Length;

psrc = (unsigned char *)&Load$$Exec_IAP$$Base;

pdst = (unsigned char *)ImageExecIAPBase;

while (count--) {

*pdst++ = *psrc++;

}

}

// 调用“IAP.O”中的某函数

{

void (* pfnIAPWrite)(unsigned long, int);

pfnIAPWrite = (void (*)(unsigned long, int))

(ImageExecIAPBase +

(unsigned int)IAPWrite - // 被调用函数名

(unsigned int)&Load$$Exec_IAP$$Base)

pfnIAPWrite((int)((CUPDATA *)CODESTARTADDR)->data,

((CUPDATA *)CODESTARTADDR)->length);

}

提醒:《ADS下的分散加载文件应用实例》最后刷新时间 2024-03-14 01:20:26,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《ADS下的分散加载文件应用实例》该内容的真实性请自行鉴别。