LCF文件使用说明

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

序言:Codewarrior 2.10是飞思卡尔32位汽车级单片机Qorriva系列的集成开发环境,与之前版本2.8、2.9完全兼容。

Codewarrior 10.3是飞思卡尔最新的集成开发环境,是一个开放源代码的、基于Java的可扩展开发平台。

许多新用户对codewarrior链接文件不是十分了解,本文将针对链接文件的常见问题以及段的定义进行介绍帮助用户快速了解和使用CodeWarrior。

目录
第一节LCF文件定义及使用说明
1
并且代码要在程序开始执行的时候从ROM去拷贝到RAM区。

下面是一个完整的lcf文件,其中包括每行的解释及用法。

/* lcf file for MPC5604B M27V (debug RAM version) 文件的名字及对应单片机(RAM版本)*/
//RAM版本和ROM版本的区别在于RAM版本不将程序下载到ROM中去,而在RAM中执行程序
/* 512KB Flash, 32KB SRAM */ //单片机的FLASH和SRAM大小
MEMORY下面是对单片机存储空间的定义,不同的段的起始地址,不能叠加地址空间
{
pseudo_rom:(仿真ROM区)org = 0x40000000, (开始地址)len = 0x00003000(长度)
init: org = 0x40004000, len = 0x00001000 //初始化段所在位置
exception_handlers: org = 0x40005000, len = 0x00001000 //中断向量所在地址
internal_ram: org = 0x40006000, len = 0x00001800 //内部RAM的起始地址
heap : org = 0x40007800, len = 0x00000400 //堆的起始地址
stack : org = 0x40007C00, len = 0x00000400 //栈的起始地址
}
SECTIONS段的定义
{
GROUP : { // 它的定义需要遵从本例程方式”GROUP:{}” .“{}”中是内容部分
.init : {} //.init段中所有内容。

.init_vle (VLECODE) : { //.init_vle(使用VLE代码)
*(.init)
*(.init_vle)
}
} > init //可以参看前面的init段在存储空间的定义.本GROUP中的所有内容
//放在init段中,”>”代表放在哪个段
GROUP : {
.ivor_branch_table (VLECODE) ALIGN (4096) : {} //ALIGN(4096)按照4096字节对齐
.__exception_handlers (VLECODE) LOAD (_e_ivor_branch_table) : {}
// LOAD()将本段加载到指定地址} > exception_handlers
GROUP : {
.text (TEXT) ALIGN(0x10) : {}
.text_vle (VLECODE) ALIGN(0x10): {
*(.text)
*(.text_vle)
}
.rodata (CONST) : {
*(.rdata)
*(.rodata)
}
.ctors : {}
.dtors : {}
extab : {}
extabindex : {}
} > pseudo_rom
GROUP : {
.__uninitialized_intc_handlertable ALIGN(0x10) : {}
.data : {}
.sdata : {}
.sbss : {}
.sdata2 : {}
.sbss2 : {}
.bss : {}
} > internal_ram
}
/* Freescale CodeWarrior compiler address designations */
_stack_addr = ADDR(stack)+SIZEOF(stack); //ADDR()是取括号内段的首地址
//SIZEOF()是求某段的长度_stack_end = ADDR(stack); //详见第3小节
_heap_addr = ADDR(heap);
_heap_end = ADDR(heap)+SIZEOF(heap);
/* Exceptions Handlers Location (used in Exceptions.c for IVPR initialization) */
EXCEPTION_HANDLERS = ADDR(exception_handlers);
2.LCF文件中预定义的各个段的名称及解释
Section Description
.init 包含初始化代码
.text 包含程序代码
.rodata 包含程序的常量
.sdata 包含初始化的全局小数据
.sdata2 包含初始化过的全局常量(const定义内容)小数据
.data 包含初始化过的全局数据
.sbss 包含未初始化过的全局小数据
.sbss2 包含未初始化过的全局常量(const 定义内容)小数据
.bss 包含未初始化过的全局数据
.ctors 包含构造函数
.dtors 包含析构函数
3.常用关键字及使用说明
关键字列表:
1) SECTION
2) ALIGN
3) ADDR
4) SIZEOF
5) LOAD
6) BIND
7)Declspec
8)pop, push
9)FORCEACTIVE
1)SECTION
Section使用pragma来将编译的目标代码放到预定义的段中,然后可以在LCF文件中将对应的段放到指定的地址区域。

Section和__declspec(section)都可以用来指定一个段,但是不能同时使用
语法
#pragma section [ objecttype | permission ][iname][uname]
[data_mode=datamode][code_mode=codemode]
参数
objecttype
可以是以下三种选项,用来指定将目标数据放在哪里
∙code_type –可执行目标类型
∙data_type –非常量数据,包含比small data大的数据
∙sdata_type –非常量数据,包含比small data小或者等同的数据。

∙const_type –常量数据,包含比small const大的数据
∙sconst_type –常量数据,包含小或者等同small data的数据
∙all_types –所有数据和代码
permission
定义访问权限,包含下列三个选项
∙R –只读
∙W –可写
∙X –可执行
iname
定义段的名字,编译器存储初始化过的目标。

变量在定义的时候被初始化过的,函数和字符串也属于初始化过的目标。

The iname parameter may be of the form .abs.xxxxxxxx where xxxxxxxx is an 8-digit hexadecimal number specifying the address of the section.
uname
定义段的名字,编译器存储未被初始化过的目标。

下面是例子
#pragma push // 保存当前状态
#pragma section ".data" "COMM"
int red;
int sky;
#pragma pop // 恢复之前的状态
data_mode=datamode
为编译器指定使用哪种数据模式
下面是可选的数据模式
∙near_abs –目标必须在16位地址空间
∙far_abs –目标必须在32位RAM地址空间
∙sda_rel –目标必须在链接器为small data定义的32K 地址空间.
code_mode=codemode
向编译器指定地址模式
下面是可选的三种地址模式:
∙pc_rel –被调用子函数地址必须在调用函数24位地址空间范围内
∙near_abs –函数地址必须在24位地址范围
∙far_abs -函数地址必须在32位地址范围内
预定义的段和默认模式
Type Name Data mode Code mode
code_type ".text" data_mode=far_abs c ode_mode=pc_rel
data_type ".data" data_mode=far_abs c ode_mode=pc_rel const_type ".rodata" data_mode=far_abs c ode_mode=pc_rel
sdata_type ".sdata" data_mode=sda_rel c ode_mode=pc_rel sconst_type ".sdata2" ".sbss2" data_mode=sda_rel c ode_mode=pc_rel ".PPC.EMB.sdata0" ".PPC.EMB.sbss0" d ata_mode=sda_rel c ode_mode=pc_rel
2)ALIGN
按照指定的边界进行排列,必须是2的整倍数。

SECTIONS
{
GROUP:
{
.init ALIGN(0x1000) : {}
.text ALIGN(0x1000) : {}
} > text
}
例子中定义了两个段:.init和.text。

在运行的时候每个段都会被放在下一个可以使用的地址(可以被0x1000整除)3)ADDR
返回指定名称的段或者内存区域的开始地址.
ADDR(sectionName | segmentName)
参数
sectionName
文件中段的标志符
segmentName
存储区域中段的标志符
范例
下面代码中使用的ADDR功能来将ROOT的地址赋值给__rootbasecode .
列举ADDR() 功能
MEMORY{
ROOT : origin = 0x80000400, length = 0
}
SECTIONS{
.code :
{
__rootbasecode = ADDR (ROOT);
*.(text);
} > ROOT
}
4)SIZEOF
返回指定Section或者segment的大小(以字节为单位)
SIZEOF(segmentName | sectionName)
参数
segmentName
segment的名字;必须以“.”作为起始。

sectionName
section的名字;必须以“.”作为起始。

5)LOAD
在指定地址加载一个或者多个段。

语法
LOAD(address)
参数
address
一个内存地址例如: 0x80000400.
注意
∙使用load指令来指定一个外部的ROM addr_mode。

∙Load指令可以被用于所有的在ROM中的段。

∙如果编译器选项面板中的Generate ROM image没有被选择的话,指令会被在链接中忽略。

∙从ROM拷贝到RAM中的不连续的未初始化的数据段可能需要参考ROM的地址。

举例来说:保存紧跟在.text 段后面的.data和.sdata段到ROM中,可以尝试下面的例子:
.text LOAD(ADDR(.text)) : {} > rom
.data LOAD(ROMADDR(.text) + SIZEOF(.text)): {} > code
.sdata LOAD(ROMADDR(.data) + SIZEOF(.data)): {} > code
6)BIND
指定一个段修饰语来设定一个地址。

BIND(address)
参数
address
一个存储空间地址例如: 0x80000400.
7)pop, push
保存和恢复pragma设置
语法
#pragma push
#pragma pop
pragma push 保存所有当前的pragma设置。

Pragma pop 恢复所有pragma设置范例
#pragma ANSI_strict on
#pragma push /* Saves all compiler settings. */
#pragma ANSI_strict off
#pragma pop /* Restores ANSI_strict to on. */
例程中的pragma不受任何面板设置影响,和之前其它的pragma的设定
8)__declspec(section name)
指定在已经定义的section中放置变量或者函数
语法
__declspec(section <section_name>) declaration
__declspec(section <section_name>) definition
参数
section_name
指定一个初始化过的数据段的名字
9)FORCEACTIVE
指定不能被优化掉的目标.
参数
FORCEACTIVE{ symbol [, symbol]* }
第二节 EPPC 链接器
使用EPPC Linker设置面板来控制设定链接相关选项,规定目标代码链接成的可执行文件,库或者其它的最终文件格式。

如下图所示2.10版本(图2-1)和10.3版本(图2-2)
图2-1:Codewarrior 2.10 版本
图2-2:codewarrior 10.3版本
EPPC 链接器设定面板各条目的含义及用法
元素目的注释
Link Mode list box 指定链接器使用多少内存做缓冲来写输出文件,然后写到硬盘上
选项:
∙Use Less RAM –直接将输出文件写到硬盘,不使用缓冲
∙Normal – 512字节缓冲
∙Use More RAM –将每个部分写到自己的缓冲,然后写回硬盘链接需要足够的RAM空间来保存输入文件。

Normal是最好的选择,More RAM更适合小工程
Generate DWARF Info
checkbox
Clear –不生成调试信息Checked –生成调试信息
Use Full Path Names checkbox Clear –链接器只使用文件名
Checked –链接器包含路径名字在elf文件中
Generate Link Map checkbox C lear –不生成map文件
Checked –生成map文件
List Closure checkbox Clear – map不列举程序开始点调用的函数
Checked - Map 文件列举所有程序开始点调用的函数
List Unused Objects checkbox Clear - Map 不包含没用到的目标Checked – Map 列举所有没有用到的目标
List DWARF Objects checkbox Clear - Map 不列出 DWARF 调试目标
Checked - Map 在Section里列出所有 DWARF 调试目标
Suppress Warning Messages checkbox Clear –链接器在消息窗口显示警告Checked –链接器不显示警告
Heap Address checkbox Clear – Heap顶和堆栈底相同Checked –指定heap内存位置参考表后备注.
Stack Address checkbox Clear –链接器使用默认的堆栈地址0x003DFFF0. 参考表后备注
Auto FAE: Alan Yang-r66151 Page 11
Checked –为堆栈指定栈顶内存地址
Generate ROM Image
checkbox
Clear –不生成ROM image. Checked –生成ROM image
RAM Buffer Address checkbox Clear –不指定RAM buffer地址
Checked –给flash 编程器指定RAM buffer地址。

许多其他的flash编程器使用指定的,
独立的缓冲区来加载所有的二进制段到连续的flash ROM地址空间。

尽管如此,在运行的
时候系统会将这些段加载到lcf文件或者数据地址框指定的地址。

对于Codewarrior Flash编程器,RAM buffer和
ROM image的地址是一样的。

(参考备注)
ROM Image Address checkbox C lear –不指定目标地址
Checked –为二进制文件指定ROM目标地址
参考备注
Use Linker Command File checkbox Clear –用户指定段地址,忽略lcf文件的配置。

Checked –从lcf文件中寻找段地址
如果选定,而lcf文件中并没有指定段地址,编
译器将报错
Binary File list box 生成二进制文件
∙None –不生成bin文件
∙One –一个二进制文件
∙Multiple –多个二进制文件
默认不生成二进制代码
Generate S-Record File checkbox Clear –不生成srecord文件.
Checked –生成S3 S-record文件
S-record 文件以 .mot扩展名存在,是早期的
srecord文件扩展名。

现在后缀名都是.s19,但
格式内容相同
Sort S-Record checkbox Clear –不排序s-recored文件
Checked –地址上升排序s-recored文件
.
Max Length text box 指定S-recored的最大长度(256字节或者少于)
EOL Character list box 针对不同系统指定srecord文件行尾的字符
Auto FAE: Alan Yang-r66151 Page 12
∙DOS - <cr> <lf>
∙Unix - <lf>
∙Mac - <cr>
Entry Point text box 指定程序性的入口地址-加载程序时使用的第一个函数默认函数是__start.c中的bootstrap/glue 代
码。

配置EABI的环境,然后执行main() Auto FAE: Alan Yang-r66151 Page 13
Heap
如果你的程序使用malloc 或者new将会使用到堆。

如果使用MSL C,你的程序可能会使用隐含的堆。

尽管如此,MSL分配程序不需要在栈下面申请堆。

如果不选择检验框,堆的高地址等于栈的底部。

RAM
MEMORY
{

reloc_flash: org = 0x0007F000, len = 0x00001000 //重定向的函数存储在Flash中

reloc_ram: org = 0x40005000, len = 0x00001000 // 重定向的函数在RAM中被调用

}
SECTIONS
{
….
.RelocCode (VLECODE) LOAD(ADDR(reloc_flash)): {} > reloc_ram // define a section for relocated functions }
2) 包含重定向函数的C文件,例如测试代码: void Delay(void)
#pragma push
#pragma section code_type ".RelocCode" ".RelocCode" code_mode = far_abs
__declspec(section ".RelocCode")
void Delay(int cnt)
{ int i,j;
for(i=0;i<cnt;i++) {
LedOn();
for(j=0;j<900000;j++) {
;
}
LedOff();
for(j=0;j<900000;j++) {
;
}
}
}
#pragma pop
3) 引用重定向函数的函数:
#pragma push
#pragma section code_type ".RelocCode" ".RelocCode" code_mode = far_abs
__declspec(section ".RelocCode")
extern void Delay(int cnt);
#pragma pop
int main(void) {

Delay(count);

}
4) 在EPPC LINKER 设置面板中选中Generate ROM Image. 否则LOAD指令会被忽略。

5) 注意: 在第 2)项中,如果 Delay()同时需要调用在Flash中的函数,比如, LedOn() and LedOff(). 那么我们需要向下面这样定义:
#pragma push
#pragma section code_type ".text_vle" code_mode = far_abs
__declspec(section ".text_vle")
void LedOn(void)
{
SIU.GPDO[68].B.PDO = 0;
}
void LedOff(void)
{
SIU.GPDO[68].B.PDO = 1;
}
#pragma pop
And similarly:
#pragma push
#pragma section code_type ".text_vle" code_mode = far_abs
__declspec(section ".text_vle")
extern LedOn(void);
extern LedOff(void);
#pragma pop
Codewarrior编译器会自动生成代码,在执行main函数之前将重定向的函数从FLASH拷贝到RAM。

相关文档
最新文档