LCF文件使用说明.docx
《LCF文件使用说明.docx》由会员分享,可在线阅读,更多相关《LCF文件使用说明.docx(14页珍藏版)》请在冰豆网上搜索。
LCF文件使用说明
Codewarrior2.10是飞思卡尔32位汽车级单片机Qorriva系列的编译器,与之前版本2.8、2.9完全兼容。
许多新用户对codewarrior链接文件不是十分了解,本文将针对链接文件的常见问题以及段的定义进行介绍帮助用户快速了解和使用CodeWarrior。
LCF文件定义及用法介绍
链接文件用来控制不同类型数据代码、数据以某种排列方式在最终在生成的可执行文件或者二进制文件,调试文件中的放置位置。
它可以通过在EPPClinker的面板中进行配置,也可以直接在lcf文件中直接进行修改。
Lcf文件中首先是对整个memorymap(MEMORY)地址空间内的所有RAM,ROM进行分割,将其分为几个区域,便于放置不同类型的存储内容,而这些区域内包含的内容可以是用户自定义的段或者系统预定义的段(SECTION)。
关于段的定义和使用将在lcf文件介绍结束后进行介绍。
一个工程通常在建立的时候默认的都是在RAM中执行,由于RAM中执行的效率高于FLASH。
在生成的ROMImage中常量,初始化过的数据或者代码如果没有被定义在ROM区域则假设为这部分代码要在程序开始执行的时候从ROM去拷贝到RAM区。
下面是一个完整的lcf文件,其中包括每行的解释及用法。
/*lcffileforMPC5604BM27V(debugRAMversion)文件的名字及对应单片机(RAM版本)*/
RAM版本和ROM版本的区别在于RAM版本不将程序下载到ROM中去,而在RAM中执行程序
/*512KBFlash,32KBSRAM单片机的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/*Heapstart*/(堆的起始地址)
stack:
org=0x40007C00,len=0x00000400/*StackStart*/(栈的起始地址)
}
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_handlertableALIGN(0x10):
{}
.data:
{}
.sdata:
{}
.sbss:
{}
.sdata2:
{}
.sbss2:
{}
.bss:
{}
}>internal_ram
}
/*FreescaleCodeWarriorcompileraddressdesignations*/
_stack_addr=ADDR(stack)+SIZEOF(stack);//ADDR()是取括号内段的首地址,SIZEOF()是求某段的长度
_stack_end=ADDR(stack);
_heap_addr=ADDR(heap);
_heap_end=ADDR(heap)+SIZEOF(heap);
/*ExceptionsHandlersLocation(usedinExceptions.cforIVPRinitialization)*/
EXCEPTION_HANDLERS=ADDR(exception_handlers);
备注
ALIGN
按照指定的边界进行排列,必须是2的整倍数。
SECTIONS
{
GROUP:
{
.initALIGN(0x1000):
{}
.textALIGN(0x1000):
{}
}>text
}
例子中定义了两个段:
.init和.text。
在运行的时候每个段都会被放在下一个可以使用的地址(可以被0x1000整除)
预定义的各个段的名称及解释
Section
Description
.init
包含初始化代码
.text
包含程序代码
.rodata
包含程序的常量
.sdata
包含初始化的全局小数据
.sdata2
包含初始化过的全局常量(const定义内容)小数据
.data
包含初始化过的全局数据
.sbss
包含未初始化过的全局小数据
.sbss2
包含为初始化过的全局常量(const定义内容)小数据
.bss
包含为初始化过的全局数据
.ctors
包含构造函数
.dtors
包含析构函数
section
Section使用pragma来将编译的目标代码放到预定义的段中,然后可以在LCF文件中将对应的段放到指定的地址区域。
Section和__declspec(section)都可以用来指定一个段,但是不能同时使用
语法
#pragmasection[objecttype|permission][iname][uname]
[data_mode=datamode][code_mode=codemode]
参数
objecttype
可以是以下三种选项,用来指定将目标数据放在哪里
∙code_type–可执行目标类型
∙data_type–非常量数据,包含比smalldata大的数据
∙sdata_type–非常量数据,包含比smalldata小或者等同的数据。
∙const_type–常量数据,包含比smallconst大的数据
∙sconst_type–常量数据,包含小或者等同smalldata的数据
∙all_types–所有数据和代码
permission
定义访问权限,包含下列三个选项
∙R–只读
∙W–可写
∙X–可执行
iname
定义段的名字,编译器存储初始化过的目标。
变量在定义的时候被初始化过的,函数和字符串也属于初始化过的目标。
Theinameparametermaybeoftheform.abs.xxxxxxxxwherexxxxxxxxisan8-digithexadecimalnumberspecifyingtheaddressofthesection.
uname
定义段的名字,编译器存储未被初始化过的目标。
下面是例子
#pragmapush//savethecurrentstate
#pragmasection".data""COMM"
intred;
intsky;
#pragmapop//restorethepreviousstate
data_mode=datamode
为编译器指定使用哪种数据模式
下面是可选的数据模式
∙near_abs–目标必须在16位地址空间
∙far_abs–目标必须在32位RAM地址空间
∙sda_rel–目标必须在链接器为smalldata定义的32K地址空间.
code_mode=codemode
向编译器指定地址模式
下面是可选的三种地址模式:
∙pc_rel–被调用子函数地址必须在调用函数24位地址空间范围内
∙near_abs–函数地址必须在24位地址范围
∙far_abs-函数地址必须在32位地址范围内
默认的地址模式是pc_rel
pop,push
保存和恢复pragma设置
语法
#pragmapush
#pragmapop
pragmapush保存所有当前的pragma设置。
Pragmapop恢复所有pragma设置
范例
#pragmaANSI_stricton
#pragmapush/*Savesallcompilersettings.*/
#pragmaANSI_strictoff
#pragmapop/*RestoresANSI_stricttoon.*/
例程中的pragma不受任何面板设置影响,和之前其它的pragma的设定
__declspec(sectionname)
指定在已经定义的section中放置变量或者函数
语法
__declspec(section)declaration
__declspec(section)definition
参数
section_name
指定一个初始化过的数据段的名字
注意
段的名字必须用双引号("").如果使用用户自定义的段,必须是事先用#pragma定义过的
预定义的段和默认段
Type
Name
Datamode
Codemode
code_type
".text"
data_mode=far_abs
code_mode=pc_rel
data_type
".data"
data_mode=far_abs
code_mode=pc_rel
const_type
".rodata"
data_mode=far_abs
code_mode=pc_rel
sdata_type
".sdata"
data_mode=sda_rel
code_mode=pc_rel
sconst_type
".sdata2"".sbss2"
data_mode=sda_rel
code_mode=pc_rel
".PPC.EMB.sdata0"".PPC.EMB.sbss0"
data_mode=sda_rel
code_mode=pc_rel
.
EPPC链接器
使用EPPCLinker设置面板(Figure3.10)来控制设定链接相关选项,规定目标代码链接成的可执行,库或者其它的最终文件格式。
EPPC链接器设定面板
元素
目的
注释
LinkModelistbox
指定链接器使用多少内存做缓冲来写输出文件,然后写到硬盘上
选项:
∙UseLessRAM–直接将输出文件写到硬盘,不使用缓冲
∙Normal–512字节缓冲
∙UseMoreRAM–将每个部分写到自己的缓冲,然后写回硬盘
链接需要足够的RAM空间来保存输入文件。
Normal是最好的选择,MoreRAM更适合小工程
GenerateDWARFInfocheckbox
Clear–不生成调试信息Checked–生成调试信息
UseFullPathNamescheckbox
Clear–链接器只使用文件名
Checked–链接器包含路径名字在elf文件中
GenerateLinkMapcheckbox
Clear–不生成map文件
Checked–生成map文件
ListClosurecheckbox
Clear–map不列举程序开始点调用的函数
Checked-Map文件列举所有程序开始点调用的函数
ListUnusedObjectscheckbox
Clear-Map不包含没用到的目标
Checked–Map列举所有没有用到的目标
ListDWARFObjectscheckbox
Clear-Map不列出DWARF调试目标
Checked-Map在Section里列出所有DWARF调试目标
SuppressWarningMessagescheckbox
Clear–链接器在消息窗口显示警告
Checked–链接器不显示警告
HeapAddresscheckbox
Clear–Heap顶和堆栈底相同Checked–指定heap内存位置
参考表后备注.
StackAddresscheckbox
Clear–链接器使用默认的堆栈地址0x003DFFF0.
Checked–为堆栈指定栈顶内存地址
参考表后备注
GenerateROMImagecheckbox
Clear–不生成ROMimage.Checked–生成ROMimage
RAMBufferAddress
checkbox
Clear–不指定RAMbuffer地址
Checked–给flash编程器指定RAMbuffer地址。
许多其他的flash编程器使用指定的,独立的缓冲区来加载所有的二进制段到连续的flashROM地址空间。
尽管如此,在运行的时候系统会将这些段加载到lcf文件或者数据地址框指定的地址。
对于CodewarriorFlash编程器,RAMbuffer和ROMimage的地址是一样的。
(参考备注)
ROMImageAddresscheckbox
Clear–不指定目标地址
Checked–为二进制文件指定ROM目标地址
参考备注
UseLinkerCommandFilecheckbox
Clear–用户指定段地址,忽略lcf文件的配置。
Checked–从lcf文件中寻找段地址
如果选定,而lcf文件中并没有指定段地址,编译器将报错
BinaryFilelistbox
生成二进制文件
∙None–不生成bin文件
∙One–一个二进制文件
∙Multiple–多个二进制文件
默认不生成二进制代码
GenerateS-RecordFilecheckbox
Clear–不生成srecord文件.
Checked–生成S3S-record文件
S-record文件以.mot扩展名存在,是早期的srecord文件扩展名。
现在后缀名都是.s19,但格式内容相同
SortS-Recordcheckbox
Clear–不排序s-recored文件
Checked–地址上升排序s-recored文件
.
MaxLengthtextbox
指定S-recored的最大长度(256字节或者少于)
EOLCharacterlistbox
针对不同系统指定srecord文件行尾的字符
∙DOS-
∙Unix-
∙Mac-
EntryPointtextbox
指定程序性的入口地址-加载程序时使用的第一个函数
默认函数是__start.c中的bootstrap/glue代码。
配置EABI的环境,然后执行main()
Heap
如果你的程序使用malloc或者new将会使用到堆。
如果使用MSLC,你的程序可能会使用隐含的堆。
尽管如此,MSL分配程序不需要在栈下面申请堆。
如果不选择检验框,堆的高地址等于栈的底部。
_stack_end=_stack_addr-(stack_size*1024);
_heap_end=_stack_end;
_heap_addr=_heap_end-(heap_size*1024);
如果你的代码不需要堆你可以清除堆地址检验框
注意
如果没有足够的空间,malloc函数会返回0.如果你不用malloc,可以把堆的大小设定为零来给其它需要内存空间的数据代码,栈。
Stack
在指定栈的开始地址后,栈使用将向下增长。
所以尽可能将栈顶设高
如果你没有指定栈的地址,链接器将使用0x003DFFF0.但是默认值并不适合所有板子,有些芯片RAM很小。
ROMImage
应用程序的ROMImage通常是整个应用程序镜像。
一个ROM镜像通过ROMImageAddress和RAMBufferrAddress来定义。
ROMImageAddress:
ROM将被分配在什么位置。
通常是在.lcf文件中定义的某一个存储块的开始。
RAMBufferAddress:
在RAM中指定一个位置,用来作为Flashimage编程器的缓冲区。
代码重定向
范例:
如果我们想把一个函数存在flash,但是在RAM中被执行
1)LCFfile:
MEMORY
{
…
reloc_flash:
org=0x0007F000,len=0x00001000//RelocatedfunctionsarestoredinFlash
…
reloc_ram:
org=0x40005000,len=0x00001000//RelocatedfunctionswillbeinvokedfromRAM
…
}
SECTIONS
{
….
.RelocCode(VLECODE)LOAD(ADDR(reloc_flash)):
{}>reloc_ram//defineasectionforrelocatedfunctions
}
在EPPCLinker设定面板打开GenerateROMImage。
否则LOAD指令将被忽略.
Codewarrior编译器会自动生成代码,在执行main函数之前将重定向的函数从FLASH拷贝到RAM。