实验二:编写一个以C语言为基础的DSP程序
一、实验目的
1.学习C语言编制程序:了解C语言程序设计方法和组成部分。 2.学习编制连接命令文件,用来控制代码的连接。
3.学会建立和改变map文件,以及利用它观察DSP内存使用情况。 4.进一步熟悉CCS调试程序。 二、实验设备
1.PC机一台:操作系统为Windows2000或WindowsXP。 2.ICETEK-F2812-EDU实验箱一台。 三、实验原理 1.C语言程序
(1)CCS支持使用标准C语言应用程序。当使用标准C 语言编制的程序时,其源程序文件名的后缀应为.c(如:volume.c)。
(2)CCS 在编译标准C 语言程序时,首先将其编译成相应汇编语言程序,再进一步编译成目标DSP 的可执行代码。最后生成的是coff 格式的可下载到DSP 中运行的文件,其文件名后缀为.out。 2.命令文件的作用
命令文件(文件名后缀为cmd)为链接程序提供程序和数据在具体DSP 硬件中的位置分配信息。通过编制命令文件,我们可以将某些特定的数据或程序按照我们的意图放置在DSP 所管理的内存中。命令文件也为链接程序提供了DSP 外扩存储器的描述。在程序中使用CMD 文件描述硬件存储区,可以只说明使用部分,但只要是说明的,必须和硬件匹配,也就是只要说明的存储区必须是存在的和可用的。
3.内存映射(map)文件的作用
一般地,开发的DSP 程序在调试好后,要固化到系统的ROM 中。为了更精确地使用ROM空间,我们就需要知道程序的大小和位置,通过建立目标程序的map 文件可以了解DSP 代码的确切信息。当需要更改程序和数据的大小和位置时,就要适当修改cmd 文件和源程序,再重新生成map 文件来观察结果。另外,通过观察map 文件,可以掌握DSP 存储器的使用和利用情况,以便进行存储器方面的优化工作。 四、实验步骤
1.实验准备:设置软件仿真模式。
2.建立工程文件:新建工程文件设置如图2.1。
图2.1 建立CProgram.pjt
3.编辑输入源程序 (1)编辑C语言程序
? 新建源程序窗口
? 在源程序窗口输入源程序:
int x,y,z; main() {
x=1; y=2; while ( 1 ) z=x+y;
}
? 保存源程序为CProgram.c
(2)编辑连接命令文件
? 建立空源程序窗口 ? 输入连接命令文件内容:
-l rts2800.lib -stack 400h -heap 100 MEMORY {
PAGE 0 : PROG(R) : origin = 0x3E8000, length = 0x10000 PAGE 0 : BOOT(R) : origin = 0x3FF000, length = 0xFC0 PAGE 0 : RESET(R) : origin = 0x3FFFC0, length = 0x2
{ }
PAGE 0 : VECTORS(R) : origin = 0x3FFFC2, length = 0x3E
PAGE 1 : M0RAM(RW) : origin = 0x000000, length = 0x400 PAGE 1 : M1RAM(RW) : origin = 0x000400, length = 0x400 PAGE 1 : L0L1RAM(RW) : origin = 0x008000, length = 0x2000 PAGE 1 : H0RAM(RW) : origin = 0x3F8000, length = 0x2000
}
SECTIONS {
/* 22-bit program sections */ .reset : > RESET, PAGE = 0 vectors : > VECTORS, PAGE = 0 .pinit : > PROG, PAGE = 0
.cinit : > PROG, PAGE = 0 .text : > PROG, PAGE = 0
/* 16-Bit data sections */
.const : > L0L1RAM, PAGE = 1 .bss : > L0L1RAM, PAGE = 1 .stack : > M1RAM, PAGE = 1
.sysmem : > M0RAM, PAGE = 1
/* 32-bit data sections */ .ebss : > H0RAM, PAGE = 1 .econst : > H0RAM, PAGE = 1
.esysmem : > H0RAM, PAGE = 1
}
? 将连接命令文件保存为CProgram.cmd
4.编译源文件、下载可执行程序
(1)编译源程序:单击菜单“Project”的“Rebuild All”项,或单击工具条中的编译按钮。
(2)下载可执行程序:执行File/Load Program ,在随后打开的对话框中选择刚刚建立的D: \\CProgram \\Debug\\ CProgram.out 文件。完成后,系统自动打开一个反汇编窗口“Disassembly”,并在其中指示程序的入口地址为“_c_int00”。
5.打开观察窗口,观察程序运行结果
开启CPU 寄存器观察窗口:单击菜单View->Registers->CPU Registers。这时,在“Disassembly”代表程序运行位置的绿色箭头指向程序的入口地址,程序将 从此开始执行。
(1) 选择菜单中Debug->Go Main,CCS 自动打开CProgram.c,程序会停在用户主程序入口main 上,这从反汇编窗口和CProgram.c 窗口中的指示箭头位置可以看出。
(2)在内存观察窗口中观察变量的值:选择“View”菜单中“Memory…”项,在“Memroy Window Options”窗口中的“Adress”项中输入&x,按“Enter”按钮完成设置;“Memory”窗口中x 的当前取值显示在第1 个地址的后。
(3)将变量x、y、z 分别加入观察窗口:在源程序中双击变量名,再单击鼠标右键,选择“Add to Watch Window”。这时,这3个变量还未作初始化。
(4)单步运行,在观察窗中观察到变量x、y 被赋值。变化的值被显示成红色。同时在“Memory”窗口中也能观察到x 和y 值的改变。
(5)再单步运行,可观察到z 的值被计算出来。双击观察窗口中变量x、y 在“Value”栏中的取值并修改成其他取值,单步运行后观察结果。
(6)双击观察窗口中变量x、y 在“Value”栏中的取值,并修改成0;选择菜单Debug->Restart,返回程序起点。
(7)重新单步运行程序,观察在CPU 寄存器窗口中,各寄存器使用情况,观察哪个寄存器参与了运算。 6.内存映像文件
(1)选择菜单“Project”的“Build Option…”,启动“Build Option”工程设置对话框。
(2)单击“Linker”属性页,在“Map Filename”项中观察生成的map 文件名和路径。
(3)单击“取消”退出。
7.对照观察map 文件和cmd 文件的内容
(1)选择菜单File->Open…,将找到D:\\ CProgram \\Debug目录,将文件类型改为“Memory Map Files”,选择CProgram.map 文件、打开。
(2)打开CProgram.cmd 文件。
(3)程序的入口地址:map 文件中“ENTRY POINT SYMBOL”中说明了程序入口地址(_c_int00)。
(4)内存使用情况:map 文件中“MEMORY CONFIGURATION”标明了程序占用RAM 的使用情况;观察map 文件中的“SECTION ALLOCATION MAP”段,可以看出CProgram.obj 的入口地址为0x3e801e,这也是main 函数的
入口地址;用户堆栈段从400H 开始,程序运行到main 函数中后,变量x、y、z 均开设在栈中;还能看出程序运行都需要调用rts2800.lib 中的哪些模块。 8.改变内存分配 修改cmd 文件中的
PAGE 0 : PROG(R) : origin = 0x3E8000, length = 0x10000 改为
PAGE 0 : PROG(R) : origin = 0x3E9000, length = 0x10000 重新编译工程,观察map文件中有何变化。 9.退出CCS 。 五、实验结果
通过实验可以发现,修改cmd 文件可以安排程序和数据在DSP 内存资源中的分配和位置;map 文件中描述了程序和数据所占用的实际尺寸和地址。
C 语言编制的程序,在经过编译器编译后,需要连接若干C 标准程序辅助运行。以下是运行流程:
1.程序入口为_c_int00,执行标准C 库中的程序,负责初始化C 环境、申请堆栈、初始化有初始值的变量等。
2.程序最终转到用户编制的主函数运行。 3.程序在主函数中的无限循环中持续运行 六、问题与思考
修改程序完成计算sin(2.3π)+cos(1.7π)的值。