第7章 Memory
7.1 Background
本章处理静态内存配置(也就是内存映射和片放置)、缓存和栈。还提供了有关动态内存分配(运行时分配和释放内存)等相关信息。
静态存储器配置涉及到可执行文件的“内存映射”,以及将代码和数据放置到内存映射中。内存映射由CPU和位于硬件板上的外部存储器区域内存在的内存区域组成。参考7.2节获取有关内存映射的详细信息。
代码和数据由链接器使用链接命令文件放置在内存区域中。链接命令文件指定了内存映射。对于每个内存区域,链接命令文件都指定了原始或基地址、长度和属性(读、写和执行)。链接命令文件所指定的内存区域也叫“内存段”。
以下为来自链接命令文件的内存映射说明:
MEMORY {
IRAM (RWX) : org = 0x800000, len = 0x200000 DDR : org = 0x80000000, len = 0x10000000 } |
如下例所示,链接命令文件还包含“内存片”放置信息。片(Sections)是由编译器产生的可再分配块代码。编译器产生一些众知段以放置各种类型的代码和数据,例如:.text、.switch、.bss、.far、.cinit和.const。请参考相应的编译器用户指南了解相关信息。
SECTIONS {
.text: load >> DDR . switch: load >> DDR .stack: load > DDR .vecs: load >> DDR .args: load > DDR .sysmem: load > DDR .far: load >> DDR .data: load >> DDR .cinit: load > DDR .bss: load > DDR . const: load > DDR .pinit: load > DDR .cio: load >> DDR } |
链接器将“内存片”(如.text和.cinit)放置进“内存段”(如IRAM),由链接命令文件中的SECTIONS部分指定。参考7.3节获取有关片放置的详细信息。
7.3节讨论SYS/BIOS应用程序的片放置。(MSP430用户应查看7.4节)
7.5节讨论栈,包括如何配置系统栈和任务栈。
7.6节涵盖缓存配置,具体到C6000和缓存运行时APIs。
7.7节也讨论动态内存分配。运行时代码可从“堆”中分配和释放内存,也就是以动态内存分配为目的的内存池预留和管理。
各种堆实现在7.8节描述。
7.2 内存映射
注意:如果你使用的是MSP430,见7.4节,这节不适用于MSP430.
可执行文件的内存映射由设备(有内部存储的)和硬件板(有外部存储的)决定。当你使用SYS/BIOS创建一个CCS项目,在RTSC Configuration Settings项选择一个“platform”时,板载和外部内存的内存映射已经由此平台决定。平台还设置时钟速率和指定内存片放置。
当你创建一个新项目或更改项目属性时选择平台,而不是在创建配置文件时选择。如果可执行文件运行于相同类型的板子上时需要不同的内存映射,必须使用不同的平台。
平台绑定到一个特定设备(CPU)并从设备获取内部内存映射,如IRAM和FLASH。平台还包含外部存储器规格和缓存设置。内部和外部内存段都来自内存映射。
7.2.1 选择一个可用的平台
在生成SYS/BIOS 6.x可执行文件之前,你需要选择所使用的硬件板。可通过创建CSS项目或在项目的
CCS General属性里的RTSC标签内做此选择。
Platform字段提供了一个匹配目标的所有可用平台的下拉列表;这些项目代表了你所选择设备(CPU)的各种类型的可用的开发板。
![基于TI-RTOS的CC2650DK开发(17)---Memory(内存) - 阿巴睇 - 阿巴睇的博客](http://img2.ph.126.net/ibXvaWE6idb05daHgw2L5g==/6632028738862119266.jpg)
查看你的平台的内存映射,可以通过选择
Tools > RTSC Tools > Platform > Edit/View打开平台向导。在你的SYS/BIOS安装内选择包库(也就是目录:
<bios_install_dir>\packages)。然后单击
Next选择你所使用的包。
![基于TI-RTOS的CC2650DK开发(17)---Memory(内存) - 阿巴睇 - 阿巴睇的博客](http://img1.ph.126.net/a6P4kkTFZ69hAamReF-XSA==/6631548252283878835.jpg)
- 你处于开发阶段,正在使用评估板。
- 你不关心缓存大小,并且对现有平台设置的默认值感到满意。
- 你不希望改变默认片放置。
- 你希望与评估板相同的时钟速率
如果上述条件中任何一条不满足,参考7.2.2节。
7.2.2 创建自定义平台
在应用程序开发过程中的某个点上,大多客户建立自己的主板,选择TI设备并加入自定义外部存储。如果满足下列条件之一,你还需要创建自己的平台:
- 你希望自定义缓存尺寸。
- 你希望手 动重写默认片放置。
对于这些自定义主板,你需要使用平台向导创建一个平台。平台向导是一个GUI工具,使你可以简单地寻到个自定义平台。创建自定义平台在定义内存映射和为片放置选择默认内存段方面提供了很大的灵活性。
通过以下设置运行平台向导:
1、在CSS菜单中选择
Tools > RTSC Tools > Platform > New,将会打开新平台向导。
2、输入包名。这应该是包含平台包的目录名称,也是为项目使用选定平台时所选择使用的名称。你可以使用简单名称或句号分隔名。当平台包创建时,句号对应目录层级。例如,如果你使用C:\myRepository\packages作为存储位置,myBoards.DA830_bigCache将被创建在C:\myRepository\packages\myBoards\DA830_bigCache。
3、接下来是
Platform Package Repository字段,单击
Browse,选择平台包所存储的位置,默认是C:\Users\<username>\myRepository\packages。
![基于TI-RTOS的CC2650DK开发(17)---Memory(内存) - 阿巴睇 - 阿巴睇的博客](http://img0.ph.126.net/TqBPa_2DD3IRbrPp0Swpag==/6631754960469913125.jpg)
4、另外,如果已经创建了一个相关平台的CCS项目,选中
Add Repository to Project Package Path复选框。然后选择将要访问此存储位置的项目。你无需立即做此项工作,也可以在project’s Build Properties对话框添加项目的存储位置。
5、在下拉列表中选择
Device Family和
Device Name,如:
![基于TI-RTOS的CC2650DK开发(17)---Memory(内存) - 阿巴睇 - 阿巴睇的博客](http://img0.ph.126.net/txH1ksFwr1yqSiPhZGdxhA==/6631606526400158967.jpg)
注意:如果你希望另一个项目可用此平台,可之后在右键单击此项目,选择Build Properties,并将存储位置包含进此平台。选择CCS General类别、RTSC标签,单击Add并找到项目可寻找到的平台所对应的存储位置的文件系统。
接下来查看小节,介绍为你的平台指定缓存、段和片使用的方法。也可以访问
Demo of the RTSC Platform Wizard观看使用平台向导的演示。
7.2.2.1 获取和设置时钟频率和默认内存设置
设备页没有时钟频率设置,无外部内存段,无内存片分配。通常,第一件事应当是从已存平台输入默认设置,可以此为基础进行你所需要的修改。
使用以下步骤输入默认值:
1、单击
Import按钮,接下来是Clock Speed字段。
2、在
Select Platform对话框中,选择你想要输入的默认平台,然后单击
OK。
![基于TI-RTOS的CC2650DK开发(17)---Memory(内存) - 阿巴睇 - 阿巴睇的博客](http://img0.ph.126.net/2SWX0z_fDLh9BnZoKWx10g==/6632007848141199978.jpg)
4、此时你会看到默认时钟频率和外部存储设置。可根据需求更改它们。
![基于TI-RTOS的CC2650DK开发(17)---Memory(内存) - 阿巴睇 - 阿巴睇的博客](http://img1.ph.126.net/zHfUcC3ALlutT5kHZFS-zA==/6632146386606300361.jpg)
7.2.2.2 决定缓存尺寸和自定义平台
因为缓存尺寸影响内存映射,如果你使用的是C6000目标,当创建平台时,需要决定你希望使用的尺寸。例如,如果在使用"ti.platforms.evmDA830" 平台,L1P、L1D和L2缓存尺寸影响L1PSRAM、L1DSRAM和IRAM的可用尺寸。
因为缓存尺寸在平台中设置,可执行文件所需的不同缓存配置也需要不同的平台。
下列步骤使用平台向导的设备页指定TMS320DA830平台的最大缓存尺寸:
1、设置L1D缓存为32K。设置L1P缓存为32K。设置L2缓存为256K。
2、注意L1PSRAM、L1DSRAM和IRAM的尺寸被调整为0。
![基于TI-RTOS的CC2650DK开发(17)---Memory(内存) - 阿巴睇 - 阿巴睇的博客](http://img2.ph.126.net/j2SoVUgS6iKlxHAc3xglqQ==/6632065022745845123.jpg)
7.2.2.3 为数据、代码和栈选择默认内存段
平台还可以为代码、数据和栈的放置决定默认内存段。如果你不想显式地放置片,就使用默认值。例如,如果不在*.cfg文件中配置Task栈的位置,那么Task栈将会被放置在由平台指定的栈内存段。
您可以通过选择在平台定义中的数据存储器、代码存储器和堆栈内存的值来粗略地决定要在哪里放置代码、数据和堆栈。
例如,在evmDA830中,如果希望代码放在SDRAM并且数据放在RAM,你可以在平台向导中选择Code Memory值为SDRAM,Data Memory值为IRAM来实现这些。
![基于TI-RTOS的CC2650DK开发(17)---Memory(内存) - 阿巴睇 - 阿巴睇的博客](http://img0.ph.126.net/md9HcgXP19qPuhipIyvVNg==/6632192566094665233.jpg)
7.2.2.4 设置自定义基地址和段长度
你可以自定义内部和外部内存段的名称、位置、大小、类型和访问。
自定义内部内存段,首先在Device Memory区域选择
Customize Memory多选框。单击内存段下拉列表进行改变。在
Name、
Base和
Length列,输入你想使用的值。
Space和
Access列,你可以通过选项列表选择。
![基于TI-RTOS的CC2650DK开发(17)---Memory(内存) - 阿巴睇 - 阿巴睇的博客](http://img1.ph.126.net/Bp_M_NArm4e97uK246gy7Q==/6631642810283872483.jpg)
定制外部内存段,你可以右击External Memory区域并选择
Insert Row或
Delete Row。
![基于TI-RTOS的CC2650DK开发(17)---Memory(内存) - 阿巴睇 - 阿巴睇的博客](http://img0.ph.126.net/987cuziubROS7j000kd8ew==/6631721975121039261.jpg)
请通过以下网址观看定制内存段示例:
http://rtsc.eclipse.org/docs-tip/Demo_of_Customizing_Memory_Sections
7.3 在内存段内放置片
注意:如果你在使用MSP430,请参考7.4节。这节内容不适用于MSP430。
平台定义了你的应用程序映射以及这些节在内存中的默认片放置。平台提供了对“代码”、“数据”、“栈”的普通片控制。对于更细粒度的片控制,这里有几个选项:
- 定义并放置不属于SYS/BIOS管理的新片,可以如7.3.1、7.3.2节所述的更改项目配置文件,或如7.3.3节所述的追加一个链路命令文件。
- 更改SYS/BIOS管理的片的放置,可以如7.3.1、7.3.2节所述的更改项目配置文件,或提供你自己的链路命令文件以替代部分或全部的自动生成的那一个,如7.3.4节所述。
注意:在*.cfg文件中将片放入段时,需要在文本编辑器中编辑你的*.cfg脚本源代码。目前,还无法使用XGCONF GUI编辑器。
7.3.1 配置简单片放置
在配置文件中,片放置是通过Program.sectMap[]数组实现的。下例简单演示了将段配置为放置哪个片:
Program.sectMap[
".foo"] =
"IRAM";
|
此例将使IRAM段用于.foo片的载入和运行。
7.3.2 使用SectionSpec配置片放置
Program.sectMap[]数组将片名映射至SectionSpec类型结构体。如果使用如上节所示的简单声明语法,不需要创建SectionSpec结构体。使用SectionSpec结构体让你在为指定片如何运行或载入内存段(或地址)获得更为精确的控制。
SectionSpec结构体包含以下字段:
- runSegment:片在哪个段上运行。
- loadSegment:片在哪个段上被载入。
- runAddress:片运行的起始地址。不能同时指定runSegment和runAddress。
- loadAddress:片载入的起始地址。不能同时指定loadSeegment和loadAddress。
- runAlign:由runSegment指定的片对齐。如果你指定了runSegmeent,仍可指定runAlign。
- loadAlign:由loadSegment所指定的片对齐。如果指定了loadSegment,仍可指定loadAlign。
- type:你可以使用此字段来定义各种指定目标标志以标识片类型。例如COPY、DSECT和NOLOAD。
- fill:如果赋值,此值用于未初始化片的初始化。
下面的.cfg文件声明指定了.foo片在哪个内存段载入和运行:
Program.sectMap[
".foo"] =
new Program.SectionSpec();
Program.sectMap[ ".foo"].loadSegment = "FLASH"; Program.sectMap[ ".foo"].runSegment = "RAM"; |
如果一个片仅指定了loadSegment或runSegment,那么载入和运行将使用指定段的默认行为。
下列声明将Swi_post()函数放置进IRAM内存段:
Program.sectMap[
".text:_ti_sysbios_knl_Swi_post__F"] =
new Program.SectionSpec();
Program.sectMap[ ".text:_ti_sysbios_knl_Swi_post__F"] = "IRAM"; |
以下声明将所有Task模块的静态实例放置在.taskStatic片:
var Task = xdc.useModule(
'ti.sysbios.knl.Task');
Task.common$.instanceSection = ".taskStatic"; Program.sectMap[ ".taskStatic"] = new Program.SectionSpec(); Program.sectMap[ ".taskStatic"].loadSegment = "IRAM"; |
使用sectMap数组指定片的配置声明会影响到从配置生成的链接命令文件的片放置。
7.3.3 提供追加的链接命令文件
也可以提供自己的链接命令文件以补充XDCtolls生成的那个。你可以此定义新片并利用链接命令语言的所有可用功能。
简单地将链接命令文件写入你的CCS项目。文件必须有一个*.cmd文件扩展名。CCS自动组织这样的链接命令文件并于链接步骤间调用。
内存映射定义(链接命令文件的“内存”规范)由平台处理,所以此方法不能用于改变现存内存段的定义。
此方法用于定义新的内存片。如果希望更改由SYS/BIOS管理的片放置,请使用7.3.1、7.3.2、7.3.4节所描述方法中的一种。
7.3.4 默认链接命令文件和自定义选项
SYS/BIOS应用程序在处理配置文件时自动生成链接命令文件。这些命令文件通常位于配置包,如下所示:
![基于TI-RTOS的CC2650DK开发(17)---Memory(内存) - 阿巴睇 - 阿巴睇的博客](http://img2.ph.126.net/ULAUMJoLQpJL0GUoMuGYvw==/6632083714443524759.jpg)
你可以使用以下任何一项技术定制自动生成链接命令文件:
- 从自动生成的命令文件中排除片,请参考http://rtsc.eclipse.org/cdoc-tip/xdc/cfg/Program.html#sections.Exclude里面的配置Program.sectionsExclude参数例子。
- 替代生成的链接命令文件中整个SECTIONS部分,请参考Program.sections模板参数:http://rtsc.eclipse.org/cdoc-tip/xdc/cfg/Program.html#sections.Template。
- 为程序链接命令文件指定模板,参考:http://rtsc.eclipse.org/cdoc-tip/xdc/cfg/Program.html#link.Template获取使用Program.linkTemplate参数使用信息和例程。使用简单方法为你的程序第一次自动生成链接命令文件创建一个模块,然后将其编辑为合适你的应用程序需要,然后参考你的编辑文件设置Program.linkTemplate参数。
重要事项:此项技术需要在每次改变配置、平台或安装新版本XDCtools时都拷贝自动生成链接命令文件并编辑它。
7.4 MSP430、Stellaris M3和C28x的片和内存映射
当你创建一个CCS项目,必须在CCS项目创建向导,选择一个设备作为项目设置的一部分(例如MSP430F5435A)。所选设备的链接命令文件会被CCS自动添加到项目内。
在向导的RTSC Configuration Settings页中,会基于你之前的选择自动配置目标和平台。我们推荐使用在Build-Profile中使用“release”,甚至在代码开发的debugging阶段。查看2.4.5节获取更多关于为MSP430减少执行文件尺寸的生成设置。
MSP430、Stellaris Cortex-M3微控制器,C28x设备的平台和其它平台不一样,它们不为设备定义内存映射,而是直接在项目向导中添加链接命令文件使用。任何内存映射和片放置的改变都可通过直接编辑链接命令文件而实现。查阅
MSP430 Optimizing C/C++ Compiler User's
Guide获取更多链接命令文件选项信息。
注意,一个附加的XDCtools生成的链接命令文件添加进项目时,此文件会代替SYS/BIOS指定的少部分。这个命令文件假设“FLASH”和“RAM”是内存映射的一部分。
注意:有关使用SYS/BIOS的指定硬件信息,请参考链接:
http://processors.wiki.ti.com/index.php/Category:SYSBIOS