5-1 二进制目标文件格式
视频地址:二进制目标文件格式
这个视频主要详细讲解CMD文件的编写。
主要讲解以下四个部分内容:
- 二进制目标文件格式:介绍DSP编译器或者说是CCS支持生成二进制目标文件的格式。
- CMD文件(Linker Command Files):详细讲解CMD文件的编写,并以一个CMD文件为例讲解各个模块的功能。
- MAP文件:介绍一下MAP文件。
- 预编译指令#pragma:介绍与内存分配有关的预编译指令,使用预编译指令可以指定代码的存储空间。
- ABI和EABI:ABI是应用程序二进制接口,EABI是嵌入式应用程序二进制接口。所谓的接口就是我们所生成的目标文件在与其他目标文件调用的时候调用的标准。在程序中调用其他人写的库文件,必须知道接口才能调用。
- COFF和ELF:COFF是通用目标文件格式,ELF是可执行和链接格式。在程序中,每一个源文件都会编译成一个.obj的目标文件,在链接的步骤将所有的.obj文件链接到同一个可执行文件中。COFF文件中包含一个入口地址、各个段和各个段的内存大小及初始化的值等信息。ELF文件和COFF格式基本类似,但又做了一些改进。使用ELF文件在进入main函数之前会将全局变量初始化为0,而且使用ELF文件格式会很简单的链接一些动态的代码。
- ABI和EABI类似于一个容易,而COFF和ELF相当于在容器中二进制文件的具体组织形式。COFF在Windows下常用,.exe就使用的PECOFF的格式。ELF通常在Linux下使用的
二进制文件。TI的7.2版本以上的编译器才支持ELF文件格式。今后可能对ELF文件格式的支持会越来越多。 - ELF文件格式是一种趋势,支持比较好,将来的二进制文件格式可能会统一到ELF。
- Section段是二进制文件中的最小单元,每个段内所有的内存都是占用的连续的存储空间,不同的段的存储空间可能不是连续的。
我们的代码存在.text段,它所占用的空间都是连续的。.bss段,可能处在另一部分存储空间。TMS320C6748内部有32KB的一级程序缓存,32KB的一级数据缓存和256KB的二级RAM,还有128KB接在总线上的共享RAM。通过CMD文件可以将.text段放在256KB的L2 RAM中,把.bss放在128KB的共享RAM中。
在一个应用程序可执行文件中,有些代码编译好后会确定不变的,.text中保存固定的代码,可以存在ROM或FLASH中,程序中的全局变量和局部变量在运行中变量我们是不知道的(可变的),由于值修改的比较频繁,可以把数据放在数据存储比较快的RAM中,我们不需要保存这些值,掉电易失。这就是为什么程序要分段。
对于我们的DSP来说,程序运行时默认把所有的段复制到内存中,这样做的为了加快程序的执行速度,从ROM或FLASH中读取数据的速度要远远慢于从RAM中读取数据,一般将这些数据复制到内存再开始执行。如果复制到程序存储器来执行速度就会慢很多。
- ROM:保存内容固定的代码,具体的指令、启动时候的初始化表。
- RAM:保存易变的代码,频繁修改的内容。
- near和far:对于16位的CPU来说,16位CPU内部只有16根地址线,最大寻址空间是64KB,如果要寻址超过64KB的内容需要通过地址加偏移的方式。对于32位CPU则没有这个问题。
回顾DSP C6748内部可以使用的存储空间。在C6748内部没有可供用户使用的程序存储空间,虽然有1MB大小的ROM,但只能用于启动使用,不能存放用户代码。
对DSP内部空间的读写不需要初始化操作。128KB的共享RAM在使用之前要对它进行使能。
对于接在扩展接口的外部的存储空间来说,在使用之前必须要初始化,比如外接的DDR2或mDDR,首先需要对DDR2或mDDR控制器进行初始化。
5-2 内存空间声明及分配
视频地址:内存空间声明及分配
CMD文件(Linker Command Files)链接 命令 文件,一个工程中可以有多个CMD文件,但内存分配不能重叠。
两个重要的关键字:
- MEMORY:指示存储空间
- SECTIONS:为各个段分配空间。
CMD文件里命名的时候,关键字不能冲突。
MEMORY
{ // DSP内部的存储空间
名称 可选关键字[RWIX] : o 十六进制地址 l 十六进制地址
}
名称:可以是任意的名字,只要自己能够理解就可以;
可选关键字:代表内存区域的属性,R表示内存空间可以读取,W表示内存空间可以被写入,I代表内存空间可以被初始化,X代表内存空间的代码可以被执行。默认省略,代表这段空间同时具有RWIX四种属性;
: :可加可不加;
o:空间的原始地址,ORIGIN origin org o都可以,后面跟一个十六进制的地址;
l:使用l这个关键字指定内存空间的长度,LENGTH length len l都可以使用,后面跟一个十六进制长度。
各个段内存的分配
SECTION
{
.text > MEMORY中定义的名称
}
对每一个段可以指定一些属性:
- RUN run:运行地址
- LOAD load:加载地址
- fill FILL:初始填充值
- type TYPE:类型
- align ALIGN:内存对齐,对齐的好处是提高CPU对内存的读取效率。对32位的CPU来说,进行一次内存读取一般默认读取4个字节的内容。
对于DSP C6748 AM1808 OMAPL138来说,三款CPU pin to pin兼容,不同的是CPU核心不同。DSP C6748内部只有一个DSP C674x核心。OMAPL138内部有一个DSP C674x核心和ARM9核心。AM1808内部只有一个ARM9核心。
/****************************************************************************/
/* */
/* OMAPL138 及 DSP C6748 内存空间分配定义 */
/* */
/* 2014年07月05日 */
/* */
/****************************************************************************/
#define DSP_CORE // 宏定义 后面有一个条件编译选项 针对DSP还是针对ARM
-o test.out // 指示工程输出文件的名称和路径 CMD文件中修改的参数会覆盖掉工程设置的参数
-m 11.map // 指示工程输出文件的名称和路径 CMD文件中修改的参数会覆盖掉工程设置的参数
-stack 0x10000 // 指示堆和栈的值
//-heap 0x10000 // 指示堆和栈的值
main.obj // 指示要包含的目标文件
-l libc.a // 需要包含的库
// 指示工程中可能用到或者需要用到的内存空间
MEMORY
{
#ifdef DSP_CORE
/****************************************************************************/
/* */
/* DSP 专有内存区域 */
/* */
/****************************************************************************/
DSPL2ROM(R) origin = 0x00700000 length = 0x00100000 /* 1MB L2 DSP 本地 ROM (DSP ROM Bootloader) */
DSPL2RAM(RWIX) org = 0x00800000 len = 0x00040000 /* 256kB L2 DSP 本地 RAM */
DSPL1PRAM o = 0x00E00000 l = 0x00008000 /* 32kB L1 DSP 本地程序 RAM */
DSPL1DRAM o = 0x00F00000 l = 0x00008000 /* 32kB L1 DSP 本地数据 RAM */
#endif
/****************************************************************************/
/* */
/* 公共内存区域 */
/* */
/****************************************************************************/
SHDSPL2ROM o = 0x11700000 l = 0x00100000 /* 1MB L2 共享内置 ROM */
SHDSPL2RAM o = 0x11800000 l = 0x00040000 /* 256KB L2 共享内置 RAM */
SHDSPL1PRAM o = 0x11E00000 l = 0x00008000 /* 32KB L1 共享内置程序 RAM */
SHDSPL1DRAM o = 0x11F00000 l = 0x00008000 /* 32KB L1 共享内置数据 RAM */
EMIFACS0 o = 0x40000000 l = 0x20000000 /* 512MB SDRAM (CS0) */
EMIFACS2 o = 0x60000000 l = 0x02000000 /* 32MB 异步 (CS2) */
EMIFACS3 o = 0x62000000 l = 0x02000000 /* 32MB 异步 (CS3) */
EMIFACS4 o = 0x64000000 l = 0x02000000 /* 32MB 异步 (CS4) */
EMIFACS5 o = 0x66000000 l = 0x02000000 /* 32MB 异步 (CS5) */
SHRAM o = 0x80000000 l = 0x00020000 f = 0xFFEEDDCC /* 128KB 共享 RAM */
DDR2 o = 0xC0001000 l = 0x08000000 /* 128MB DDR2 分配给 DSP */
EntryPoint o = 0xC0000000 l = 0x00000800 /* 2 KB C 语言入口点 */
Vector o = 0xC0000800 l = 0x00000800 /* 2 KB 中断向量表 */
/****************************************************************************/
/* */
/* 外设内存区域 */
/* */
/****************************************************************************/
page 2:
SYSCFG0 o = 0x01C14000 l = 0x00001000 /* 4K SYSCFG0 */
uPP o = 0x01E16000 l = 0x00001000 /* 4K uPP */
GPIO o = 0x01E26000 l = 0x00001000 /* 4K GPIO */
McBSP1 o = 0x01D11000 l = 0x00000800 /* 2K McBSP1 */
#ifndef DSP_CORE
/****************************************************************************/
/* */
/* ARM 专有内存区域 */
/* */
/****************************************************************************/
ARMROM o = 0xFFFD0000 l = 0x00010000 /* 64kB ARM 本地 ROM (ARM ROM Bootloader) */
ARMRAM o = 0xFFFF0000 l = 0x00002000 /* 8kB ARM 本地 RAM */
#endif
}
SECTIONS
{
.text{} > DDR2 align(32768) /* 可执行代码 */
.text:_c_int00 > SHDSPL2RAM /* 可执行代码 C 程序入口点*/
.stack > DDR2 /* 软件系统栈 */
.cio > DDR2 /* C 输入输出缓存 */
.vectors > Vector /* 中断向量表 */
.const > DDR2 /* 常量 */
.data > DDR2 /* 已初始化全局及静态变量 */
.switch > DDR2 /* 跳转表 */
.sysmem > DDR2 /* 动态内存分配区域 */
.args > DDR2
.ppinfo > DDR2
.ppdata > DDR2
/* TI-ABI 或 COFF */
.pinit > DDR2 /* C++ 结构表 */
.cinit load = DDR2 /* 初始化表 */
/* EABI */
.binit > DDR2
.init_array > DDR2
.fardata > DDR2
.rodata > DDR2
.c6xabi.exidx > DDR2
.c6xabi.extab > DDR2
GROUP(NEARDP_DATA)
{
.neardata
.rodata
.bss
} > DDR2
.far > DDR2
/* DDR2 */
.buffer > DDR2
/* 外设 */
.Reg_SYSCFG0 > SYSCFG0 page 2
.Reg_uPP > uPP page 2
.Reg_GPIO > GPIO page 2
.Reg_McBSP1 > McBSP1 page 2
.buffer0: fill = 0, align = 8, load = DDR, run = SHRAM
.buffer1 > SHRAM fill 0 align 16
}
// 指示工程中可能用到或者需要用到的内存空间
MEMORY
{
DDR2 o = 0xC0001000 l = 0x08000000 /* 128MB DDR2 分配给 DSP */
}
SECTIONS
{
.text{} > DDR2 align(32768) /* 可执行代码 */
.text:_c_int00 > DDR2 /* 可执行代码 C 程序入口点*/
.stack > DDR2 /* 软件系统栈 */
.cio > DDR2 /* C 输入输出缓存 */
.vectors > DDR2 /* 中断向量表 */
.const > DDR2 /* 常量 */
.data > DDR2 /* 已初始化全局及静态变量 */
.switch > DDR2 /* 跳转表 */
.sysmem > DDR2 /* 动态内存分配区域 */
.args > DDR2
.ppinfo > DDR2
.ppdata > DDR2
/* TI-ABI 或 COFF */
.pinit > DDR2 /* C++ 结构表 */
.cinit load = DDR2 /* 初始化表 */
/* EABI */
.binit > DDR2
.init_array > DDR2
.fardata > DDR2
.rodata > DDR2
.c6xabi.exidx > DDR2
.c6xabi.extab > DDR2
GROUP(NEARDP_DATA)
{
.neardata
.rodata
.bss
} > DDR2
.far > DDR2
/* DDR2 */
.buffer > DDR2
.buffer0: fill = 0, align = 8, load = DDR, run = SHRAM
.buffer1 > DDR2 fill 0 align 16
}
5-3 MAP文件及预编译指令
CMD是为各个段分配存储空间,MAP文件就是显示最终的分配结果以及各个内存区域占用的空间和各个符号。
编译工程:
修改工程配置方式:工程文件夹单击右键,Properties,General,Configuration。
- Release:对Debug添加了调试选项,添加了一些优化选项。
- Debug:编译出来的文件包含调试信息,使用Debug模式编译出来的汇编文件没有优化操作,包含一些路径信息,方便CCS进行Debug调试时方便找到源文件,还包含一些符号声明。
.map文件中包含了一些信息:
- 输出文件名称
- C语言入口地址:"_c_int00"
- 内存配置信息
GPIO_LED.map
******************************************************************************
TMS320C6x Linker PC v7.4.16
******************************************************************************
>> Linked Wed Jan 01 14:47:47 2020
OUTPUT FILE NAME: <GPIO_LED.out>
ENTRY POINT SYMBOL: "_c_int00" address: c0000000
MEMORY CONFIGURATION
name origin length used unused attr fill
---------------------- -------- --------- -------- -------- ---- --------
SYSCFG0 01c14000 00001000 00000000 00001000 RWIX
McBSP1 01d11000 00000800 00000000 00000800 RWIX
uPP 01e16000 00001000 00000000 00001000 RWIX
GPIO 01e26000 00001000 00000000 00001000 RWIX
SHDSPL2ROM 11700000 00100000 00000000 00100000 RWIX
SHDSPL2RAM 11800000 00040000 00000000 00040000 RWIX
SHDSPL1PRAM 11e00000 00008000 00000000 00008000 RWIX
SHDSPL1DRAM 11f00000 00008000 00000000 00008000 RWIX
EMIFACS0 40000000 20000000 00000000 20000000 RWIX
EMIFACS2 60000000 02000000 00000000 02000000 RWIX
EMIFACS3 62000000 02000000 00000000 02000000 RWIX
EMIFACS4 64000000 02000000 00000000 02000000 RWIX
EMIFACS5 66000000 02000000 00000000 02000000 RWIX
SHRAM 80000000 00020000 00000000 00020000 RWIX
EntryPoint c0000000 00000800 00000080 00000780 RWIX
Vector c0000800 00000800 00000000 00000800 RWIX
DDR2 c0001000 08000000 00008204 07ff7dfc RWIX
ARMROM fffd0000 00010000 00000000 00010000 RWIX
ARMRAM ffff0000 00002000 00000000 00002000 RWIX
SEGMENT ALLOCATION MAP
run origin load origin length init length attrs members
---------- ----------- ---------- ----------- ----- -------
c0000000 c0000000 00000080 00000080 r-x
c0000000 c0000000 00000080 00000080 r-x .text:_c_int00
c0001000 c0001000 00006aa0 00006aa0 r-x
c0001000 c0001000 00006aa0 00006aa0 r-x .text
c0007aa0 c0007aa0 00001000 00000000 rw-
c0007aa0 c0007aa0 00000800 00000000 rw- .stack
c00082a0 c00082a0 00000800 00000000 rw- .sysmem
c0008aa0 c0008aa0 0000031c 0000031c rw-
c0008aa0 c0008aa0 0000031c 0000031c rw- .fardata
c0008dc0 c0008dc0 00000148 00000000 rw-
c0008dc0 c0008dc0 00000148 00000000 rw- .far
c0008f08 c0008f08 00000138 00000138 r--
c0008f08 c0008f08 00000138 00000138 r-- .const
c0009040 c0009040 00000120 00000000 rw-
c0009040 c0009040 00000120 00000000 rw- .cio
c0009160 c0009160 000000a8 000000a8 r--
c0009160 c0009160 00000010 00000010 r-- .switch
c0009170 c0009170 00000098 00000098 r-- .cinit
SECTION ALLOCATION MAP
output attributes/
section page origin length input sections
-------- ---- ---------- ---------- ----------------
.init_array
* 0 c0001000 00000000 UNINITIALIZED
.text:_c_int00
* 0 c0000000 00000080
c0000000 00000080 rts6740_elf.lib : boot.obj (.text:_c_int00)
.text 0 c0001000 00006aa0
c0001000 000005c0 rts6740_elf.lib : _printfi.obj (.text:_getarg_diouxp)
c00015c0 000005a0 : divd.obj (.text:__c6xabi_divd)
c0001b60 00000580 drivers.lib : gpio.obj (.text)
c00020e0 00000520 rts6740_elf.lib : _printfi.obj (.text:_setfield)
c0002600 00000460 : _printfi.obj (.text:_printfi)
c0002a60 000003a0 : fputs.obj (.text:fputs)
c0002e00 00000320 : _printfi.obj (.text:_pproc_fge)
c0003120 000002e0 : _printfi.obj (.text:_pproc_fwp)
c0003400 000002a0 : _printfi.obj (.text:ecvt)
c00036a0 000002a0 : _printfi.obj (.text:fcvt)
c0003940 00000280 : memory.obj (.text:free)
c0003bc0 00000260 : imath64.obj (.text:__c6xabi_divull)
c0003e20 00000260 : _printfi.obj (.text:_pconv_e)
c0004080 00000240 : _printfi.obj (.text:_pproc_diouxp)
c00042c0 00000220 : _printfi.obj (.text:_pproc_str)
c00044e0 00000220 : fputc.obj (.text:fputc)
c0004700 00000200 : _printfi.obj (.text:_pconv_g)
c0004900 00000200 : setvbuf.obj (.text:setvbuf)
c0004b00 000001e0 Platform.lib : GPIO.obj (.text)
c0004ce0 000001e0 main.obj (.text)
c0004ec0 000001c0 rts6740_elf.lib : _printfi.obj (.text:_mcpy)
c0005080 000001a0 : imath40.obj (.text:__c6xabi_divul)
c0005220 00000180 : trgdrv.obj (.text:HOSTrename)
c00053a0 00000180 : copy_decompress_rle.obj (.text:__TI_decompress_rle_core)
c0005520 00000180 : memory.obj (.text:malloc)
c00056a0 00000140 : _printfi.obj (.text:_pproc_fflags)
c00057e0 00000140 drivers.lib : psc.obj (.text)
c0005920 00000140 rts6740_elf.lib : lowlev.obj (.text:getdevice)
c0005a60 00000120 : fclose.obj (.text:_closefile)
c0005b80 00000120 : _printfi.obj (.text:_ltostr)
c0005ca0 00000120 : fseek.obj (.text:fseek)
c0005dc0 00000100 : trgdrv.obj (.text:HOSTlseek)
c0005ec0 00000100 : autoinit.obj (.text:_auto_init_elf)
c0005fc0 00000100 : _io_perm.obj (.text:_wrt_ok)
c00060c0 00000100 : cpy_tbl.obj (.text:copy_in)
c00061c0 000000e0 : trgdrv.obj (.text:HOSTopen)
c00062a0 000000e0 : trgdrv.obj (.text:HOSTread)
c0006380 000000e0 : atoi.obj (.text:atoi)
c0006460 000000e0 : lowlev.obj (.text:close)
c0006540 000000e0 : copy_zero_init.obj (.text:decompress:ZI:__TI_zero_init)
c0006620 000000e0 : ltoa.obj (.text:ltoa)
c0006700 000000e0 : memset.obj (.text:memset)
c00067e0 000000e0 : printf.obj (.text:printf)
c00068c0 000000c0 : trgdrv.obj (.text:HOSTunlink)
c0006980 000000c0 : trgdrv.obj (.text:HOSTwrite)
c0006a40 000000c0 : divu.obj (.text:__divu)
c0006b00 000000c0 : _printfi.obj (.text:_div)
c0006bc0 000000c0 : fflush.obj (.text:_doflush)
c0006c80 000000c0 : exit.obj (.text:exit)
c0006d40 000000c0 : tls.obj (.text:tls:init:__TI_tls_init)
c0006e00 000000a0 : trgdrv.obj (.text:HOSTclose)
c0006ea0 000000a0 : fopen.obj (.text:_cleanup)
c0006f40 000000a0 : _printfi.obj (.text:_ecpy)
c0006fe0 000000a0 : _printfi.obj (.text:_fcpy)
c0007080 000000a0 : memory.obj (.text:_minit)
c0007120 000000a0 : _printfi.obj (.text:_pconv_f)
c00071c0 000000a0 : lowlev.obj (.text:finddevice)
c0007260 000000a0 : lowlev.obj (.text:lseek)
c0007300 000000a0 : memcpy64.obj (.text:memcpy)
c00073a0 000000a0 : memory.obj (.text:minsert)
c0007440 000000a0 : memory.obj (.text:mremove)
c00074e0 000000a0 : lowlev.obj (.text:write)
c0007580 00000080 : llshift.obj (.text:__c6xabi_llshl)
c0007600 00000080 : trgmsg.obj (.text:readmsg)
c0007680 00000080 : lowlev.obj (.text:unlink)
c0007700 00000060 : cpp_init.obj (.text:__TI_cpp_init)
c0007760 00000060 : imath64.obj (.text:_subcull)
c00077c0 00000060 : memccpy.obj (.text:memccpy)
c0007820 00000060 : trgmsg.obj (.text:writemsg)
c0007880 00000040 : frcmpyd_div.obj (.text:__c6xabi_frcmpyd_div)
c00078c0 00000040 : isinf.obj (.text:__c6xabi_isinf)
c0007900 00000040 : _printfi.obj (.text:__c6xabi_isnan)
c0007940 00000040 : llshift.obj (.text:__c6xabi_llshru)
c0007980 00000040 : args_main.obj (.text:_args_main)
c00079c0 00000020 : negll.obj (.text:__c6xabi_negll)
c00079e0 00000020 : _lock.obj (.text:_nop)
c0007a00 00000020 : printf.obj (.text:_outc)
c0007a20 00000020 : printf.obj (.text:_outs)
c0007a40 00000020 : exit.obj (.text:abort)
c0007a60 00000020 : copy_decompress_none.obj (.text:decompress:none:__TI_decompress_none)
c0007a80 00000020 : copy_decompress_rle.obj (.text:decompress:rle24:__TI_decompress_rle24)
.stack 0 c0007aa0 00000800 UNINITIALIZED
c0007aa0 00000008 rts6740_elf.lib : boot.obj (.stack)
c0007aa8 000007f8 --HOLE--
.sysmem 0 c00082a0 00000800 UNINITIALIZED
c00082a0 00000008 rts6740_elf.lib : memory.obj (.sysmem)
c00082a8 000007f8 --HOLE--
.fardata 0 c0008aa0 0000031c
c0008aa0 000001e0 rts6740_elf.lib : defs.obj (.fardata:_ftable)
c0008c80 000000a0 : lowlev.obj (.fardata:_stream)
c0008d20 00000078 : lowlev.obj (.fardata:_device)
c0008d98 0000000c : exit.obj (.fardata)
c0008da4 0000000c : memory.obj (.fardata)
c0008db0 00000008 : _lock.obj (.fardata)
c0008db8 00000004 : defs.obj (.fardata)
.far 0 c0008dc0 00000148 UNINITIALIZED
c0008dc0 00000140 rts6740_elf.lib : defs.obj (.far)
c0008f00 00000008 : trgdrv.obj (.far)
.const 0 c0008f08 00000138
c0008f08 00000101 rts6740_elf.lib : ctype.obj (.const:.string:_ctypes_)
c0009009 00000023 : _printfi.obj (.const:.string)
c000902c 00000014 main.obj (.const:.string)
.cio 0 c0009040 00000120 UNINITIALIZED
c0009040 00000120 rts6740_elf.lib : trgmsg.obj (.cio)
.switch 0 c0009160 00000010
c0009160 00000010 drivers.lib : gpio.obj (.switch:GPIOIntTypeSet)
.cinit 0 c0009170 00000098
c0009170 00000072 (.cinit..fardata.load) [load image, compression = rle]
c00091e2 00000002 --HOLE-- [fill = 0]
c00091e4 0000000c (__TI_handler_table)
c00091f0 00000008 (.cinit..far.load) [load image, compression = zero_init]
c00091f8 00000010 (__TI_cinit_table)
LINKER GENERATED COPY TABLES
__TI_cinit_table @ c00091f8 records: 2, size/record: 8, table size: 16
.fardata: load addr=c0009170, load size=00000072 bytes, run addr=c0008aa0, run size=0000031c bytes, compression=rle
.far: load addr=c00091f0, load size=00000008 bytes, run addr=c0008dc0, run size=00000148 bytes, compression=zero_init
LINKER GENERATED HANDLER TABLE
__TI_handler_table @ c00091e4 records: 3, size/record: 4, table size: 12
index: 0, handler: __TI_zero_init
index: 1, handler: __TI_decompress_rle24
index: 2, handler: __TI_decompress_none
GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name
address name
-------- ----
c0007a40 C$$EXIT
c0007878 C$$IO$$
c0004e80 Delay
c0004b00 GPIOBank0Pin0PinMuxSetup
c0004b38 GPIOBank0Pin1PinMuxSetup
c0004b74 GPIOBank0Pin2PinMuxSetup
c0004bb0 GPIOBank0Pin5PinMuxSetup
c0004bec GPIOBank0Pin6PinMuxSetup
c0004c64 GPIOBank6Pin12PinMuxSetup
c0004ca0 GPIOBank6Pin13PinMuxSetup
c0004c28 GPIOBank6Pin1PinMuxSetup
c0002004 GPIOBankIntDisable
c0001fd4 GPIOBankIntEnable
c0004e18 GPIOBankPinInit
c0004df8 GPIOBankPinMuxSet
c0002030 GPIOBankPinsWrite
c0001bf8 GPIODirModeGet
c0001b60 GPIODirModeSet
c0001ea4 GPIOIntTypeGet
c0001d38 GPIOIntTypeSet
c0001f8c GPIOPinIntClear
c0001f2c GPIOPinIntStatus
c0001cd8 GPIOPinRead
c0001c58 GPIOPinWrite
c0006e00 HOSTclose
c0005dc0 HOSTlseek
c00061c0 HOSTopen
c00062a0 HOSTread
c0005220 HOSTrename
c00068c0 HOSTunlink
c0006980 HOSTwrite
c0004de0 PSCInit
c00057e0 PSCModuleControl
c0009040 __CIOBUF_
c00091f8 __TI_CINIT_Base
c0009208 __TI_CINIT_Limit
c00091e4 __TI_Handler_Table_Base
c00091f0 __TI_Handler_Table_Limit
UNDEFED __TI_INITARRAY_Base
UNDEFED __TI_INITARRAY_Limit
c00082a0 __TI_STACK_END
00000800 __TI_STACK_SIZE
00000000 __TI_STATIC_BASE
00000800 __TI_SYSMEM_SIZE
UNDEFED __TI_TLS_INIT_Base
UNDEFED __TI_TLS_INIT_Limit
00000001 __TI_args_main
c0007700 __TI_cpp_init
c0007a60 __TI_decompress_none
c0007a80 __TI_decompress_rle24
c0008da0 __TI_enable_exit_profile_output
ffffffff __TI_pprof_out_hndl
ffffffff __TI_prof_data_size
ffffffff __TI_prof_data_start
c0006d40 __TI_tls_init
c0006540 __TI_zero_init
ffffffff __binit__
c00015c0 __c6xabi_divd
c0006a40 __c6xabi_divu
c0005080 __c6xabi_divul
c0003bc0 __c6xabi_divull
c0007880 __c6xabi_frcmpyd_div
c00078c0 __c6xabi_isinf
c0007580 __c6xabi_llshl
c0007940 __c6xabi_llshru
c00079c0 __c6xabi_negll
ffffffff __c_args__
c0006a40 __divu
c0007980 _args_main
c0005ec0 _auto_init_elf
c0000000 _c_int00
c0006ea0 _cleanup
c0008d98 _cleanup_ptr
c0005a60 _closefile
c0008f08 _ctypes_
c0006bc0 _doflush
c0008d9c _dtors_ptr
c0008db8 _ft_end
c0008aa0 _ftable
c0008db0 _lock
c0007080 _minit
c00079e0 _nop
c0002600 _printfi
c0007aa0 _stack
c0007760 _subcull
c00082a0 _sys_memory
c0008dc0 _tmpnams
c0008db4 _unlock
c0005fc0 _wrt_ok
c0007a40 abort
c0006380 atoi
ffffffff binit
c0006460 close
c00060c0 copy_in
c0006c80 exit
c00044e0 fputc
c0002a60 fputs
c0003940 free
c0005ca0 fseek
c0007260 lseek
c0006620 ltoa
c0004ce0 main
c0005520 malloc
c00077c0 memccpy
c0007300 memcpy
c0006700 memset
c00067e0 printf
c0007600 readmsg
c0007680 remove
c0004900 setvbuf
c0007680 unlink
c00074e0 write
c0007820 writemsg
GLOBAL SYMBOLS: SORTED BY Symbol Address
address name
-------- ----
00000000 __TI_STATIC_BASE
00000001 __TI_args_main
00000800 __TI_STACK_SIZE
00000800 __TI_SYSMEM_SIZE
c0000000 _c_int00
c00015c0 __c6xabi_divd
c0001b60 GPIODirModeSet
c0001bf8 GPIODirModeGet
c0001c58 GPIOPinWrite
c0001cd8 GPIOPinRead
c0001d38 GPIOIntTypeSet
c0001ea4 GPIOIntTypeGet
c0001f2c GPIOPinIntStatus
c0001f8c GPIOPinIntClear
c0001fd4 GPIOBankIntEnable
c0002004 GPIOBankIntDisable
c0002030 GPIOBankPinsWrite
c0002600 _printfi
c0002a60 fputs
c0003940 free
c0003bc0 __c6xabi_divull
c00044e0 fputc
c0004900 setvbuf
c0004b00 GPIOBank0Pin0PinMuxSetup
c0004b38 GPIOBank0Pin1PinMuxSetup
c0004b74 GPIOBank0Pin2PinMuxSetup
c0004bb0 GPIOBank0Pin5PinMuxSetup
c0004bec GPIOBank0Pin6PinMuxSetup
c0004c28 GPIOBank6Pin1PinMuxSetup
c0004c64 GPIOBank6Pin12PinMuxSetup
c0004ca0 GPIOBank6Pin13PinMuxSetup
c0004ce0 main
c0004de0 PSCInit
c0004df8 GPIOBankPinMuxSet
c0004e18 GPIOBankPinInit
c0004e80 Delay
c0005080 __c6xabi_divul
c0005220 HOSTrename
c0005520 malloc
c00057e0 PSCModuleControl
c0005a60 _closefile
c0005ca0 fseek
c0005dc0 HOSTlseek
c0005ec0 _auto_init_elf
c0005fc0 _wrt_ok
c00060c0 copy_in
c00061c0 HOSTopen
c00062a0 HOSTread
c0006380 atoi
c0006460 close
c0006540 __TI_zero_init
c0006620 ltoa
c0006700 memset
c00067e0 printf
c00068c0 HOSTunlink
c0006980 HOSTwrite
c0006a40 __c6xabi_divu
c0006a40 __divu
c0006bc0 _doflush
c0006c80 exit
c0006d40 __TI_tls_init
c0006e00 HOSTclose
c0006ea0 _cleanup
c0007080 _minit
c0007260 lseek
c0007300 memcpy
c00074e0 write
c0007580 __c6xabi_llshl
c0007600 readmsg
c0007680 remove
c0007680 unlink
c0007700 __TI_cpp_init
c0007760 _subcull
c00077c0 memccpy
c0007820 writemsg
c0007878 C$$IO$$
c0007880 __c6xabi_frcmpyd_div
c00078c0 __c6xabi_isinf
c0007940 __c6xabi_llshru
c0007980 _args_main
c00079c0 __c6xabi_negll
c00079e0 _nop
c0007a40 C$$EXIT
c0007a40 abort
c0007a60 __TI_decompress_none
c0007a80 __TI_decompress_rle24
c0007aa0 _stack
c00082a0 __TI_STACK_END
c00082a0 _sys_memory
c0008aa0 _ftable
c0008d98 _cleanup_ptr
c0008d9c _dtors_ptr
c0008da0 __TI_enable_exit_profile_output
c0008db0 _lock
c0008db4 _unlock
c0008db8 _ft_end
c0008dc0 _tmpnams
c0008f08 _ctypes_
c0009040 __CIOBUF_
c00091e4 __TI_Handler_Table_Base
c00091f0 __TI_Handler_Table_Limit
c00091f8 __TI_CINIT_Base
c0009208 __TI_CINIT_Limit
ffffffff __TI_pprof_out_hndl
ffffffff __TI_prof_data_size
ffffffff __TI_prof_data_start
ffffffff __binit__
ffffffff __c_args__
ffffffff binit
UNDEFED __TI_INITARRAY_Base
UNDEFED __TI_INITARRAY_Limit
UNDEFED __TI_TLS_INIT_Base
UNDEFED __TI_TLS_INIT_Limit
[113 symbols]
预编译指令:#define
,#include
,.h中包含函数声明,.c中包含函数本体,#include包含.h文件
- #include <>:c语言标准库文件,编译器优先从系统目录寻找;
- #include “”:编译器优先从当前目录寻找,然后在到系统目录寻找;
#pragma
可以通过.cmd文件为整个段分配存储空间,可是有时我们不需要把整段的内容放在一个空间里,只需要把一个或几个变量放在读写比较快的内存中,就需要使用预编译指令进行#pragma。
- CODE_SECTION:为代码来指定存储空间
- DATA_SECTION:为数据来指定存储空间
- SET_CODE_SECTION:为代码来指定存储空间,可以为一部分代码指定存储空间
- SET_DATA_SECTION:为数据来指定存储空间可以为一部分数据指定存储空间
- DATA_ALIGN:
在.cmd文件中划分出一段空间(删除了大部分代码,为了清晰)
MEMORY
{
DDR2 o = 0xC0800000 l = 0x07800000 /* 128MB DDR2 分配给 DSP */
Data o = 0xC0000000 l = 0x00800000 /* 自定义内存区域*/
}
SECTIONS
{
.text{} > DDR2 align(32768) /* 可执行代码 */
.text:_c_int00 > SHDSPL2RAM /* 可执行代码 C 程序入口点*/
.stack > DDR2 /* 软件系统栈 */
.cio > DDR2 /* C 输入输出缓存 */
.vectors > Vector /* 中断向量表 */
.const > DDR2 /* 常量 */
.data > DDR2 /* 已初始化全局及静态变量 */
.switch > DDR2 /* 跳转表 */
.sysmem > DDR2 /* 动态内存分配区域 */
/* TI-ABI 或 COFF */
.pinit > DDR2 /* C++ 结构表 */
.cinit load = DDR2 /* 初始化表 */
/* EABI */
.binit > DDR2
.init_array > DDR2
.fardata > DDR2
.rodata > DDR2
.c6xabi.exidx > DDR2
.c6xabi.extab > DDR2
GROUP(NEARDP_DATA)
{
.neardata
.rodata
.bss
} > DDR2
.far > DDR2
.Buf > Data /* 自定义代码段 */
.DataSH > SHRAM /* 自定义数据段 */
}
CCS工程
main.c
```c
// 为代码指定存储空间
#pragma CODE_SECTION(fun, ".Buf")
int fun(void)
{
return 0;
}
//#pragma DATA_ALIGN(i, 4)
#pragma DATA_ALIGN(i, 64)
//#pragma DATA_SECTION(i, ".DataSH") // 注意:代码段和数据段不能放在一个空间中,编译器会报错
unsigned int i;
#pragma SET_DATA_SECTION(".DataSH")
unsigned int j;
unsigned char k;
#pragma SET_DATA_SECTION()
int main(void)
{
*(volatile unsigned int *)(0x01C14124) = 0x88800800;
*(volatile unsigned int *)(0x01E26000 + 0x10) &= 0xFFFFFFD8;
*(volatile unsigned int *)(0x01E26000 + 0x14) |= 0x00000027;
fun(); // 如果main函数不调用子函数fun,编译器不会为其分配存储空间
i = 0; // 需要在代码用使用一下i这个变量,否则编译器不会为其分配存储空间
return 0;
}