ADI DSP开发中很重要的一个知识点:LDF,也就是内存分配(5) 作者的话我也同步找了一下ADI提供的LDF相关资料以BF533为例再做一下详细的说明。ADI DSP仿真器链接https://item.taobao.com/item.htm?id38007242820详细介绍ADSP-BF533.LDF前导段.LDF文件的开头是简单的注释介绍.LDF文件中可以使用的选项由链接器预处理器宏决定。在.LDF文件中的相关部分对这些选项有详细的解释。ARCHITECTURE指令规定这个.LDF文件用于ADSP-BF533 Blackfin处理器。所有的Blackfin处理器.LDF文件都面向单个处理器。SEARCH_DIR指令识别标准run-time库的位置像VisualDSP安装目录的Blackfin\lib子目录一样。链接器将$ADI_DSP置为VisualDSP安装目录。如果选择__NO_STD_LIB选项不包括SEARCH_DIR指令这意味着链接器没有搜索run-time库的缺省空间。这个选项由-no-std-lib编译器开关选择确保应用仅被用户提供的库链接。库选择这部分.LDF文件构建不同的宏和变量目的是产生$LIBRARIES表按需要的顺序搜索库和目标文件解决引用问题。一些选项指定选择一个库对另一个库如工作区激活版本对普通版本其它选项指定选择一个库对另一个库顺序如选择完全兼容的IEEE浮点支持版本对较高性能版。USE_FILEIO选项是强制定义的。这对在大部分开发周期内使用的printf()和其它与stdio-相关的函数是必要的。禁用USE_FILEIO选项就禁用了所有与stdio-相关的I/O操作。一些选项与指定代码介绍有关。编译器有三个开关用于profiler: -p, -p1和–p2。对这三种开关编译器用相同的方法编码使它在每个指定函数调用的开始和结束处调用profiling库以获得统计数据。这三种开关的不同之处是随后的应用如何报告收集到的数据。-p1开关将数据写到mon.out文件–p2开关将它写到标准的输出流-p开关将数据写到这两个位置。通过链接由.LDF文件选项控制的不同的目标文件就可以实现这些不同。开关选择下面的LDF选项• p selects USE_PROFILER• p1 selects USE_PROFILER1• p2 selects USE_PROFILER2当检测到输入目标文件被指定给profiling时由预链接器设置一个附加的USE_PROFILER0选项。这意味着即使链接时没有打开profiling开关也必须链接profiling库。USE_PROFILER用来设置USE_PROFILER0解释链接时任何profiling开关的缺少缺少时表明两种输出方法都要使用。通过链接包括两个全局变量的小目标文件决定输出方法的选择。这些变量表明是否选择了每个输出方法。几个不同的目标文件定义两个变量的置换见表2。像其它的目标文件一样这些文件存在几个变量如“普通”和“激活工作区”变量。当对象构建了激活工作区时会产生不同的代码以处理已知的芯片异常。当对象只包括数据时没有代码在这个特例中这个“激活工作区”开关不起作用“变量”是一样的。仍旧构建这些冗余的多个变量是为了保持命名习惯。如果需要profiling的话PROFFLAG被定义为一个目标文件的名称。如果不需要就不定义PROFFLAG。OMEGA是包括idle程序的文件名称。如果应用自动终止如从main()返回或通过调用exit()就使用这个程序。只要链接时需要工作区__WORKAROUNDS_ENABLED选项就被编译器驱动器定义尽管编译时可以单独选择每个可用的工作区不能对所有的工作区组合提供预构建库。因此每个库和目标都有单个激活工作区版本选择了所有的工作区。MEMINIT保持目标文件的名称包括指向由存储器初始化实用程序产生的任何初始化数据的指针。除非随后的应用被存储器初始化程序处理否则这个指针是NULL指针。这个文件没有变量。规定LIBSMALL是监视模式库的名称。M3_RESERVED选项用于模拟器。缺省时模拟器将Blackfin处理器的堆栈用作工作区不过可以使用M3寄存器来替代它。构建的run-time库具有-reserve m3开关允许使用寄存器替代堆栈用作工作区。但有少量程序需要额外的处理。如如果保留了M3中断处理程序可能不存储和恢复M3但如果没保留就必须进行这样存储和恢复。因此用一些库的两个变量来处理这种情况。LIBM3包括异常处理程序setjmp()和longjmp()而LIBDSP包括与DSP有关的优化程序当M3被模拟器保留时会损失一些性能。通过排序选择浮点库。完全兼容的库是独立的库高性能库是LIBDSP的一部分。这两个库的排序根据需要的浮点库而改变。由–ieee-fp编译器开关设置IEEEFP选项选择替代排序方案。这样选择的库被汇编到LIBS表如果设置了__ADI_LIBEH__(链接时由–eh设置)可以选择与C异常–eh和–rtti开关一起构建的C库。合适的文件I/O库附到这个表上形成完整的$LIBRARIES表。CRT的选择这部分选择需要的C run-time部分(CRT)的预构建版本调用在main()之前执行的启动代码。根据下面的四个选项的值定义的或未定义的选择CRT• USE_PROFILER• USE_FILEIO• __cplusplus• __WORKAROUNDS_ENABLED选中的目标文件命名时使用本应用指南前面介绍的后缀。对后三个选项选择单个目标文件包括在$OBJECTS表中。如果选择USE_PROFILER也设置CRT以包括profiling库和前面决定的PROFFLAG文件。C构建(__cplusplus选项)时把ENDCRT定义成包括C构造器表的表结束符号的对象。对其它构建不定义ENDCRT。然后CRT和ENDCRT、以及COMMANDLINEOBJECTS被包括在COMMAND_LINE_OBJECTS被包括在COMMANDL​INEO​BJECTS被包括在OBJECTS表中链接器定义它是链接器命令行上命名的所有对象和库。CPLB定义表对象用来配置CACHE设置完成$OBJECTS表。LIBRARIES和LIBRARIES和LIBRARIES和OBJECTS为链接器使用的源命名以分解符号。OBJECTS中的项被链接到应用中OBJECTS中的项被链接到应用中OBJECTS中的项被链接到应用中LIBRARIES从$OBJECTS得到分解符号参考。存储空间声明Blackfin处理器.LDF文件定义与硬件存储器映射很接近的存储器。.LDF文件有附加的划分方法可以根据run-time库如堆和堆栈的不同需要对存储器进行合适的分配。核与系统的存储器映射的寄存器(MMR)在存储器的顶部。链接器不允许为核MMR定义存储器部分这个存储器声明被通过注释去掉不过还保留下来以保持透明度。定义了L1中间结果暂存器不过.LDF文件不使用它。注意静态初始化数据可能不会映射到中间结果暂存器。L1指令存储器被分为代码和代码CACHE。代码CACHE可以被选作CACHE或代码空间。L1数据存储器Bank B被分为数据和数据CACHE前者进一步分为常数数据和堆栈使用的空间。总的来说.LDF文件试图将堆栈放置到快速L1存储器中因为编译器常常将堆栈用作函数参数和临时工作空间。L1数据存储器Bank A也有CACHE/非CACHE的划分。非CACHE区域有可选择的256字节用于命令行变量。这个IDDE_ARGS选项支持导配置文件导引优化PGO如前面所述。定义了4个异步存储器Bank和一个SDRAM Bank。后者是存储器的最低Bank是一个32 MB的空间最低16 KB被声明为堆使用。注意堆不包括地址0x0000 0000这个地址为C中的NULL指针保留不能用来指向有效的数据。代码/数据到存储器映射定义PROCESSOR指令将随后得到的.DXE文件写入$COMMAND_LINE_OUTPUT_FILE这是链接器定义的输出文件名称由编译器驱动器传递。使用RESOLVE指令start符号CRT的第一个可执行部分被直接映射到处理器的复位地址。如果使用配置文件导引优化PGO通过同样的方法_argv_string符号被直接映射到变量部分的开头。_main和start符号被明确命名以免激活选项时被链接器屏蔽。.LDF文件的其余部分将代码或数据通过存储区域从输入部分映射到输出部分。.LDF文件是通用的目的是确保适用所有的情况。因此像program和data1这样的部分被映射到不同存储区域的大量输出部分中。当一个存储部分添满后余下的可能会进入其它的部分。一些项可以随意映射。C对象仅能用于C链接映射代码和数据被映射到L1 SRAM (当指定USE_CACHE选项时被映射到外部存储器)的CACHE区域中。BSZ部分被标记为ZERO_INIT它指示存储器初始化时将相应部分初始化为空并且在运行时应该填充零。bsz_init部分包括指向存储器初始化程序产生的表的开始处的指针通常被映射到只读存储器。为简单起见在开发的初期它被映射到常规数据部分。.meminit部分被链接器区别对待。在链接时.meminit中没有代码和数据。不过一旦链接完成.meminit部分会扩展使存储区域中所有未使用的空间用来容纳被映射的内容。特殊的.LDF文件中.meminit被映射到MEM_L1_DATA_B因此链接后.meminit占据.DXE文件未使用的MEM_L1_DATA_B的其余部分。这定义了一个空白空间存储器初始化程序可以用它来存储配置表。像bsz_init一样.meminit部分通常映射到只读存储器空间。堆栈和堆空间没有.LDF文件映射的数据。而是各自定义全局符号包括它们的开始、结束地址和长度对堆而言。这允许Run-time Bank来决定运行时堆栈和堆的大小和位置因此在.LDF文件中可以很容易地修改它们。注意CRT要求这些符号。结尾以上就是ADI DSP的LDF全部内容。在下载区我会把这个LDF的工程上传有兴趣的兄弟可以下载下来再对照文章仔细瞅瞅。