admin 管理员组文章数量: 1086019
2024年3月26日发(作者:violates)
PhoenixTreeSky
Code Composer Studio 教 程
Edited by
PhoenixTree
School of Automation
Beijing Institute of Technology
2014.09.09
0
PhoenixTreeSky
CONTENTS
Code Composer Studio 教程(一)
——
开发一个简单的程序
...................................... 4
步骤1:创建一个新项目 ............................................................................................ 4
步骤2:在项目中加载源文件 ..................................................................................... 4
步骤3:浏览源代码 .................................................................................................... 4
步骤4:建立并运行程序 ............................................................................................ 4
步骤5:改变程序设置并修改语法错误 ...................................................................... 4
步骤6:使用断点和观察窗口 ..................................................................................... 5
步骤7:用Watch window观察指令 ........................................................................... 6
步骤8:代码执行时间的性能分析.............................................................................. 6
Code Composer Studio 教程(二)
——
开发一个
DSP/BIOS
程序
................................. 8
步骤1:创建一个配置文件......................................................................................... 8
步骤2:加载DSP/BIOS文件到项目中......................................................................... 9
步骤3:用CCS来进行测试....................................................................................... 10
步骤4:DSP/BIOS代码执行时间的性能分析............................................................. 10
步骤5:试一试 ......................................................................................................... 11
步骤6:释放性能分析所占用的资源: .................................................................... 12
Code Composer Studio 教程(三)
——
从文件中测试算法和数据
............................. 13
1
PhoenixTreeSky
步骤1:打开并检测项目 .......................................................................................... 13
步骤2:观察源代码 .................................................................................................. 13
步骤3:为文件I/O加一探针点(probe point) ....................................................... 14
步骤4:图表显示 ..................................................................................................... 15
步骤5:启动程序和图表 .......................................................................................... 15
步骤6:调整gain参数 ............................................................................................. 16
步骤7:观察out-of-scope变量................................................................................. 17
步骤8:使用一GEL文件 .......................................................................................... 17
步骤9:调整并分析processingLoad(负载处理) .................................................... 18
Code Composer Studio 教程(四)
——
调试程序性能
............................................... 20
步骤1:打开并检查项目 .......................................................................................... 20
步骤2:观察源代码 .................................................................................................. 20
步骤3:修改配置文件 .............................................................................................. 21
步骤4:用thread execution(线性执行)来观察运行图表 ...................................... 22
步骤5:改变并观察加载程序 ................................................................................... 23
步骤6:分析调度表 .................................................................................................. 24
步骤7:加入外部STS装置 ....................................................................................... 25
Code Composer Studio 教程(五)
——
实时性能分析
............................................... 28
步骤1:打开并检查项目 .......................................................................................... 28
2
PhoenixTreeSky
步骤2:修改配置文件 .............................................................................................. 28
步骤3:观察源代码的改变....................................................................................... 29
步骤4:在运行时用RTDX控制来改变 30
步骤5:修改软中断优先权....................................................................................... 31
Code Composer Studio 教程(六)
——
与
I/O
设备的连接
........................................ 34
步骤1:打开并检查项目文件 ................................................................................... 34
步骤2:观察C源代码 .............................................................................................. 34
步骤3:回顾signalprog应用程序 ............................................................................. 35
步骤4:运行应用程序 .............................................................................................. 36
步骤5:修改源代码以使用Host Channels and Pipes ................................................. 37
步骤6:更多有关Host Channels and Pipes ................................................................ 38
步骤7:向配置文件中加入通道和一个软中断 ......................................................... 38
步骤8:运行修改后的程序....................................................................................... 39
3
PhoenixTreeSky
Code Composer Studio 教程(一)
—— 开发一个简单的程序
步骤1:创建一个新项目
1) 创建一个工作文件夹,D:hanstudy1。
2) 进入CCS环境中,并编译源文件:
File ——> New ——> Source File ,
编译完毕,分别存为hello.c, ,,hello.h。
3) project ——> New,保存于D:hanstudy1目录下,项目名称为
。
步骤2:在项目中加载源文件
1) project ——> Add File to project ,分别选择hello.c 、 、
和TiC6000cgtoolslib目录下的 。
步骤3:浏览源代码
1) 双击,打开hello.c,浏览源代码。
步骤4:建立并运行程序
1) project ——> Rebuild All 。在此项目中CCS编译、汇编,并链接所有
文件。生成、和文件。
2) File ——> Load Program,选择 。这样CCS将此程序加载
入目标板DSP中,并同时打开此程序的反汇编文件。
3) Debug ——> Run ,运行程序,输出结果hello world 。
步骤5:改变程序设置并修改语法错误
在以上步骤中,处理器指令#ifdef 和#endif没有运行,因为FILEIO没有定义。
在此,设置CCS处理器设置选择,以运行之,并找出、更正其中的错误。
4
PhoenixTreeSky
1) project ——> Options 。
2) 在Category列表中点击preprocessor,并在Define symbol框中输入
FILEIO。
3) OK,保存新的选项控制设置。
4) Project ——> rebuild All 。
注意:无论何时,项目选项(project options)发生改变,都必须重新建立
(rebuild All)所有文件。
5) 提示:有错误,是否继续链接?取消,改正错误并保存。
6) project ——> Build 。
注意:CCS将重新建立(Buill)更改过数据的文件。
步骤6:使用断点和观察窗口
当你正在开发和测试程序时,经常需要检查程序执行期间的变化值。在此,
使用断点和观察窗口来观察这些值。在到达断点后,也可以使用单步执行命令。
1) File ——> Reload Program 。
2) 双击hello.c。
3) 将光标放置在fprintf(fptr,“%s”,scanStr);行上。
4) 点击“手形图案”(Toggle Breakpoint)或F9。此行此时呈高亮色(紫
色亮条)。
5) View ——> Watch window 。
6) 在Watch window窗口中右击,选择Insert New Expression。
7) 在消息框中输入*scanStr,OK。
8) 此时在Watch window窗口中*scanStr 为尚未定义。因为,当前程序还
未在main()函数的局域变化处运行。
9) Debug ——> Run 或F5。
10) 在提示框中输入goodbye,OK。此时,在Watch window中,为
*scanStr=goodbye。而程序运行并停止在断点处(黄色亮条),并在结果窗口中显
示goodbye。
11) 点击step over 图标或F10来单步调用fpritf()。
12) step into(F8)、step over(F10)、step out(F7)、Run to Cursor(Ctrl F10)。
13) 点击运行(Run)或F5,完成程序的运行。
5
PhoenixTreeSky
步骤7:用Watch window观察指令
1) 在Watch window窗口中右击,选择Insert New Expression项。
2) 在提示框中输入str,OK。则在Watch window中出现+str={…}。“+”表
示此乃一指令,此指令为PARMS类型,并在hello.c中有所描述。此指令类型在
hello.h中定义。
3) 点击“+”,则出现所有元素:
-str={…}
Beta=2934
EchoPower=9432
ErrorPower=213
Ratio=9432
+Link=0x80000174
4) 双击其中任意一个元素行,则打开一个元素编辑窗口,改变元素值,
则Watch window中值亦随之改变。
5) 注意:操作完毕,必须从Watch window中移走指令str,并关闭Watch
window,撤去断点。
步骤8:代码执行时间的性能分析
在此,使用CCS的描述特性来获得有关标准puts()函数的运行统计,并使之
与使用DSP/BIOS API来显示hello world信息相比较。
1) File ——> Reload Program。
2) Profiler ——> Enable clock。此时钟计数指令周期,其必须对profiler-
points使能来计数指令周期。
3) 打开hello.c。
4) View ——> Mixed Source/ASM。在C源代码下出现此指令的汇编指令。
5) 将光标置于指令行puts(“hello world!n”); ,并点击时钟符号(Toggle
Profiler-point),则此行C代码与其下第一行汇编指令变为绿色亮条,其下一条指
令亦如此。
6) Profiler ——> View Statistics。在右下角出现一显示框,以显示对测试
点(profiler-point)的统计。
7) 点击运行符号或F5,运行程序,在弹出的提示框中输入字符串“goodbye”,
6
PhoenixTreeSky
OK。
8) 观察小窗口中数字的变化:注意第二个profiler-point的周期数,其周
期数应在1600-1700间,此乃运行puts()所需要的周期数。
7
PhoenixTreeSky
Code Composer Studio 教程(二)
—— 开发一个DSP/BIOS程序
在此教程中,通过使用DSP/BIOS来优化hello程序。此教程需要一个目标板,
而且不可以用一软件模拟器来实现。同时,此教程需要CCS的DSP/BIOS部分。
步骤1:创建一个配置文件
另一种实现hello程序的方法是使用配有DSP/BIOS API的LOG模块(API—
—应用程序接口)。你可以在加载入的程序中使用DSP/BIOS来提供基本的运行时
间服务。API模块使实时DSPs进行最优化。不同于C库调用如puts(),DSP/BIOS
在不暂停目标硬件的情况下进行实时分析。另外,API代码占用更小的空间,同
时比C标准的I/O运行更快。一个程序可使用一个或更多的DSP/BIOS模块。
在此,修改hello 文件以使用DSP/BIOS API。为应用DSP/BIOS API,一个程序
必须拥有一个程序所使用的定义了DSP/BIOS对象的配置文件。
1) 打开项目。(在D:hanstudy2目录下)
2) File ——> New ——> DSP/BIOS Config。
3) 选择对DSP板的类型,确定。此时弹出一界面窗口。
4) 右击LOG-Event Log Manager,并选择Insert LOG,这样建立一个名为
LOG0的LOG对象。
5) 右击LOG0,选择Rename,改名为“trace”。
6) File ——> Save。保存于工作目录下,配置文件名为。保
存此配置直接产生以下文件:
① :保存配置的设置。
② :连接器命令文件。
③ myhellocfg.s62:汇编语言源文件。
④ myhellocfg.h62:包含在myhellocfg.s62中的汇编语言头文件。
尽管这些文件拥有.s62和.h62 的扩展名,它们也可应用在TMS320C6701中。
DSP/BIOS不需要使用TMS320C6701支持的浮点指令,因此支持二者DSPs只需一
种版本的软件。
8
PhoenixTreeSky
步骤2:加载DSP/BIOS文件到项目中
在此,加载上面生成的新文件于工作目录中,并移走它们替代的文件。
1) Project ——> Add Files to Project 。选择。这样在项目下
DSP/BIOS Config中加入了。此外,CCS自动地在项目下源文件夹中加
入myhellocfg.s62文件。
2) 输出文件的文件名必须与.cdb 文件名相匹配(和
)。选择Project ——> Options,点击Linker标签,在output文件框
中,确认为文件名。
3) project ——> Add File to project。选择文件,确定。此
时,出现一警告板,单击“Yes ”。这样,在保存配置文件是生成的新的.cmd 文
件代替旧的文件()。
4) 在项目目录树中,右击源文件,选择Rename from project,
从项目中移走此文件。硬件中断向量会被DSP/BIOS配置文件自动定义。
5) 同样移走文件。此库文件自动包含于文件
中。
6) 双击打开hello.c文件,选择View ——> Mixed Source/Asm来隐藏其
汇编代码。
7) 改变源文件的内容,替换主函数,因为puts()与LOG_printf使用相同的
资源。
注意:此代码的下列部分:
① 此代码包括std.h和log.h头文件。所有使用DSP/BIOS API的程序必须包
含std,h文件,而且头文件适合于任何程序所使用的模块。log.h头文件定义
LOG_Obj结构,,并且声明API在LOG模块中的运行。Std.h文件必须优先包含。
而包含的拥有模块顺序并不重要。
② 此代码亦声明在配置文件中生成的LOG对象。
③ 在主函数中,此例调用LOG_printf并忽略LOG对象(&trace)和hello
world信息的地址。
④ 最后主函数返回,而导致程序进入DSP/BIOS空循环。在此循环中,
DSP/BIOS等待软中断和硬中断的出现。
8) 保存文件。Project ——> option。在Compiler标签下,Category框中
选择Preprocessor,移走右边Define symbols框中的FILEIO。
9) Project ——> Rebuild All 。
9
PhoenixTreeSky
步骤3:用CCS来进行测试
由于程序只写了一行到一个LOG,在此无须进行分析。
1) File ——> Load program,选择刚刚重建的文件,确定。
2) Debug ——> go main。
3) Tools ——> DSP/BIOS ——> Message Log。此时在CCS窗口底部出现
一消息区域。
4) 在此消息区域上右击,选择Property Page 。
5) 选择trace作为监测记录(the log to monitor)的名字,确定。默认更
新率为1次/秒。(改变更新率,Tools ——> DSP/BIOS ——> RTA。在RTA控制面
板上右击并选择Property Page。选择一个新的更新率,确定。)
6) Debug ——> Run或F5。则hello world显示在消息记录区域。
7) Debug ——> Halt或shift F5停止程序的执行。在主函数返回之后,程
序处于DSP/BIOS空循环状态,直至出现一个事件。
8) 关闭Message Log窗口。(这是必需的一步)
9) Tools ——> RTDX。打开RTDX控制窗口。选择RTDX Disable,在下拉
列表中,在RTDX区域上右击,选择Hide。
注意:profiling与RTDX在一些目标板上不能同时应用。
DSP/BIOS插件程序(plug-ins)使用RTDX来进行主机/目标间的通信。在一
些DSP目标板上(例如,TMS320C6201),不能同时使用profiling和RTDX。关闭
所有使用RTDX的工具,在使用profiling之前,例如Message Log和其它DSP/BIOS
plug-ins。为确保取消RTDX,特别是在使用DSP/BIOS plug-ins之后,选择Tools —
—> RTDX来打开RTDX plug-in。选择RTDX Disable在下拉列表中,右击,选择Hide。
相反地,在使用profiling之后,使用RTDX之前释放protiler资源,如同教程
1步骤8末尾所描述的那样。如尝试同时使用RTDX和profiling,则会出现一个错
误信息。
步骤4:DSP/BIOS代码执行时间的性能分析
以前,使用CCS性能分析特性得到周期数需要调用puts()。现在,通过调用
LOG_printg来完成相同的工作。
1) File ——> Reload program。
2) Profiler ——> Enable Clock。
10
PhoenixTreeSky
3) 打开hello.c文件。
4) View ——> Mixed Source/ASM。
5) 将光标置于LOG_printf(&trace,“hello world!”);行。
6) 点击Toggle profile-point 按钮。
7) 将光标置于程序的最后一行,点击Toggle profile-point按钮。
注意:此最后一行并不是return行,而是大括号“}”行。
8) profiler ——> View statistics。
9) 要使在View statistics窗口中的行数为正序,即行数从上向下,从小变
大。
10) 点击Run或F5,运行程序。
11) 注意指令周期数应为第二个profile-point。其值大约为36,这是执行
调用LOG_printf所必需的周期数。调用LOG_printf是生效的,因为一系列格式化
的执行在主机上要好于在目标DSP上。
12)点击Halt或shift F5,停止程序的运行。
步骤5:试一试
为进一步了解CCS,试一试以下的内容:
① Load ,并设置一断点于LOG_printf行。用Debug ——>
Breakpoints来加入一个断点于IDL_F_Loop。(在位置条输入IDL_F_Loop,单击Add)。
运行程序。在第一个断点,View ——> Cpu registers ——> Cpu register观察
寄存器值列表。注意GIE为0,此表示当主函数(main)正在执行是中断无效。
继续运行程序至下一断点。此时GIE为1,此时中断生效。如果运行程序,
不断访问此断点。在启动过程和主函数完成之后,一个DSP/BIOS进入一空循环。
此循环由IDL模块处理,直到停止程序的运行。此空循环带有中断使能并且可以
通过任何ISR(中断服务程序),或软中断,或事件触发一操纵实时处理应用程序,
在任何点优先取得。
② 在MS-DOS窗口中,以下列命令运行:
cd c:tic6000tutorialhello1
sectti >
cd …hello2
sectti >
当使用stdio.h调用和DSP/BIOS时,比较和二文件以观
11
PhoenixTreeSky
察内存部分和大小的区别。
步骤6:释放性能分析所占用的资源:
1) 在profiler菜单内,取消Enable clock。
2) 关闭profiler统计窗口。
3) 删除所有profiler-profile-points。
4) 取消Mixed Source/ASM。
5) 关闭所有窗口。
6) 关闭项目。
12
PhoenixTreeSky
Code Composer Studio 教程(三)
—— 从文件中测试算法和数据
在此教程中,创建一个执行基本信号处理的程序。在此得使用探点、图形、
动画和GEL文件。
步骤1:打开并检测项目
用CCS打开一个项目并检测源代码和库。
1) 建立一工作文件夹,D:hanstudy3。
2) 在此文件夹中创建一项目,,项目中有,,
volume.c,,volume.h,等文件。
① volume.c:主程序源文件。
② volume.h:包含在volume.c中定义的常量和结构的头文件。
③ :此文件包含载入程序(一个简单的汇编循环程序,可用一条C
指令调用的,其大概消耗1000条指令周期)。
④ :在DSP中断向量表中定义一个复位输入点。
⑤ :此链接命令文件映射内存块。
⑥ :提供目标板的运行支持。
步骤2:观察源代码
注意此例的以下部分:
① 在主函数输出一条信息之后,进入一无限循环。在此循环内,其调用
dataIO和处理函数。
② 此处理函数将input buffer和gain的输入结果值分别相乘,输出到output
buffer。其还调用汇编载入程序,此程序在处理传递程序载入值的基础上占用指
令周期。
③ 此例中的dataIO函数不执行任何动作,除了return之外。除了用C代
码执行I/O外,可以用一探针点来从一个主机上文件读取数据到inp_buffer位置。
13
PhoenixTreeSky
步骤3:为文件I/O加一探针点(probe point)
在此,加入一个探针点,从PC机上的一个文件读取数据。Probe point对于
运算法则的开发是一非常有用的工具。可以在以下几方面使用他们:
① 通过运算法则,传递主机上的文件输入数据到目标的buffer以使用。
② 传递目标buffer上的输出数据到主机一文件中来进行分析。
③ 更新窗口,例如带数据的图表。
Probe point类似于断点,他们都可终止目标的任何动作。然而,probe point
在以下几个方面不同于断点:
① probe point终止目标的瞬间,只执行一单一的动作,并继续执行目标。
② 断点终止CPU,直到手动继续执行并导致所有打开的窗口重新更新。
③ probe point允许自动地执行文件的输入或输出,而断点不可。
此教程显示如何使用probe point来传递PC文件内容到目标上,进行数据测
试。当到达probe point时,其也用一断点来更新所有打开的窗口。这些窗口包
括输入、输出数据的图表。
1) Project ——> Rebuild Add。
2) File ——> Load program。选择。
3) 打开volume.c。
4) 当光标置于主函数中此行:dataIO();
dataIO()函数相当于一占位符,稍后加入其。现在,其在方便位置连接一从PC
文件注入数据的probe point。
5) 点击“眼睛”图标(Toggle probe point),则此行变蓝。
6) File ——> File I/O。此File I/O对话显示可以选择输入、输出文件。
7) 在input tab,单击Add。
8) 选择文件。
注意:可以在文件类型框中选择数据格式(其中有十六进制、整数、浮点等
格式),文件对于一正弦波包含十六进制值(Hex)。
9) 此时,一文件控制窗口出现。随后,当运行程序时,可以用此
窗口来启动、停止、重绕或者在数据文件内快速传递。
10) 在File I/O对话框,改变地址为inp_buffer,长度为100,并选中Wrap
Around。
① 地址域说明从文件来的数据将要放置的地方。Inp_buffer作为BUFSIZE
整数数组在volume.c中定义。
14
PhoenixTreeSky
② 长度域说明每次探点(probe point)到达时有多少从数据文件来的采样
可以读取。使用100是因为它是在volume.h中设置的BUFSIZE常量值。(0x64)
③ 当到达文件末端时,Wrap Around选项启动CCS从文件开始处进行读取。
这样可将数据文件看作一连续的数据流,尽管它仅包含1000值,而且每次探点
到达读取100值。
11) 点击Add probepoint。出现一probe point对话框。
12) 点击probe point列表中的语句,其变为兰色。此时显示无连接。
13) 在connect条框中,在下拉菜单中选择文件。
14) 单击Replace。此时在probe point框中显示probe point已连接到
文件。
15) 确定。
16) 在File I/O对话框中,确定。
步骤4:图表显示
如果现在就运行程序,那么将看不到有关程序运行的相关信息。可以在
inp_buffer和out_buffer地址列上设置观察变量,但是需要观察大量变量,而且
是数字式显示。
CCS提供了多种方法给程序处理的数据图表。此例,将看到一快速信号图。
此步骤中,将打开图表,下一步进行程序。
1) View ——> Graph ——> Time/Frequency
2) 在图表属性对话框,改变图表标题、启始地址、获取缓冲器大小、显
示数据大小、Autoscale(自动测量)和最大Y值等属性。
3) 确定,一个Input buffer的图表出现。
4) 在Input buffer窗口中右击,并选择clear display。
5) View ——> Graph ——> Time/Frequency。
6) 此次,改变Graph Title为Output Buffer,start Address为out_buffer。
其它不变。
7) 确定,在图表窗口中右击,选择clear display。
步骤5:启动程序和图表
到目前为止,已经防止一探点(probe point),它暂时停止目标,从主机传输
15
PhoenixTreeSky
数据到目标,并重新执行目标应用程序。然而,探点不能导致图表的更新。在此,
设置一断点来促使图表的更新,并在到达断点后用Animate命令重新自动执行。
1) 在volume.c窗口中,放置光标在dataIO行。
2) 点击“手”形触发断点钮(Toggle breakpoint)或F9。此行变为紫红色
和兰色,以指示出此行既是断点又是探点。
将断点和探点设置为同一行,这样只被停止一次来执行数据传输和图表更新
两种操作。
3) 排列图表以便二者都可看到。
4) 点击Animate图标或F12运行程序。
此Animate命令与Run命令相似,其促使目标程序运行直至一个断点,目标
则被停止运行并更新窗口内容。然而,与Run命令不同的是,此Animate命令重
新启动直至到达另一断点。此过程一直持续下去直到手工停止目标程序。可以将
Animate命令看作一个Run-Break-contince的过程。
5) 注意每个图表包含两个半正弦波形,并且波形相反。每次到达探点,
CCS从文件得到100个值,并将他们写入inp_buffer地址。波形之所以
相反,因为input buffer中包含从读入的值,而output buffer包含被处理
函数最后设置与处理值。
注意:目标在探点终止
CCS在目标无论何时到达一个探点是都将暂时停止。因此,如果正使用探点,
则目标应用程序不会遇到实时极限(real-time deadlines)。在此发展阶段,正测试
运算法则。稍后分析使用RTDX和DSP/BIOS的实时行为。图表可以用探点或Run
命令更新。
步骤6:调整gain参数
在C源代码中,处理函数通过gain参数在input buffer使每个值相乘,并将
结果送入output buffer。这样做是通过下列包含于一个while 循环的语句:
*output++=*input++*gain;
此语句通过gain参数相乘每一个在inp_buffer 中的值,并将其放入
out_buffer中相应的位置。Gain参数最初设置为MINGAIN,在volume.h中定义
为“1”。为更改output,需更改gain参数。这样做的一种方法是使用一个监视变
量。
1) View ——> Watch window。
16
PhoenixTreeSky
2) 在watch window中右击,选择Insert New Expression。
3) 在对话框中输入gain,确定。则在窗中显示gain的值。
4) 如果已停止程序,点击Animate钮,重新启动程序。
5) 在watch window中双击gain。
6) 在变量编辑窗口中,改变gain的值为10,确定。
7) 观察改变gain值后,在output buffer图表中信号的振幅。
步骤7:观察out-of-scope变量
已经用watch window来观察和改变变量值。当变量目前没有在断点的当前
范围时,有时你应该检查变量。可通过使用堆栈调用来完成。
1) 单击Halt按钮或shift F5停止程序运行。
2) 回顾volume.c程序。注意到*input既在主函数中定义又在处理函数中
定义。然而,其没有在dataIO函数中定义。
3) 在volume.c代码窗口中,将光标放置在dataIO函数的return;行上。
4) 点击“手”形图标(Toggle Breakpoint)或F9,设置一断点。
5) 运行程序(F5)。CCS自动将断点移到此函数的下一行,以与汇编指令
相符合。并将显示一通知框告诉你系统已移走断点。
6) 按下F5,直到程序停止在dataIO函数的末尾断点处。
7) 在watch window窗口中右击,选择insert new expression。
8) 输入*input。
9) 注意:在watch window中显示*input=unknown identifier,表示*input
在dataIO函数范围内没有定义。
10) View ——> call stack。在watch window旁出现一call stack区域。
11) 点击main(),则在watch window中*input的值为主函数范围内的表
示。(此值应为0,如果修改文件可能会不同)。
12) Hide call stack窗口。
13) 移走dataIO中的return;行断点。
步骤8:使用一GEL文件
CCS提供另一种方法更改变量。此方法用GEL,一个扩展名方式,来创建一
个允许更改变量的小窗口。
17
PhoenixTreeSky
1) File ——> Load GEL。在Load GEL文件对话框,选择。
2) GEL ——> Application control ——> gain。当读取GEL文件时,gain已
被加入到菜单中。
3) 如果已经停止程序,点击Animate按钮。注意:gain仍为先前值,直
到改变gain板的滑标。
4) 在Gain窗口中,用滑标改变gain的值。则在output buffer窗口中波形
振幅改变。另外,无论何时移动滑标,在watch window中的gain变量值也随之
改变。
5) 停止程序运行。
6) 为观察gain GEL函数如何工作,在项目上点击GEL文件的“+”。双击
文件,观察其内容。
Gain函数定义一个slider (滑标)的最小值0,最大值10,与一个增量和
up/down页的值为1。当移动滑标,gain变量改变为滑标所显示的新值。
步骤9:调整并分析processingLoad(负载处理)
在教程中,使用profile-points(分析点)来测量调用put()所必需的周期数。
现在,用profile-point在观察processingLoad变量的结果,此变量被传递到汇编
加载程序。
ProcessingLoad最初设置为BASELOAD,BASELOAD在volume.h中定义为1。
1) profiler ——> Enable clock。(如果出现一资源冲突通知,关闭所有
DSP/BIOS plug-in(插件程序)窗口。接下来,选择Tools ——> RTDX,在下拉菜
单中选择RTDX使之无效)。
2) 打开文件volume.c。
3) 将光标放在Load(processingLoad);行,点击“钟形”图标(Toggle profile-
point)。
4) 同样将return(TRUE);行设置为Toggle profile-point。
5) profile ——> view statistics。其中位置标识数字应为从上向下,从小到
大。
6) 点击Animate标签或F12。
7) 注意第二个profile-point所显示的最大周期数,其应为1018个周期。
(实际数目可能不同,尤其是如果使用一特殊的开发板)这就是当processingLoad
为1时,执行加载程序所需的周期数。
18
PhoenixTreeSky
8) GEL ——> Application control ——>Load。
9) 输入2,并单击Execute。第二个profile-point的最大周期数变为2018。
当增加processingLoad 1,周期数增加约1000。这些指令周期在存储在
中的加载函数中执行。
10) 在profile statistics窗口中右击,选择clear All,将分析结果清零。
11) 停止运行程序(Halt或shift F5)。
12) ①关闭Load和gain控制窗口,窗口,时间/频率图形。
②File ——> File IO,点击Remove File来删除 。
③profile ——> Enable clock。
④取消所有的Breakpoints、probe points和profile points。
⑤关闭所有的窗口,关闭项目。
这些是做其它动作所必需的。
试一试:
① 在watch window加入processingLoad。当使用Load GEL控制,
processingLoad在watch window中的值被更新。
② 在watch window中右击,并选择Insert new expression。用不同的显示
形式进行试验。例如,键入*input,x作为表达式来观察十六进制的sine input。
③ 在volume.h中改变BUFSIZE为0x78(或120)并重新链接,接着重新载
入程序。在File IO对话中改变长度为0x78。对于两个图表,改变Acquisition Buffer
size 和Display size为0x78。这导致一个buffer包含了完整的正弦波而不是两个
半波形。激活程序,注意到输入和输出缓冲器图表现在同相。
④ 试着使用二选一时钟来生成统计表。用断点代替profile-point。选择
profile ——> view clock。运行程序到达第一个断点。在时钟区域双击清除之。重
新运行程序。时钟显示其到达第二个断点处的周期数。
⑤ 通过重复操作第3步至第5步来试验probe points。此时,只使用probe
point和Run命令。注意:需要建立3个probe point。这是因为一个probe point
只能与一个动作相关联。在此两个图表将被更新,一个文件被用做输入。每个这
些动作都需要其自己的probe point。
同时注意到每个probe point必须在代码的不同行进行。作为一结果,目标
被停止三次,并且在目标执行过程中在相同点动作不被执行。因为这些原因,在
此教程中使用的一个probe point和一个断点相结合的方法比只用probe points更
有效。
19
PhoenixTreeSky
Code Composer Studio 教程(四)
—— 调试程序性能
在此教程中,修改上一教程中的例子来建立一个确定其运行时间和允许多线
(multi-threading)的程序。看到调试效果的执行信息。也使用到更多的DSP/BIOS
特性,包括运行图表,实时分析控制板(RTA控制板),统计表视图和CLK、SWI、
STS、TRC模块。
此教程需要一个物理板而不能用一软件模拟器来实行。同时,需要CCS
DSP/BIOS成分。
步骤1:打开并检查项目
1) 在D:hanstudy4建立一文件夹。
2) project ——> open。打开。
3) 在此项目中包含以下文件:
① :此项目的配置文件。
② volume.c:主程序源代码文件,此文件使用了DSP/BIOS。
③ volume.h:此为一头文件,包括volume.c文件中定义的各种变量和结构。
④ :此文件包括载入程序,它只是一个可从只有一个自变量的C程
序生成的汇编循环程序。
⑤ :当保存配置文件时,此链接命令文件即生成。
⑥ volumecfg.s62:当保存配置文件时,此汇编文件生成。
⑦ volumecfg.h62:当保存配置文件时,此头文件生成。
步骤2:观察源代码
保持主函数循环,在真正的应用程序中的dataI/O作为一周期性外部中断的
结果是适合的。在例中仿真一周期性外部中断的一个简单方法是从on-chip定时
器中使用定时中断。
1) 打开文件volume.c。
2) 注意例中以下方面:
① 说明的数据类型已经改变,DSP/BIOS提供的数据类型对其它处理器是很
方便的。DSP/BIOS所使用的大部分类型转变成相应的C类型。
20
PhoenixTreeSky
② 代码用#include来定位三个DSP/BIOS头文件:std.h、log.h和swi.h。std.h
文件必须在其它DSP/BIOS头文件前包括其中。
③ 在配置文件中创建的对象视做外部对象。
④ 主函数不再调用dataIO 来进行处理。取而代之的是,主函数只是在调
用LOG_printf来显示一信息之后返回。这将程序投入到DSP/BIOS空循环。在这
点,DSP/BIOS调用程序控制执行路径。
⑤ 处理函数是通过一调用服从所有硬中断的processing_SWI 的软中断来
调用的。作为选择,一硬ISR(中断服务程序)可直接执行信号处理。然而,信
号处理需要大量周期,或者更多的时间直到下一个中断的到来。这样处理将防止
中断被执行。
⑥ dataIO函数调用一与软中断对象相关联的递减计数器的SWI_dec。当计
数器到达0,软中断安排函数执行并复位计数器。
DataIO函数对基于硬件的dataI/O进行仿真。一典型的程序在一缓存中积累
数据直到有足够的数据进行处理。在此例,处理函数每执行一次dataIO 函数运
行10次。计数器递减通过SWI_dec来控制它。
步骤3:修改配置文件
1) 打开文件。
2) 打开CLK、LOG和SWI管理器。此配置文件包含这些模块的对象,除
了配置文件中的默认设置对象。
3) 点亮LOG管理器中的对象trace ,右边窗口中是它的特性。Vo lu me . c
程序调用LOG_printf来写入大量从此LOG对象开始的例子。
4) 在LOG中,LOG_system对象上右击,从弹出菜单中选择propertise项。
此时出现一LOG_system properties对话框。在运行时,此Log通过不同的DSP/BIOS
模块的系统来存储事件轨迹。
5) 改变buflen特性为512words,确定。
6) 点亮CLK管理器中的dataIO_clk 。注意当此CLK对象被_dataIO激活时
此函数调用。在volume.c中有dataIO函数。
注意:下划线和C函数名称。
此C函数名称冠以下划线前缀是因为配置产生汇编语言文件。此下划线前缀
是从汇编中调用C函数的惯例。
此规则只在所编写的C函数中应用。不需要在配置产生对象或DSP/BIOS API
21
PhoenixTreeSky
调用中使用下划线前缀,因为对于每个对象两个名称自动地创建:一个前缀有下
划线,一个没有。
7) 既然在main中dataIO函数不再运行,那么什么导致此CLK对象执行
其函数?
为了找出原因,在CLK-clock manager properties对话框。
注意到clock manager的CPU中断是HWI_INT4。此特性为灰暗色,是因为它
由HWI_INT4对象自动设置。
8) 不做任何动作,cancel(取消)。
9) 打开HWI对象列表并检查HWI_INT4对象特性。其中断源是在DSP上
的定时器,而且当on-chip定时器产生一中断时它执行一函数来调用CLK_F_isr。
CLK对象函数的执行在CLK_F_isr硬中断函数范围内。因此,它们顺利执行且具有
比任何软中断更高的优先权。(CLK_F_isr保存着寄存器范围,因此CLK函数无需
像在一硬中断服务程序函数内通常所要求的那样保存和还原范围。)
10) 在SWI管理器中,在processing_SWI软中断对象上右击。从弹出菜单
中选择properties项。
① function:当此软中断被激活,处理函数运行。
② mailbox:当一软中断运行时,此mailbox值可控制。个别的API调用影响
着mailbox的值,并可传递依靠结果值的软中断。当一软中断被传递时,当有最
高级优先权的软中断和硬中断线被传递完毕时它运行。
③ arg0、arg1: inp_buffer和out_buffer地址被传递到处理函数。
11) 不做任何更改,cancel。
12) 既然处理函数不再在main中运行,那么什么导致此SWI对象来执行
其函数?在volume.c中,dataIO函数调用减少mailbox值并当新的mailbox值为
0时传递软中断的SWI_dec。因 此 ,SWI对象每到dataIO_CLK对象执行dataIO
函数第十次时执行其功能。
13) File ——> close。提示是否保存变动,Yes。保存此文件同时产生
、volumecfg.s62和volumecfg.h62文件。
14) Project ——> Build。
步骤4:用thread execution(线性执行)来观察运行图表
当你可以用在处理函数内放置一个probe point来测试程序并观察输入/输出
数据图表时,你已经测试了信号处理运算法则。到这一步,你的注意焦点在确定
22
PhoenixTreeSky
thread execution能遇到它们的real-time deadline。
1) File ——> Load program,选择。
2) Debug ——> go main。程序运行到主函数的第一条语句。
3) Tools ——> DSP/BIOS ——> RTA control panel。在CCS窗口底部出现
一使用仪器类型的列表。
4) 在此列表中选中enable SWI logging、enable CLK logging和global host
enable项。
5) Tools ——> DSP/BIOS ——> Execution Graph。在CCS窗口底部出现一
执行图形窗口。
6) 在RTA control panel窗口中右击,选择property page项。
7) 检验message Log/Exection Graph的刷新速率为1 second,确定。
8) Debug ——> Run。在Exection Graph窗口中观察图形。
9) 在时间行上的标志显示每次clock 管理器运行了的CLK函数,计数着
两次processing_SWI对象被运行的标志。应该有10个标志。这表示processing_SWI
对象运行其函数每10次dataIO_CLK对象运行其函数。这是所期望的,因为通过
dataIO函数来减少mailbox值是从10开始。
步骤5:改变并观察加载程序
使用执行图表,能看到程序与其real-time deadline相遇。然而,在一个典型
程序中的信号处理函数必须执行复杂而循环的衰减工作,而不是增加一个值并将
其复制到另一缓存中。你可以通过用Load函数逐渐增加循环衰减来仿真如此复
杂的过程。
1) Tools ——> DSP/BIOS ——>CPU Load Graph。出现一空的CPU Load
Graph。
2) 在RTA control panel窗口中右击,选择property page项。
3) 将statistics view/cpu load graph的刷新速率改为0.5秒,确定。
注意:cpu load通常很低。
Statostics view和cpu load从目标传递很少的数据到主机,因此可以不断地
更新其窗口而不会对程序的执行有大的影响。Message Log和Execution Graph传
递的字数指明了配置文件中相应的LOG对象的buflen(缓存长度)的特性。
由于更多的数据将被传递,你可以使这些窗口更新慢些。
4) File ——> Load GEL。选择文件。
23
PhoenixTreeSky
5) GEL ——> Application Control ——> Load。
6) 输入100,点击Exacute。Cpu Load增加到约9%。
7) 在Execution Graph窗口中右击,并选择clear。注意到程序依然遇到它
的real-time deadline。在每个processing_SWI函数执行间有10个时间标志。
8) 使用GEL控制,改变为200,execute。
9) 在Exection Graph窗口中右击,选择clear。当processing_SWI函数执
行时,一个或两个时间标志出现。这样做意味着程序已消除其real-time deadline?
不,这表示程序的正确机能。运行CLK对象函数的硬中断可以中断软中断处理,
并且软中断依然会在其需要重新运行前完成其工作。
10) 使用GEL控制,将load变为1250,execute。Cpu load增加到大约95%,
并且Exeacution Graph和cpu load更新更慢。
11) 在Execution Graph窗口中右击,选择clear。程序依然遇到其real-time
deadline。因为processing_SWI在10个时间标志出现前完成了。
12) 改变GEL load为1500。Cpu load Graph和Execution Graph停止更新。
这是因为Execution Graph数据在一个空thread execution 中送到主机,此空
thread execution在程序中执行优先权最低。因为高级优先权thread execution使
用所有处理时间,没有足够的时间给主机控制更改就已执行。程序此时失去其
real-time deadline。
13) Debug ——> Halt。这将停止程序并更新Execution Graph。你会在
Execution Graph窗口中assertions行看到矩形。这些矩形指出CCS探测到应用程
序失去一real-time deadline。
14) 改变GEL load为10。Cpu load和Execution Graph重新更新。
注:用RTDX更改load
使用load GEL控制暂停目标。如果你正分析一实时系统而不想影响系统的运
行,使用一RTDX(real-time data exchange)应用程序更改load。这在下一教程中
详述。
步骤6:分析调度表
你可以使用其它DSP/BIOS控制来执行DSP上的load和processing_SWI对象
中的处理统计表。
1) Tools ——> DSP/BIOS ——>Statistics view。一 个statistics view区域
出现。接下来需选择你要观察的统计表。
24
PhoenixTreeSky
2) 在statistics view 窗口中右击,选择property page 项。点亮左框中的
processing_SWI项和右框中全部项,确定。
3) 在窗口中出现一processing_SWI对象的统计表区域。
4) 在RTA control panel窗口中,选中enable SWI accumulators项。
5) 运行程序,Run。
6) 注意在statistics view中的max值,SWI statistics在指令周期被测量。
7) 使用GEL控制,增加load,execute。注意从开始到结束processing_SWI
增加指令周期的执行数目max值的改变。
8) 用不同的load值进行试验。如果减小load值,在statistics view窗口中
右击,选择clear项。这样做重置到他们最低的可能值,允许你观察在max区域
中的当前指令周期数。
9) Halt。关闭所有打开的DSP/BIOS和GEL控制。
步骤7:加入外部STS装置
上一步,你使用statistics view来观察在一软中断执行期间指令执行数目。如
果使用一配置文件,DSP/BIOS自动地支持统计表。这个叫做隐性装置。你也可以
使用API调用其它统计表。这叫做显性装置。
1) 打开文件。
2) 在STS管理器上右击,选择Insert STS。
3) 将新的对象STS0改名为processing_STS。此对象的默认特性都是正确
的。
4) File ——> close。保存该改变到文件。
5) 打开volume.c文件。将程序做以下改动:
① 在#include
#include
#include
#include
② 在注释行/*objects created by the configuration Tool*/下加入下列行:
extern far STS_obj processingLoad_STS;
③ 在processing函数中,调用Load函数前加入下列行:
/*enable instrumentation only if TRC_USER0 is set */
if (TRC_query(TRC_USER0)==0)
25
PhoenixTreeSky
{ STS_set ( &processing_STS,CLK_gethtime());}
④ 在processing函数中,调用Load函数之后加入下列行:
if (TRC_query(TRC_USER0)==0)
{ STS_delta(&processingLoad_STS,CLK_gethtime());}
6) File ——> save。
7) project ——> Build。
步骤8:观察显性装置
1) File ——> Load program。打开文件。
2) Tools ——> DSP/BIOS ——> RTA control panel。
3) 在RTA control panel窗口中,取消前面所选中的项,重新选中enable
SWI accumulators、enable USER0 trace和global host enable项。
4) Enabling USER0 trace致使调用TRC_query(TRC_USER0)返回0。
5) Tools ——> DSP/BIOS ——> Statistics view。
6) 在statistics view窗口中右击,选择property page项。选择processing_SWI
和processingLoad_STS项,并选中所有四个statistic项,确定。
7) Debug ——> Run。
8) 对processingLoad_STS的max值增加4。
因为使用CLK_gethtime函数作为processingLoad的基准,processingLoad_STS
统计表在on-chip定时计数器增量被测量。SWI统计表在指令周期被测量。在
TMS320C6000 DSPs上,时间的高分辨率每4个指令周期被增加。因此,为转换
processingLoad_STS单元到指令周期,增量必须为4。
9) 在指令周期从processing_SWI max值减去processingLoad_STS max值。
结果应为3420指令周期。(实际上可能有所不同,特别是如果使用了特殊的开发
板)。
10) 这些指令在processing函数内执行,但并不在STS_set和STS_delta调
用之间。例如,如果load 为10,processingLoad max约为2604,processing_SWI
max约为13832。为计算在processing 函数内指令周期(除了调用STS_set和
STS_delta之外)的执行数,公式如下:13832-(2604*4)=3416
11) GEL ——> Application control ——>Load。
12) 改变Load的值。
13) 当两max值增加,两者之间的差度保持不变。
14) 在RTA control panel窗口中,取消enable USER0 trace选项。
15) 在statistics view窗口中右击,选择clear项。
26
PhoenixTreeSky
16) 注意processingLoad_STS没有值被更新。这是因为取消USER0 trace导
致程序中的下列说明为错误:
if (TRC_query(TRC_USER0)==0)
结果导致STS_set和STS_delta调用不被执行。
17) Halt,停止程序运行。
试一试:
为更深一层地探究DSP/BIOS,试一试以下内容:
① 在配置文件中改变SWI管理器的统计表单元特性为毫秒或微秒。Rebuild
并Reload程序,观察在statistics view中值的改变。
② 在配置文件中改变processingLoad_STS对象的主机操作特性A*x和A特
性为4。此主机操作对统计表以4来增加。调用CLK_gethtime导致统计表在高分
辨率定时器增量被测量,次增量每4个cpu周期出现一次。因此,改变主机操作
来转换定时器增量为cpu周期。Rebuild程序,观察statistics view 中值的改变。
③ 用CLK_gethtime函数来代替CLK_gethtime函数。Rebuild,观察statistics
view中值的变化。CLK_gethtime函数得到一个在执行图表中符合定时器标志的低
分辨率时间。当使用CLK_gethtime时必须较大幅度地增加load 来改变statistics
view值。
27
PhoenixTreeSky
Code Composer Studio 教程(五)
—— 实时性能分析
在此教程中,你对程序进行实时性能分析和恰当的时序安排。使用RTDX
(real-time data exchange —— 实时数据交换)对目标进行实时改变,使用
DSP/BIOS周期函数,并设置软中断优先权。
此教程需要一物理板而不能用一软件仿真器来实现。同时,也需要CCS的
DSP/BIOS和RTDX部分。
步骤1:打开并检查项目
1) 建立工作文件夹,编译文件,并创建下列文件:
① volume.c:源文件,允许你在不停止目标程序运行的情况下使用RTDX来
改变load。
② :用VB5.0编写的一个简单的窗口应用程序,它实时地用RTDX
将load值送到目标。
③ ,,:如果你已掌握了VB,就可以用VB
来检查应用程序的这些源文件。
2) 进入CCS,打开项目。
步骤2:修改配置文件
在此,需加一个新的对象在配置文件中。
1) 打开文件。
2) 选择LOG_system,改变buflen特性为512 words,确定。
3) 在PRD管理器上右击,选择Insert PRD。
4) 将PRD0改名为loadchange_PRD。
5) 在loadchange_PRD对象上右击,选择properties项。
6) 将period(ticks)框中改为2,function框中改为_loadchange,确定。
① 将period变默认值为2,PRD管理器用CLK管理器来驱动PRD的执行。
CLK类的。默认特性每毫秒产生一个时钟中断来触发一个PRD标记。因此,此
PRD对象每2毫秒运行一次其函数。
② 改变function为_loadchange。每个period,此PRD对象执行一次
28
PhoenixTreeSky
loadchange C函数。
7) 打开SWI管理器。一个SWI对象PRD_SWI已自动加入。在运行期间,
此软中断执行周期函数。因此,所有PRD函数在软中断环境下被调用并对硬中
断让步。相反,CLK函数在硬中断环境下运行。
8) 打开CLK管理器。注意到PRD_clock的CLK对象运行一个叫PRD_F_tick
的函数。此函数导致DSP/BIOS系统时钟做标记(通过调用PRD_tick API函数),
并且如任何PRD函数需要运行,PRD_swi软中断被传递。PRD_swi对所有的PRD
对象运行函数。
9) 右击PRD管理器,选择properties。PRD管理器有一特性叫 Use CLK
manger to drive PRD。确保此项被选中。如此项没选中,PRD_clock对象将自动被
删除。程序可能接着从其它一些事件中调用PRD_tick。例如,一驱动周期函数的
硬中断。
10) 回想一下,processing_SWI对象有一个值为10的mailbox,并且mailbox
值通过每毫秒运行一次的data_CLK对象来递减,结果processing_SWI每10毫秒
运行一次其函数。相反,loadchange_PRD对象应每2毫秒运行其函数一次。
11) File ——> close。保存改动到。同时产生、
volumecfg.s62和volumecfg.h62。
12) Project ——> Rebuild All。
步骤3:观察源代码的改变
打开volume.c文件。与前一教程相比此源代码有所不同。
注意void loadchange() {…}函数,其由PRD对象调用,这是处理器被控制的
地方。
此函数用RTDX API函数在实时信号处理中改变load。对于程序中的改变(与
前一教程相比)注意以下几个方面:
① RTDX_enableinput的调用可将control_channel的输入通道使能,所以数
据可从主机流向目标。在运行时,一个VB主客户程序写一个控制值在那个通道,
从而送数据到目标应用程序。
② RTDX_readNB的调用要求主机送一个load控制值在control_channel上,
并将其存储在不同的被调控制,此调用是非模块化的,它不须等待主机传递数据
即返回。
当主客户程序写入control_channel时,数据到达。从调用RTDX_readNB起
29
PhoenixTreeSky
直到数据被写入不同控制,此通道一直忙,且没有额外的请求在此通道能通过(这
叫调用RTDXreadNB不成功)。在此期间,调用RTDX_channel Busy对
control_channel返回TRUE。
③ ProcessingLoad=control;说明通过control来设置processingLoad为指定值。
步骤4:在运行时用RTDX控制来改变Load
当你通过在处理函数中放置一probe point来测试程序并观察输入/输出数据
图表时,你已经测试了信号处理运算法则。在此发展阶段,你应注意于确保所加
入的调度单元仍能遇到其real-time deadline。同样,probe point终止目标并干扰
测试的实时特性。
1) File ——> Load program,加载。
2) Tools ——> DSP/BIOS ——> RTA control panel。
3) 在RTA control panel中选中以下几项:
enable SWI logging、enable PRD logging、enable CLK logging、enable SWI
accumulators、enable PRD accumulators、global host enable。
4) Tools ——> DSP/BIOS ——> Execution Graph。
5) Tools ——> DSP/BIOS ——> Statistics view。
6) 在statistics view中右击,选择property page。选中以下几项:
loadchange_PRD、PRD_swi、processing_SWI和右框中Count、max、average。
7) 在RTA control panel中右击,选择property page。
8) 将message log/exection graph刷新率设为1秒,将statistics view/cpu
load graph刷新率设为0.5秒,确定。
9) Tool ——> RTDX。
10) 注意到RTDX已激活。这是在第2)步打开DSP/BIOS控制之后出现的。
在持续模式下DSP/BIOS控制配置和使能RTDX。
在持续模式,RTDX没有记录从目标接收到的数据。这允许持续数据流。(如
果你的程序没有使用DSP/BIOS,你可使用RTDX区域来进行配置并直接使能
RTDX)。
11) 使用窗口资源管理器,运行(在study5 文件夹中)。Load
control窗出现。其中每个刻度改变load值50,大约50000指令。这个简单的窗
口应用程序用VB编写的,如果你已掌握了VB,你可检查源文件。此应用程序使
用下列RTDX功能:
30
PhoenixTreeSky
① (“control_channel”,”W”):当打开应用程序,打开一个控制通
道来写信息到目标。
② ():当关闭应用程序,关闭控制通道。
③ 2(datal2,bufstate):写入滑标控制control_channel的当前值,使
目标程序可以读此值并用其来更新load。
12) Debug ——> Run。
Processing_SWI每10个time 记号(和PRD记号)出现一次。PRD_swi每2
个PRD记号运行一次。Loadchange_PRD在PRD_swi顺接运行。这些是预期的运
行频率。
PRD统计表在PRD记号中测量。SWI统计表在指令周期测量。Loadchange_PRD
的max和Average区域显示少于从开始运行到其完成间此函数所需时间的一完
整PRD记号。
13) 用Load control窗口中逐渐地增加processing load。(当DSP程序被终
止时,如果在Load control窗口中移动滑标,新的load control值通过RTDX在主
机上进行缓冲。这些直到DSP应用程序重新运行并从主机调用RTDX_readNB来
请求更新load值)。
14) 重复步骤13),直到看到loadchange_PRD 的max和Average值增加,
并且在Execution Graph的Assertions行出现兰色方块。Assertions表示一个调度
元没有遇到其real-time deadline。
当你增加load,loadchange_PRD 的max值增加,随着load 的增加,
processing_SWI占用长时间来运行而loadchange_PRD 不能开始运行,直到长时
间通过其real-time deadline。
当你不断增加load,因而低优先权的空循环不再执行,主机停止接收实时数
据且DSP/BIOS plug-ins停止更新。用行列数据停止目标更新plug-ins。
步骤5:修改软中断优先权
为理解为什么程序没有遇到其real-time deadline,你需要检查软中断调度元
的优先权。
1) Debug ——> Halt。
2) 打开。
3) 点击SWI管理器。SWI对象优先权在右侧窗口中显示。(KNL_swi对象
运行一个执行TSK管理器的函数。此对象必须总是具有最低的SWI优先权。)因
31
PhoenixTreeSky
为PRD_swi 和processing_SWI 对象二者具有相同的优先级,当processing_SWI
正在运行时PRD_swi不能占在其前面。
Processing_SWI每10毫秒运行一次,PRD_swi每2毫秒运行一次。当load变
高时,processing_SWI运行超时2毫秒,并且其防止PRD_swi遇到其real-time
deadline。
4) 为改正此程序,将PRD_swi拖至一高级别的优先权,如Priority2。
5) File ——> save。
6) File ——> close。关闭。
7) Project ——> Build。
8) File ——> Reload program。
9) Debug ——> Run,重新执行程序。在运行时用Load control窗口来改
变load。
10) 你可立即增加load而不会导致PRD_swi错过其real-time deadline。
11) Debug ——> Halt,关闭所有窗口。
试一试:
为进一步探究DSP/BIOS,试一试下面内容:
① 当你增加load 时,Execution Graph显示processing_SWI需要不止一个
PRD记号来运行。这意味着processing_SWI 正失去其real-time deadline 吗?要
知道processing_SWI必须每10毫秒运行一次,而PRD记号每毫秒都会出现。
② 如果processing函数直接从硬ISR(中断服务程序)调用而不是延迟到
软中断,将会发生什么?这将导致程序失去其real-time deadline。因为硬ISRs运
行的优先权高于最高级别优先权的SWI对象。
当load高时,PRD_swi需要优先于processing_SWI。如果processing_SWI是
一个硬中断,它不能被PRD_swi占先。
③ 观察cpu load graph。使 用RTA control panel来开启和关闭统计表类加
器。注意cpu load graph为受影响。这证明统计表类加器在处理器上放置了一个
非常小的load。
统计表类加器对processing_SWI统计表有多大影响?当你开启和关闭统计
表类加器时观察statistic view。所不同的是每个类加器需要指令数目的一个精确
测量。记住观看结果要clear statistics view。
④在loadchange函数中加入STS_set和STS_delta。这个变化会影响cpu load
32
PhoenixTreeSky
多少?现在,在dataIO函数中加入调用STS_set和STS_delta。这变化会影响cpu
load多少?为什么?认为每个函数周期被执行。甚至对函数处理所需要的有一个
很小的增加,运行周期在cpu load上有惊人的影响。
33
PhoenixTreeSky
Code Composer Studio 教程(六)
—— 与I/O设备的连接
在此,你用RTDX(Real-time Date Exchange)和DSP/BIOS将一个程序与I/O
设备进行连接。你也使用到DSP/BIOS API 中的HST、PIP和SWI模块。
在此需要一个物理板,且不能用一个软件仿真器来实现。同时,需要CCS的
DSP/BIOS和RTDX部分。
步骤1:打开并检查项目文件
打开一个项目文件,并检查此项目文件中的源代码文件和所用到的库文件。
1) 创建一个文件夹,d:hanstudy6 。
2) project ——>open ,打开study6中的文件。
3) 在此项目中包含以下文件:
① hostio.c:主程序源文件。
② :此 VB 应用程序产生一正弦波并显示输入、输出信号。
③ :此 VB 应用程序允许你控制输出信号的 volume。
④ :当保存配置文件(configuration file)时产生的链接命令文
件。
⑤ hostiocfg.s62:保存配置文件时创建的汇编文件。
⑥ hostiocfg.h62:保存配置文件时创建的头文件。
步骤2:观察C源代码
在此教程中的例子对一个将音频信号数字化的DSP应用程序进行仿真,调
整它的volume,且调整volume产生一个模拟输出。为达到简易性,此例中没有
实际的设备被用来发送和接收模拟数据,代替它的是,例子用host-generated数
字数据测试运算法则。输入/输出数据和volume控制用RTDX在host和target之
间进行调动。
在主机上运行一VB应用程序使用RTDX来产生输入信号并显示输入和输出
信号。此应用程序允许开发者不停止目标进行测试运算法则。类似的方法可用来
创建其它应用程序进行实时测试控制的显示。
1)打开hostio.c文件。
34
PhoenixTreeSky
2)注意此例的以下几个方面:
①三个RTDX通道被全局定义。第一个输入通道控制volume。第二个输入通
道接收从主机来的输入信号。输出通道将来自目标的输出信号传送到主机。
②如果通道当前不在等待输入调用RTDX_channelBusy返回FALSE,这表示数
据已到达并可以读取。当主机客户写数据到control_channel时数据被异步传输。
③RTDX_Poll调用与RTDX底层进行对话来读写数据。
④如果通道被使能,调用RTDX_read等待数据。
⑤如果通道使能,调用RTDX_write写缓存中的内容到输出RTDX通道。
⑥当目标通过一个RTDX_enableinput调用使能control_channel,其它RTDX通
道没被使能。取而代之的是,一个主机程序使能这些通道。这是因为被看作应用
程序主要部分的使用control_channel的滑标来进行控制。通过在目标程序中使
能此通道,你知道当应用程序运行时通道被使能。相反,A2D和D2A通道被用来
测试运算法则。因此,这些通道通过主机应用程序被使能和禁止。
步骤3:回顾signalprog应用程序
VB应用程序的源代码在文件中是可用的。关于
此应用程序的详细资料在文件中提供。在此部分,检查几个例中
重要的函数和例程。
① Test_ON:当你点击Test_ON按钮,此例程运行。它创建RTDX输入通道(to
DSP)和输出通道(from DSP)的输出界面实例。接着其打开并使能一通道。在
应用程序中的通道与在hostio.c源代码中全局定义的通道相同。
此例程同时清除图形并启动用来调用Transmit_Signal和Receive_Signal函数
的定时器。
在VB源代码中定义的全局定义将Test_ON例程中用到的READ_CHANNEL和
WRITE_CHANNEL连接到hostio.c中用到的D2A_channel和A2D_channel。
②Test_OFF:此例程禁止、关闭和释放通过Test_ON创建的RTDX对象。它也
禁止定时器。
③Transmit_Signal:此函数产生一正弦波信号并在传输信号图形中显示。接着,
函数试着用toDSP通道的写方法传输信号到目标。
④Receive_signal:此函数用fromDSP通道的ReadSAI2方法从目标读一个信号。
并在接收信号图形中显示。
⑤tmr_MethodDispatch_Timer:此例程中调用
35
Transmit_Signal和
PhoenixTreeSky
Receive_Signal函数。此例程在定时器目标通过Test_ON例程使能之后1毫秒时
间间隔被调用。
步骤4:运行应用程序
1) project ——>Build。
2) File ——>Load program,加载文件。
3) Tools ——>RTDX。
4) 在RTDX窗口中点击configure按钮。在RTDX特性对话框的General
Setting标签,选择Continous模式,确定。
5) 在RTDX窗口中将RTDX disable改为RTDX enable 。
6) Tools ——>DSP/BIOS ——>Message Log 。在Messega Log窗口中右
击,选择property page 项,选择trace作为log名称进行监控,确定。
7) Debug ——>Run 。
8) 运行和。观看这两个VB应用程序。
程序必须在RTDX被使能并且程序在运行之后启动。因为当你运行程序时,它创
建并打开RTDX control channel 。如果在此RTDX没有使能,不能打开此
通道。程序可在任何时候被启动。直到你点击Test ON按钮,它才
使用RTDX 。
9) 在signalprog窗口右上角点击Test ON ,启动输入和输出通道。
10) 在volume slider窗口中拖动滑标。这会改变输出信号的volume 。观
察接收到的信号图形振幅的变化。(只有图形的左、右刻度值发生变化。图形变
化刻度自动地调整正弦波的尺寸和窗口的尺寸。)
注意:volume slider的最初设置volume slider滑标的最初设置与应用程序是
非同步的。当你第1次移动滑标时,它们被同步。
11) 关闭volume slider应用程序。这样就关闭了输入、输出通道。
12) 在signalprog窗口中点击Test OFF,关闭控制通道。
13) Debug ——>Halt。停止程序运行。
14) 这时你在message log区域看到调用LOG_printf的Hostio例子的启动
信息。你先前没有看到此信息是因为整个程序在主程序内运行。DSP/BIOS在空循
环内与主机进行通信。知道从主程序返回一个程序,此程序才进入空循环。因此,
如果你想在运行时刻观察DSP/BIOS调用的结果,你的程序应该在从主函数返回
之后实现其功能。
36
PhoenixTreeSky
步骤5:修改源代码以使用Host Channels and Pipes
现在修改程序来使用DSP/BIOS提供的Host Channels and Pipes。修改后的程
序仍旧实时测试你的DSP运算法则。尤其是在主机上产生一个正弦波,这次数据
来自主机文件。
HST模块用外围设备提供一个更直接的途径以实现I/O。HST模块对主机I/O
使用PIP模块。每次I/O设备和ISRs准备好测试,你可使用PIP模块API对源代
码做最小的修改。
1) 改源文件hostio.c并创建一输入数据文件,如下:
① hostio.c:被修改后的源文件,它使用DSP/BIOS API 的HST和PIP模块来代
替RTDX传送输入、输出信号。
② :此文件包含输入数据。
2) 打开hostio.c,源代码做了如下改动:
① 加入下列头文件:
# include
# include
② 去掉BUFSIZE定义、inp_buffer和out_buffer的全局定义和RTDX输入/
输出通道说明。保留了RTDX通道来控制volume。
③ 将主函数中一个while循环中的input和output功能移到A2DscaleD2A
函数内。
A2DscaleD2A函数由A2DscaleD2A_SWI对象调用。
A2DscaleD2A_SWI对象传递两个HST对象到此函数。此函数于是调用
HST_getpipe来设置每个HST对象使用的内部PIP对象的地址。
调用PIP_getReaderNumFrames和PIP_getWriteNumFrames,然后测定在输入
pipe中是否至少存在一frame已准备好被读出和在输出pipe一frame被写入。
使用与步骤2相同的RTDX调用,此函数获得由RTDX控制通道设置的volume。
PIP_get的调用从输入管道中获得一个完整的frame。PIP_getReaderAddr的
调用获得一个在输入pipe frame中开始数据的指针,并且PIP_getReaderSize获得
在输入pipe frame中的字数。
PIP_alloc的调用从输出pipe中获得一空帧。PIP_getWriterAddr的调用在输
出pipe frame中获得一个写数据开始位置的指针。
函数于是通过volume增加输入信号并将结果写到由PIP_getWriterAddr提供
的使用指针的frame中。
37
PhoenixTreeSky
PIP_put的调用将完整的frame放入输出pipe,PIP_free的调用反复应用输入
图象,因此它可以在下次此函数运行时重新生成。
④ 加入一error函数,此函数写一个error信息到trace log,且将程序置于
一无限循环中。如果当没有可被处理可利用的数据frame 时,A2DscaleD2A运行,
则此函数运行。
步骤6:更多有关Host Channels and Pipes
每个Host Channel使用一个内部pipe。当你正在使用一个Host Channel,你
的目标程序控制一个pipe末端且Host Channel控制plug-in操纵pipe的另一端。
当你正准备修改程序来使用除Host PC之外的外围设备时,你可保持控制目
标端的pipe的代码,并在通过处理I/O设备以控制pipe另一端的函数内加入代
码。
步骤7:向配置文件中加入通道和一个软中断
A2DscaleD2A函数由一SWI对象调用并使用两个HST对象。
A2DscaleD2A函数也涉及两个PIP对象,但当你创建HST对象时,这些对象
被内部创建。HST_getpipe函数获得与每个HST对象进行通信的内部PIP对象的
地址。
1) 打开文件。
2) 在HST管理器上右击,选择Insert HST项。
注意:已经存在两个叫RTA_fromHost和RTA_toHost的HST对象。这些对象
内部使用以更新DSP/BIOS控制。
3) 将HST0改为input_HST。
4) 在input_HST上右击,选择properties项,为此对象设置下列特性:
① mode:此项改为input。此项特性决定目标程序控制pipe的哪一端,与
Host Channels控制play-in操纵哪一端。一输入通道将数据从主机送至目标。一
输出通道将数据从目标送到主机。
② framesize:此项改为64。此特性设置在通道中frame的大小。
③ notify、arg0、arg1:此三项分别为_SWI_andn、A2DscaleD2A_SWI和1。当
此输入通道包含一完整的frame,且参数传递到函数时,这些特性指定函数来运
行。SWI_andn函数提供另一种方法来操纵一个SWI对象的mailbox。
38
PhoenixTreeSky
SWI_andn函数将mailbox值视为一个bitmask(位掩码)。它清除掉由传递到
函数的第二参数指定的bits。因此,当此通道包含一full frame时(因为目标被一
frame 充满),它为A2DscaleD2A对象调用SWI_andn,并致使其清除mailbox的
bit 1。
5) 插入另一个HST对象,并命名为output_HST。
6) 设置下列特性:
① mode : output。
② framesize : 64。
③ notify : _SWI_andn。
④ arg0 : A2DscaleD2A_SWI。
⑤ arg1 : 1。
当此输出通道含有一空frame(因为目标读并释放一frame),其使用SWI_andn
来清除mailbox的第二位。
7) 右击SWI管理器上,选择Insert SWI。
8) 将SWI0改为A2DscaleD2A_SWI。
9) 设置A2DscaleD2A_SWI下列特:
① functin: _A2DscaleD2A。当此软中断被传递并运行时,此项特性致使对象
调用A2DscaleD2A函数。
② mailbox:3。这是mailbox对此对象的原始值。Input_HST对象清除掩码的
第一位,且output_HST对象清除掩码的第二位。当此对象运行A2DscaleD2A函
数时,mailbox值重新设置为3。
③ arg0、arg1:input_HST、output_HST。两个HST对象名称被传递到
A2DscaleD2A函数。
10) File ——> close。保存改变,同时产生、hostiocfg.s62 和
hostcfg.h62。
步骤8:运行修改后的程序
1) project ——> Rebuild All 。
2) File ——> Load Program。选择 。
3) Tools ——> DSP/BIOS ——> Host Channel control 。Host Channel control
列出了HST对象并允许你连接它们到Host PC文件来启动和关闭通道。
4) Debug ——> Run 。
39
PhoenixTreeSky
5) 在input_HST通道上右击,并选择Bind 。
6) 在你的工作文件夹内选择 。
7) 在output_HST通道上右击,并选择Bind 。
8) 在文件名称框中键入 ,并点击Bind 。
9) 在input_HST通道上右击,并选择Start 。
10) 在output_HST通道上右击,并选择Start。注意Transferred列显示数
据正被调用。
11) 当数据调动完毕,Halt
40
,停止程序的运行。
版权声明:本文标题:Code Composer Studio 教程 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1711409773a592642.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论