这一节适用所有使用 Code Composer Studio IDE 的平台。然而,不是所有器件都能权限
使用所有本节所讨论的工具。用户如果想知道可供使用的工具列表,可查看在线帮助和 Code
Composer Studio IDE 提供的在线文档。
本节讨论 Code Composer Studio 包含的不同调试工具
1 建立调试环境
为了实现成功调试,调试环境需要按下面章节的介绍进行配置
1.1 设置用户调试选项(Setting Custom Debug Options)
几种调试选项是在 Code Composer Studio IDE 中可用户定制的。用户可以配置这些选项以便辅助
调试过程或者符合自己的偏好。
1.1.1 调试属性标签
这个调试属性对话框在路径 Option->Customize->Debug Properties 下的用户化面板中找到。它允许
用户在调试中禁用某些缺省的行为在线帮助。若要了解其它选项,请查看在线帮助。
调试属性中包含的行为如下:
. 自动打开反汇编窗口:禁用这个选项将使得程序装载后反汇编窗口不再出现。缺省设置为打开。
. 自动跳至 Main 函数:激活这个选项将使得在程序装载之后调试器自动跳至 Main标号所在行。缺
省设置为禁用。
. 当控制窗口打开时连接至目标器件:控制窗口是整个 Code Composer Studio IDE 的交互接口。在
运行 PDM 时可以打开多个控制窗口实例。用户遇到目标器件连接问题或不需要连接实际器件(例如
些源代码时)时可以禁用此选项。缺省设置为禁用。
. 移除连接时剩余调试状态:Code Composer Studio IDE 与目标器件断开时,依缺省设置它会移除
断点。如果在调试过程中有错误,在重新连接器件时,Code ComposerStudio 将会尝试再次移除所有断
点。但是这种尝试将可能损坏某些目标器件。所以, TI 建议禁用这个选项,以避免重连器件时再次移除断点。
. 显示速度(Animation speed):显示速度是断点间的最小时间(秒为单位)。若从上次断点开始执行
超过了此最小时间,程序执行将会重启。
1.1.2 目录
为了打开源文件,调试器需要知道应用调试时源文件位置。调试器包含有工程中所有文件, 当前目录
下的文件的源文件路径信息,以及精确指向 Code Composer Studio IDE 的路径。指向 Code Composer
Studio IDE 的路径缺省条件下为空。所以,如果被调试的项目使用了打开的工程或是当前目录下没有
的源文件,那么必须为这些文件单独设定路径。如果没有,由于调试器在需要引用此文件的地方无法
自动打开文件,调试将会停止。此时,系统将会要求设计者手动寻找该文件。例如,在建立工程时包
含库文件就是很典型的使用已打开工程中没有的源文件的例子。目录对话框使得用户可以指定额外的
搜索路径,这样调试器就可以依据该路径寻找被包含的源文件。指定搜索路径的方法为,选中
Option->Customize menu dialog 中的 Directories tab。用户可能需要使用对话框中的滚动条来找到这个
标签。
选项包括下列这些:
. 目录(Directories) 目录列表显示被定义好的搜索路径。调试器依从上到下的顺序来搜索列出
的目录。如果两个文件有同样的名字并且保存于不同的目录下面,那么出现在目录列表最高处的文件
取得优先权。
. 新建(New) 如果需要添加一个新的目录到目录列表,点击新建(new)。键入完整路径或者浏览
合适的目录。缺省条件下,新目录将会被添加到列表的最底端。
. 删除(Delete) 选中目录列表中的一个目录,然后点击删除(delete)将该目录移除出列表。
. 上移/下移(Move Up/Move Down) 选中目录列表中的一个目录,然后点击上移(Move Up)将该
目录上移或者(Move Down)将该目录下移。
. 查看子文件夹(Look in subfolders) 用户可以激活调试器搜索列出路径中的子文件夹。
. 缺省 File I/O 目录(Default File I/O Directory) 除了设置源文件目录外,用户还可以通过激活缺省
的 File I/O 目录选项为 File I/O 文件设置缺省的路径。使用浏览按钮来寻找你希望作为缺省目录的路
径。
1.1.3 程序装载选项
. 用户可以为通过选择 Option->Customize menu dialog 下的 Program/Project Load tab 为程序装载
进行缺省设置。
它包括下面的缺省行为:
. 在程序装载时进行验证该可选框缺省设置为有效。这意味着 CCS 将确认(通过读取选定的内存单
元)程序是否被正确装载。
. 在建立(工程)后装载程序 当该选项被选中,在建立工程后马上就装载生成的可执行文件。
这样目标器件就包含了工程建立后的当前符号信息。
. 装载时不设置 CIO 断点 缺省情况下,如果用户的程序使用到 TI 实时库(rts*.lib),程序装载
时,一个 C I/O 断点(C$$IO$$)将被设置。该选项使用户能够选择是否设置 C I/O 断点。C/O 断点
是 C I/O 库函数如 printf 和 scanf 的正常调用所必须的。如果程序不需要执行 CIO 函数,那么 C I/O
断点是不必要的。当 C I/O 代码被装载到 RAM, Code Composer Studio 将设置一个软件中断。然而,
当 C I/Od 代码被载入ROM, Code Composer Studio 使用硬件中断。因为大多数处理器只支持较少数量
的硬件中断,使用哪怕一个都对调试造成极大影响。可以通过在代码段中嵌入一个断点,并将其标签
从 C$$IO$$重命名为 C$$IOE$$的方式,在 C I/O 代码装载到 ROM时避免使用硬件中断。
. 装载时不设置程序结束断点缺省情况下,如果程序被连接到 TI 实时库(rts*.lib),程序装时将会
被自动设置一个程序结束断点(C$$EXIT)。该选项允许用户选择是否设置程序结束断点。程序结束断
点中止处理器的工作,使得程序不再往下执行。如果你的程序需要执行无限次数循环时,程序结束断
点将是不必要的。如果程序结束断点代码载入 RAM, CCS 将设置一个软件中断。然而,当代码被载入
ROM 时,CCS 将设置一个硬件中断。因为大多数处理器只支持较小数量的硬件中断,使用哪怕一
个都会对调试造成极大影响。可以通过在代码段中嵌入一个断点,并将其标签从 C$$IO$$重命名为
C$$IOE$$的方式,在程序结束代码装载到 ROM 时避免使用硬件中断。
. 装载新程序时禁用所有断点 激活该选项将会在装载新程序前移除所有存在的断点。
. 装载工程时打开关联的工程 缺省时,如果程序有主工程关联的子工程,所有子工程将随主工
程一同打开。如果禁用该选项,主工程打开时子工程不会被打开。
. 装载工程时不扫描文件关联性 为了能在工程增量建立方式下确定哪些文件必须被编译,工程必
须对于每个源文件保存一个文件关联列表。每当建立一个工程时,关联树就会被创建。为了创建关联
树,所有工程列表中的源文件将被循环的扫描用以寻找 #include, include, 以及.copy directives, 并且每
个包含的文件名称将被添加到工程列表中。缺省状态下,当工程是打开的,所有文件中的工程都会被
扫描相关性。如果该选项禁用,它就不会在代开工程时自动扫描相关性,而且打开工程的速度也将变
快。
1.14 反汇编类型
. 在反汇编窗口中有可改变信息方式的选择设置。反汇编类型选择对话框允许你为调试部分选择特
定的调试类型。
反汇编类型选择设置步骤:
. Option->Disassembly Style,或者在反汇编窗口中右击并选择
Properties->Disassembly Options。
. 在反汇编类型选择对话框中输入你的选择。
点击 OK,反汇编窗口内的内容会按照设置立刻更新。
1.2 仿真(Simulation)
. 为了使仿真器按照实际硬件目标的方式运行,你可以设置内存映射(1.3 部分),管脚连接(1.4
部分),或者端口连接(1.5 部分)。
1.3 内存映射(Memory Mapping)
. 内存映射关系可以告诉调试器它能访问内存的哪个区域。内存映射关系可以随具体应用而改变。
. 当一个内存映射关系定义并且内存映射建立,调试器按照内存映射关系挨个检查内存入口。调试
器不能进入被设置为保护状态的内存区域。
. 调试器按照软件内存映射关系检查内存入口而非按照硬件。调试器并不能阻止你的程序访问不存
在的存储区域。
1.3.1 仿真器内存映射(Memory Mapping with Simulation)
. 仿真器利用预先定义的内存映射范围来作为被仿真的 DSP 硬件目标的内存设置。内存映射关系在
一定程度上可以改变但是并不推荐这样做,因为仿真器的运行可能被大量有效的内存范围的改变而受
影响。
1.3.2 利用调试器的内存映射(Memory Mapping Using the Debugger)
. 尽管在调试时可以改变内存映射关系,但是这是不方便的,因为使用者一般在调试前设定好内存
映射关系,然后应用于其它所有的调试工作中。
添加一个新的内存映射范围步骤:
1. 选择 Option->Memory Map。
2. 如果你的实际或仿真目标内存设置支持多类型,对于每一个类型内存映射关系设置对话框包含一
个单独的标签(例如 Program,Data,and I/O)。选择你想改变的内存类型的标签。对于只含有一种类型内
存的处理器,标签选择栏不出现。内存映射对话框提供以下选择:
. 激活内存映射(Enable Memory Mapping) 保证内存映射关系激活箱核查无误,否则调试器认
为你运行目标上的所有可设地址的内存(RAM)都是有效的。
. 起始地址(Starting Address) 在起始地址输入框中输入新内存范围的起始地址。
. 长度(Length) 在长度输入框中输入新内存范围的长度。
. 属性(Attributes)在属性框中选择新内存范围的特性:读/写。
. 入口大小(Access Size(bits)) 指定你的目标处理器的入口大小。你可以从下拉菜单中选择一个
入口大小,也可以在入口大小框中键入一个数值。对于只支持一个入
口大小的处理器没必要指定入口大小。
. 可变存储器(Volatile Memory) 一般的,一个写通道包括读,修改和写操作。当可变内存设定在
某个存储区域内,只通过一个写操作就可以访问那个区域。
. 内存映射清单(Memory Map List) 显示内存映射关系的清单。
. 添加(Add) 添加一个新的内存范围到内存映射关系清单中。
. 删除(Delete) 在内存映射关系清单中,选择要删除的内存映射范围并单击 Delete按钮。你还可
以通过将属性改为 None-No Memory/Protected 删除存在的内存映射范围,这也就是说你对此内存区域
既不能读也不能写。
. 重置(Reset) 将内存映射范围重设为默认数值。
3. 单击 Done 保存你的设置。
. 调试器允许你进入覆盖了原内存的新内存区域。新内存假定设为有效状态的话,被覆盖的区域的
属性也会随之改变。
. 在你定义一个内存映射关系后,你可能想修改它的读/写属性,你可以通过在原来起始地址和大小
基础上定义一个新的内存映射并单击 Add 按钮来实现。调试器将会将原来的属
性修改为新定义的属性。
1.3.3 用 GEL 定义内存映射(Defining Memory Map with GEL)
. 内存映射也可以通过通用扩展语言(general extension language (GEL) 嵌入函数方式来定义。GEL
提供一整套内存映射函数。你可以通过在一个GEL文件中加入内存映射函数并在开始中运行这个函数
很容易的建立一个内存映射。(参看1)。
. 当你第一次调用Code Composer Studio IDE,内存映射会关闭。你可以进入任何内存区域而不受内
存映射的限制。如果你调用将可选择GEL文件名作为指定参数的Code ComposerStudio,GEL文件会自
动下载。如果这个文件包括GEL函数StartUp(),这个文件中的GEL函数将被执行。你可以根据环境在
文件中指定GEL映射函数来自动定义内存映射。使用下面的GEL函数来定义你的内存映射:
GEL_MapAdd()函数定义了一个有效的内存范围并指定了它的读/写属性。下面是一个例
子,利用GEL文件定义两个长度为0xF000且可读写的内存映射。
StartUp()
{
GEL_MapOn();
GEL_MapReset();
GEL_MapAdd(0, 0, 0xF000, 1, 1);
GEL_MapAdd(0, 1, 0xF000, 1, 1);
}
当你设置好你的内存映射,选择Option->Memory Map去查看内存映射情况。
1.4 引脚连接(Pin Connect)
引脚连接工具使你可以指定外部中断发生的时间间隔。
仿真外部中断:
1. 创建一个数据文件指定中断间隔。
2. 从工具菜单中选择Pin Connect。
3. 选择Pin name并单击Connect。
4. 下载你的程序。
运行程序。
关于Pin Connect的详细信息,可查阅在线帮助中的Pin Connect主题:
Help→Contents→Debugging→Analysis Tools for Debugging→Pin Connect。
图5-3 引脚连接工具
1.5 端口连接(Port Connect)
你可以利用端口连接工具通过内存地址来访问文件。通过连接到内存(端口 )地址,你可以将数据
导出或写入文件。
连接一个内存(端口)地址到一个数据文件,按照以下步骤:
1. 从工具菜单中选择Port Connect,显示Port Connect窗口并开始Port Connect工具。
2. 点击Connect按钮打开Connect对话框。
3. 在Port Address区域输入内存地址。这个参数是一个绝对地址,可以是任何C语言表达,C函数名
称或者是汇编语言标签。如果你想指定一个hex地址,一定要以0x开头,否则它将被当作十进制地址
对待。
4. 在Length区域,输入内存范围的长度。长度可以是任何C语言表达。
在Page区域(仅C5000有),选择地址占据的内存的类型(program or I/O )。对于程序内存选择
Prog,对于I/O则选择I/O。
6. 在Type区域,选择Write还是Read按钮取决于你想将数据写入文件还是读出文件。
7. 点击OK显示Open Port File窗口。
8. 选择你想连接的数据文件并点击Open。
9. 选择No Rewind特性,防止到达文件结尾end-of-file(EOF)时文件重绕,在EOF后的读访问,数据
0xFFFFFFFF被读入并且文件指针保持不变。文件可通过相关联的内存地址使用汇编语言来进行访问,
任何内存地址可以连接到文件。一个最大的单输入输出文件可以连接到一个单内存地址,多个地址可
以连接到同一个文件。
关于Port Connect的详细信息,可以参阅在线帮助中的Port Connect主题:
Help→Contents→Debugging→Analysis Tools for Debugging→Port Connect。
1.6 程序加载(Program Load)
在执行程序前,必须将由编译程序所产生的 COFF 文件(.out)载入到真实的或仿真的目标芯片中。
将程序的代码的数据分别载入到 COFF 文件中所注释的目标地址中。把字符载入字符表中并保存到主
机中的调试器中。字符根据 COFF 文件中的注释载入到程序和数据地址中。载入一个 COFF 文件可
以通过选择文件 File->Load Program 并使用载入程序对话框来选择所需要的 COFF 文件。
1.6.1 只载入字符信息
在调试器环境下工作时(该调试器无法或不需要载入目标代码,例如代码在只读存储器的时候),
只载入字符信息是十分有效的。
载入字符信息可以通过选择文件 File->Load Symbols->Load Symbols Only from the main menu
并使用载入字符对话框来选择所需要的 COFF 文件。
调试器会将主机上保存的字符表中的先前已调用过的字符删除。然后字符表将载入字符文件中的
字符。字符根据字符文件中的注释载入到代码和数据地址中。这个命令不会修改存储器或者设置程序
入口点。
你也可以指定代码的偏移量和数据的偏移量,这样调试器就可以在指定的字符文件中应用每一个
字符。例如,假如你有一个可执行的字符文件,这个字符文件包含初始化地址为0x100 的代码地址以
及初始化地址为 0x1000 的数据地址。然而当程序载入目标芯片中时,相应的代码初始地址为
0x500100 以及相应的数据初始地址为 0x501000。
指定代码和数据的偏移量,可以先选择 File ->Load symbols->Load Symols with offsets from the main
menu 并使用载入字符对话框来选择所需要的 COFF 文件。一旦一个COFF 文件选定后,一个
新增的载入带偏移量的字符对话框将会显示出来,并可以在对话框中输入实际的代码和数据的初始地
址。
图 5-6 数据地址
1.6.2 只增加字符信息
字符信息也可以附加到现存的字符表中。这个命令与载入字符命有所不同,因为这个命令不会在
载入新的字符前清除现存的字符表。
增添字符信息的步骤如下:File→Load Symbols→Load Symbols with Offsets,或者不带偏移量的
File→Load Symbols→Load Symbols Only,,与上述载入字符的步骤相似。
2 基础调试(Basic Debugging)
在CCS集成系统中有几个组件在进行基础调试中是非常重要的。以下图表显示出一系列在CCS中
调试时使用的图标。如果这些图标在工具栏中无法显示,请选择View→Debug Toolbars→ASM/Source
Stepping。在这个调试工具栏选项表中,你可以看到许多调试工具的列表,并且你可以将想要的调试工
具设置为可视。在菜单栏中,可视的工具名字旁有个校验标记。
图 5-7 运行和调试所用到的一些工具栏图标
2.1 运行/单步调试(Running/Stepping)
2.1.1 运行
运行一个程序,首先在集成环境菜单中的调试项目中选择合适的命令。如果目标控制工具栏是可
视的,运行图标会显示在左边的垂直工具栏中。如果这些图标并没有显示出来,可以选择 View→Debug
Toolbars→Target Control。
可以运用这些命令来运行程序:
. 主程序(Main) 可以通过先择 Debug→Go Main,来开始对主程序的调试。这个执行命令将会执
行主程序函数。
. 运行(Run) 在执行停止后,可以通过点击 Run 按钮来继续运行程序。
. 运行到光标处(Run to Cursor) 如果想要程序运行到一个指定的位置,可以先把光标移到该位置,
然后按下这个按键。
. 驱动(Animate) 这个执行命令将一直运行程序直到运行到断点处。在断点处,执行停止并且将更
新所有与任何试探点(probe point)没有联系的窗口。试探点(probe point)停止执行并更新所有图表
及与之有关的窗口,然后继续运行程序。按下这个按键就可以驱动(Animate)执行程序。还可以在选
项菜单中选择用户化来修改驱动(Animate)的速度。
. 停止(Halt) 最后,可以在任意时候按下停止按键来终止程序执行。
2.1.2 单步调试
只有在执行程序的时候源程序和汇编程序的单步调试才可以使用。源程序的单步调试是通过单步
执行源程序编辑器中所显示的代码行,而汇编程序的单步调试是通过单步执行反汇编窗口中显示的指
令行。通过 View→Mixed Source/ASM 来切换源程序/汇编程序混合模式,可以同时查看源代码的汇编
代码。执行一个单步调试命令,先在工具栏中选择合适单步调试图标。另一种方法是先选择
Debug→Assembly/Source Stepping(然后选择合适的命令)。
单步调试共有三种:
. 单步调试或者只执行一个表达式然后就终止程序执行。
. 跳过整个函数的执行然后当函数返回时终止程序。
. 跳出执行当前的子程序并返回到调用函数入口。当返回到调用函数入口时,程序就终止了。
2.1.3 使用 PDM 来进行多处理器广播命令
当使用并行调试管理器(PDM)时,所有的运行/单步调试命令都会广播到当前处理器组中所有目
标处理器。如果设备驱动支持同步操作,以下每个命令都可以同时同步到每个处理器中。
. 使用锁定单步调试(Step into) 来单步调试所有还没准备好运行的处理器。
. 使用跳过单步调试(Step over)来跳过所有还没准备好运行的处理器。
. 如果所有处理器都在子程序中,可以使用跳出执行(Step out)来跳出执行所有还没准备好运行的处理
器中的命令。
. 运行命令发出全局运行命令运行所有还没准备好运行的处理器。
. 停止命令(Halt) 将同时终止所有运行的处理器程序。
. 驱动命令(Animate)开始驱动所有还没准备好运行的处理器。
. 在从当前 PC 位置中执行载入程序之前,自由运行(Run free)将禁用所有断点包括所有试探点。
2.2 断点(Breakpoints)
对于任意调试器,断点都是十分重要的组成部分。断点会停止程序的执行。当程序停止时,可以
检查程序的状态,检查或修改变量,检查调用堆栈等等。断点可以设置在编辑窗口中人任意一行源代
码中或者设置在反汇编窗口的任意一个反汇编指令上。在设置完一个断点后,可以启用断点也可以禁
用断点。
如果一个断点设置在一行源程序代码行上,必须有一行反汇编代码行与之相对应。在打开编译器
优化选项后,许多源程序代码行就不再允许设置断点了。可以在编辑窗口中的混合模式下查看可以设
置断点的代码行。
注意:
CCS 会在源程序窗口中重新定位断点到一个有效代码行上并设置断点图标在该代码行
的边缘空白处。如果一行允许设置断点的代码行无法设置断点,系统将会以消息窗形式自动
报错。
注意:
只要程序执行到任意一个试探点时,CCS 将会终止目标程序。当执行停止时,将会自动
更新任何与试探点有关的窗口或输出设备。因此,如果使用试探点,目标应用程序也许就不
能实现实时运行的效果。这个开发阶段,就要测试下所使用的算法。然后再使用 RTDX 和
DSP/BIOS 来分析实时效果。
2.2.1 软件断点
可以在任意一个反汇编窗口或者含有 C/C++源代码的文档窗口设置断点。只要断点设置
的位置合适,对于断点的数量便没有限制。软件断点通过改变目标程序使之在需要的位置增
加一条断点指令。
设置软件断点的方法:
1. 在一个文档窗口或者反汇编窗口,移动指针到你想要设置断点的那一行。
2. 当你在文档窗口设置断点时,只需在选定行的前面的页边空白处迅速双击即可。若是在反汇编窗
口,则只需在选定行双击。
在选定行的页边空白处的一个实心红点即为断点标志,它表示在所需要的位置已经设定了一个断
点。
我们也可以使用切换断点命令和切换断点按钮来迅速的设置和清楚断点。
1. 在一个文档窗口或者反汇编窗口,移动指针到你想要设置断点的那一行。
2. 点击鼠标右键并选择切换断点,或者在软件工具栏中点击切换断点标志按钮。
2.2.2 硬件断点
硬件断点与软件断点不同的是它们并不改变目标程序,而是利用芯片上可以利用的硬件资源。硬
件中断的用途是在只读存储器或者存储进程中设置断点,而不是获取指令。我们可以在特定的存储器
读、存储器写或者存储器读写中设置断点。存储器存取断点并不会在源程序或者存储器窗口中显示出
来。你可以使用的硬件断点的数量取决于你所采用的 DSP 型号。硬件断点也有计数的功能,它决定了
在断点产生前,该处指令已经运行的次数。如果计数为 1,则每次到该位置则产生断点。但是,在仿
真目标上不能实现硬件断点。
设置硬件断点的方法:
1. 选择 Debug->Breakpoints。在选择断点这一栏后,便会出现 Break/Probe Points对话框。
2. 在 Breakpoint type 一栏,选择 H/W Break 作为指令获取断点,或者在特定位置选择 Break on
<bus> <Read|Write|R/W>作为存储读取断点。
3. 在程序或存储器中你想设置断点的某个位置,按以下方法中的一种操作:- 对于一个绝对地
址,你可以输入任意 C 语言中的表达方式:C 的函数名或者一个标志符号。- 输入断点的位置基
于你的 C 源文件。当你不知道 C 指令在可执行文件中的位置时,这就很方便了。在基于 C 源文件
的位置输入的格式是:文件名 第几行 总行数。
4. 在计数这一栏,输入断点产生前,该处指令需要运行的次数。如果计数设为 1,则
每次到该位置便产生断点。
点击添加按钮可以产生一个新的断点。这样便可创造一个新的断点并对其激活。
6. 点击 OK。
2.3 探针点(Probe Points)
2.3.1 探针点的作用
探针点从你的个人电脑上的文件中读取数据。它们有助于算法的开发。你可以用它们来
达到以下目的:
. 将主机的一个文件中的输入数据转移到目标的缓冲器中以备算法使用。
. 将目标的缓冲器中的输出数据转移到主机的一个文件中以备分析。
. 运用数据升级一个窗口(例如图表)。
2.3.2 探针点与断点之间的不同
探针点和断点都会使目标停止并完成某些动作。然而,它们在以下几方面不同:
. 探针点使目标立即停止,执行一个单一的行动然后便恢复目标的执行。
. 断点会使 CPU 一直停止直到手动恢复执行。并且断点会使所有打开的窗口保持最新。
. 试探点允许文件的自动输入和输出,而断点则不允许。
2.3.3 运用试探点转移电脑文件中的数据到一个目标
在这一部分,我们将展示如何运用一个试探点将电脑文件中的内容转移到目标中,并用
于数据测试。当试探点到来时,目标程序也会运用断点使所有的窗口保持最新。
1. 选择 File->Load Program。选择一个文件,并打开。
2. 在 Project View 中选择要打开的 C 程序源文件并双击打开。
3. 将光标移动到主函数中你想要添加试探点的那一行。
4. 点击 Toggle Software Probe Point 按钮。
在文件菜单中,选择 File I/O.对话框,然后你便可选择输入或输出文件。
6. 在文件输入这一栏,点击 Add 添加文件。
7. 浏览到你的文件夹,选择一个数据文件并打开,便会出现一个关于该数据文件的控制窗口。当你
运行这个程序时,在数据文件内部可以利用这个窗口来使程序启动、停止、重运行或者快进。
8. 在 File I/O 中,改变地址和长度值。并且,将 Wrap Around 这一栏打上勾。地址这一栏表明把文
件中的数据放到哪里。Length 这一栏表明当试探点到来时,已经从数据文件中读取了多少个样本。
Wrap Around 选项使得当到达文件的末尾时又开始从文件的开头读取数据,如此便可把数据文件当作一
段连续的数据流。
9. 点击Add Probe Point以显示Break/Probe Points对话框中的Probe Points 一栏。
10. 在Probe point list中,选择你之前创造的试探点。
11. 在Connect To field中,点击向下的箭头并从列表中选择一个数据文件。
12. 点击Replace。那么试探点列表便会改变并显示该点已经关联到正弦数据文件。
13. 点击OK。那么文件输入/输出对话框便会显示该文件已经连接到一个试探点。
14. 点击OK,从而选择文件输入/输出对话框。
2.4 观察窗口(Watch Window)
2.4.1 使用观察窗口来跟踪一个变量的值
调试一个程序的时候,能了解变量的值在程序执行时是如何变化的,这是非常有用的。观察窗口
允许用户观察局部变量和全局变量还有 C/C+ +表达式的值。如果想知道观察窗口的详细资料,参看关
于观察窗口主题的在线帮助:Help→Contents→Debugging→ViewingDebug Information→Watch Window。
打开观察窗口:
1. 选择 View→Watch Window,或者点击观察工具栏上的观察窗口图标按钮。观察到窗口 包含两个
统计表:Watch Locals 和 Watch 1。
-在 Watch Locals 统计表中,调试器自动显示当前正在执行函数的局部变量的名称、值的大小、类型和
基的选择(Radix option)。
-在 Watch 1 统计表中,调试器显示局部变量、全局变量和用户指定表达式的名称、
值的大小、类型和基的选择(Radix option)。
2. 选择 File→Load Program。
3. 双击在Project View 中的filename.c 文件(filename为文件名)。
4. 把光标移动到允许打断点的行。
点击 Toggle Breakpoint 工具栏按钮或按下F9。被选择的页面空白处会显示出断点已经建立好了(红
色图标)。
6. 选择View->Watch Window。在窗口的右下角会出现一个单独的区域,在运行过程中这个区域显示
的就是被观察的变量的值。默认情况下,显示的是Watch Locals统计表,显示内容是执行过的函数的局
部变量的值。
7. 如果不是在主函数,选择Debug->Go Main。
8. 选择Debug->Run,,或按下F5, 或按下运行图标。观察窗口会更新局部的值。
9. 选择 Watch 1 统计表.
10. 在Name column点击Expression图标并且输入需要观察的变量的名称。
11. 点击窗口的空白处可以保存所做的改动。值会立即显示出来,就像下面这个例子。
12. 点击 Step Over 工具栏按钮或按下 F10 来跳过对要观察的变量的调用。除了观察一个简单的变量
的值之外,用户还可以观察一个结构体中的元素的值。
2.4.2 利用观察窗口来观察一个结构体中元素的值
用观察窗口来观察一个结构体中元素的值:
1. 选择Watch 1 统计表。
2. 点击Name 栏中表达式图表并且输入需要观察的表达式的名称。
,提供专业的 DSP 技术培训,技术服务,项目合作,外包承接等业务!
3. 点击窗口的空白处用来保存所做的改动。
4. 一旦点击“+”标记,该目录会展开并列出结构体中所有的元素以及他们对应的值。
(所示的连接地址可能会有所不同。 )
双击在结构提中任意一个元素的值,就可以对这个值进行编辑。
6. 改变这个变量的值。
需要注意的是在观察窗口中的值如果发生了改变,这个值的颜色也会变成红色用来表示它已经被
手动的进行了修改。
2.5 内存窗口(Memory Window)
内存窗口允许用户观察由指定地址开始的存储单元中的内容。 用户可以通过选项对内存窗口的
显示进行格式化,也可以编辑被选择的存储单元的内容。
可以在内存窗口选项对话框中定义内存窗口不同的特性。
该对话框提供了以下内存窗口选项:
. Title 标题 为内存窗口输入一个有意义的名字。当打开内存窗口时,这个名字会显示在标题栏
上。当有多个内存窗口打开时,标题会起到十分重要的作用。
. Address 地址 输入需要观察的存储单元的起始地址。
. Track Expression 跟踪表达式 点击这个选项会使内存窗口自动地重新评估并且改变它基于与起
始地址相关联的表达式的起始地址。当目标停止,重新启动,或改变其符号时,它将重新评估并重新
配置本身。举例来说,如果在 SP 中打开一个内存窗口,当单步执行代码、加载一个新的程序或者修
正寄存器本身时,内存窗口将不断地重新配置。
. Q 值 用户可以用 Q 值来显示整数。这个值将整数值表示成更精确的二进制值。小数点被插到
二进制值中,最低有效位(LSB) 产生的偏移量由 Q 值决定,如下所示:
New_integer_value = integer / (2^(Q value))xx 的Q值表示一个有符号的2次方余整数( 2s complement
integer) ,这个数的小数点由最低有效位 (LSB) 转移到xx位置 。
. Format 格式 从下拉菜单中选择内存显示的格式。关于不同格式的更多信息可以参看在线帮
助。
. Enable Reference Buffer 参考缓冲器有效 为指定的内存区域保存一个快照,可以用来为后面的比
较做准备。.
. Start Address 起始地址 输入想要保存在参考缓冲器中的存储单元的起始地址。这个区域只有
当“激活参考缓冲器”选择以后才会激活。
. End Address 终止地址 输入想要保存在参考缓冲器中的存储单元的终止地址。这个区域只有
当选“激活参考缓冲器”择以后才会激活。
. Update Reference Buffer Automatically 自动更新参考缓冲器 选择这个复选框可以自动地用指定地
址区域的当前内存内容覆盖参考缓冲器的内容。如果选择该选项,只要内存窗口更新,参考缓冲器就
会更新(例如,当选择了更新窗口,打了断点,或者对目标的执行被终止时)。如果该复选框没有被选
中,参考缓冲器的内容就不会改变。这个选项只有当选择了“Enable Reference Buffer”以后才会激活。
. Bypass Cache 旁路高速缓存 该选项使得内存总是从物理内存中读取内存内容。通常情况下,
如果内存内容在高速缓存中,内存的返回值会是从高速缓存中得到的值,而不是从物理内存中得到的。
如果这个选项被激活,CCS(Code Composer Studio)将忽略或者绕过高速缓存的内容。. Highlight
Cache Differences 突出高速缓存的差异 当高速缓存的值和物理值不一致时,这个选项突出强调了的
存储单元的值。也会用色彩来加强突出高速缓存的差异。选择 Option→Customize→Color 并且选择
在Screen Element 下拉框中的Cache Bypass Differences选项。参看关于寄存器窗口的在线帮助部分可
以了解跟详细的信息。
2.6 寄存器窗口(Register Window)
用户可以在寄存器窗口观察并编辑选中的不同寄存器的内容。
要访问寄存器窗口,选择View→Registers并且选择需要观察/编辑的寄存器组。 如果要访问寄
存器的内容,选择Edit→Edit Register, 或者从寄存器窗口双击一个寄存器, 或者右击一个寄存器并
选择Edit Register(编辑寄存器)。
2.7 反汇编模式/混合模式( Disassembly/Mixed Mode)
2.7.1 返汇编模式 Disassembly Mode
当 你 加 载 程 序 到 实 际 的 或 模 拟 的 目 标 板 时 , 调 试 器 会 自 动 打 开 一
个 反 汇 编 窗 口(disassembly window).
反汇编窗口显示反汇编的指令和符号信息以供调试需要。反汇编与汇编过程相反,并允许内存的
内容以汇编语言代码的形式显示。符号信息包括符号和代表目标板上地址或值的文字数字式字符串。
如果以单步命令运行程序,程序计数器将跟随这些指令向下执行。
2.7.2 混合模式 Mixed Mode
除了在分解窗口里查看分解的指令,调试器允许以 C 源代码和分解代码交叉显示方式察看。点击
View.Mixed Source/ASM, 或在源文件窗口中右击,根据你目前的模式选择Mixed Mode 或 Source
Mode。
2.8 调用堆栈(Call Stack)
可用调用堆栈窗口察看使程序运行到目前位置的函数调用。要显示调用堆栈窗口:
1. 选择 View.Call Stack,或单击调试工具条上的 View Stack 按钮。
2. 双击调用堆栈窗口中列出的一个函数。包含该函数的源代码将显示在一个文档窗口中。指针置于
函数内的当前行。一旦在调用堆栈窗口中选择了某个函数,你可以查看该函数内的局部变量。调用堆
栈功能只在 C 程序中使用。调用函数由扫描(walking through)运行时栈里的帧指针链决定。程序必
须有一个堆栈段和一个主函数;否则,调用堆栈是不能显示 C 源代码的。另外还要注意,调用堆
栈窗口只显示输出的 100 行,100 行以外的行都忽略不显示。
2.9 符号浏览器(Symbol Brower)
符号浏览窗口(Figure 5-21)能为加载的 COFF 输出文件(*.out)显示 5 个标签窗口(Tabbed
windows):
. 所有相关的文件
. 函数
. 全局变量
. 类型
. 标记(labels)
每个标签窗口包含代表各种符号的节点。节点前的加号(+)表示此节点可被进一步展开。可单击
加号展开节点。展开的节点前有一个负号(-),可单击负号隐藏该节点的内容。要打开符号浏览窗口,
选择 View.Symbol Browser。
2.10 命令窗口(Command Window)
命令窗口使你可以依据 TI 调试器的命令语法对调试器指定命令。许多的命令接受此C表达式语
法为参数。这使得指令相对较小却仍足够强大。由于评测某些类型的 C 表达式会影响既有的值,你可
以使用相同的命令来显示或改变某个值。
要打开命令窗口,选择 Tool.Command Window。
更多关于命令窗口的信息,请参看在线帮助提供的 Command Window 项。
3 高级的调试特征(Advanced Debugging Features)
3.1 高级事件触发(Advanced Event Triggering)
高级事件触发(AET)使用两个工具:事件分析(Event Analysis)和事件序列器(Event Sequencer)来简化
硬件分析。
事件分析采用了很简单的界面来配置一般的硬件调试任务。你可以用一个上下文菜单和一个拖放
动作就很方便的设置断点、激活点(action points)和计数器。可以通过工具菜单或在源文件中右击进入事
件分析(Event Analysis)。
事件序列器在你的目标程序里寻找状态标志(conditions),当探测到状态标志时就启动指定的动作
(specific actions)。CPU暂停时,你可以定义状态标志和动作,然后再次运行你的目标程序。序列程序
会寻找指定的状态,并执行被请求的动作。
3.1.1 事件分析 (Event Analysis)
使用事件分析可以执行下列任务:
. 设置断点
—硬件断点
—带计数的硬件断点
—连锁断点
—全局硬件断点
. 设置动态点/观察点
—数据动态点
—程序动态点
—观察点
—带数据的观察点
. 设置计数器
—数据存取计数器(Data access counter)
—剖析计数器(Profile counter)
—看门狗计时器
——般计数器
. 其它
—标记基准点(Benchmark to here)
—硬件仿真引脚配置(Emulation pin configuration)
更多关于事件分析工具的信息,请访问在线帮助提供的事件分析主题。
为了使用事件分析工具来配置任务,必须为集成有片上分析特性(on-chip analysis features)的目标处
理机配置CCS IDE。你可以通过从工具菜单选择或在源文件中右击来使用事件分析。一旦你配置好一
个任务,它就被激活了,当你在目标板上运行代码时,它会执行分析任务。更多关于如何激活和禁用
一个已经配置好的任务,请访问高级事件控制的在线帮助。
1. 选择Tools→Advanced Event Triggering→Event Analysis查看事件分析窗口。
图5-23事件分析窗口
2. 在事件分析窗口里右击,选择Event Triggering->Job Type->Job。任务的菜单被动态建立并取决于目
标的配置。若你的目标板上不支持某个任务,这个任务将显示灰色。
3. 在Job对话框里输入信息。
4. 点击Apply保存你的任务。
3.1.2 事件序列器( Event Sequencer)
事件序列器在你的目标程序里寻找状态标志(conditions),当探测到状态标志时就启动指定的动作。
CPU暂停时,你可以定义状态标志和动作,然后再次运行你的目标程序。序列程序会寻找指定的状态,
并执行被请求的动作。
为了使用事件序列器,必须为集成有片上分析特性(on-chip analysis features)的目标处理机配置CCS
IDE。你可以通过从工具菜单选择来使用事件序列器。一旦你创建好一个事件序列器程序,它就被激活
了,当你在目标板上运行代码时,它会执行分析。更多关于创建一个事件序列器程序,请访问高级事
件控制的在线帮助。
激活事件序列器:
1. 选择Tools→Advanced Event Triggering→Event Sequencer。
2. 在 Event Sequencer 窗口中右击或者使用 Event Sequencer 工具栏的按钮创建一个次序器程序。
4、实时调试(Real-Time Debugging)
传统的调试方法需要(停止模式)需要程序员完全停止他们的系统,这将停止所有的进程而且阻
止了中断的响应。只要系统/应用程序没有实时要求,停止模式可以用于调试。然而为了更好的测量你
应用程序的实时系统行为,代码编译集成环境平台(CCS IDE)为你提供了几种方式,包括实时模式(4.1
节)、强制实时模式(4.2)、实时数据交换模式(4.3)。
4.1 实时模式(Real-Time Mode)
实时模式允许当目标系统暂停在后台程序里时,可以响应前台代码里时间紧急的中断。时间紧急
的中断是一类在后台程序暂停时必须响应的中断。例如:时间紧急的中断可能是马达控制器和高速的
定时器的中断。你可以在多处挂起程序,这样允许你在响应一个紧急时间中断时打断去响应别的中断。
激活实时模式调试:
1. 你需要配置中断和设置断点,为实时模式调试做好准备,看网上的关于实时调试帮助以获得更多
的信息。选择 Debug→Real-time Mode,控制框的底部状态条此时显示温和实时模式。
2. 通过选择 View→Real-Time Refresh Options,配置实时刷新选项。第一个选项将确定观察窗多久更
新一次。选择全局连续刷新选择框,将连续的刷新所有的窗口,包括内存、图表和观察窗。如只要连
续更新部分窗口,不选择全局框,在观察窗列表里选择相应的框即可。
3. 点击 OK 关闭对话框。
4. 选择 View→Registers→Core Registers 来打开主寄存器,调试中断激活寄存器(DIER)在列表里
可见,DIER 代表了一个单一中断、一类特殊设置的中断、所有的通过中断激活寄存器(IER)选择的作
为实时模式的中断,DIER 反映了特殊的 IER。
右击寄存器,选择编辑寄存器。
6. 输入新的寄存器值以表示实时中断。
7. 选择 Done 关闭寄存器编辑对话框。
8. CCS IDE 已经配置好实时模式调试。
4.2 强制实时模式(Rude Real-Time Mode)
高优先级的中断,或者其它的代码段可以是非常时间紧急性,执行花费的周期数要最小。这意味
着调试行为(包括执行控制和访问寄存器和内存)可能被禁止,在一些代码段或特殊的机器状态下。
在默认的实时模式下,控制器放弃了特权来运行温和模式。这样调试行为将等待一个合适的时间延迟,
不会闯入调试敏感的窗口。
然而,假如不能获得调试 action-senstive 的窗口,调试命令(包括执行控制和访问寄存器和内存)
将要失败。为了使调试能再次获得控制权,必须把实时调试从温和模式改为强制模式。在强制实时模
式下,特权的拥有允许调试行为忽略任何阻止调试进入的手段,并且没有延迟的成功执行。你也可以
在进入强制实时模式之前不调试响应时间迫切的代码。
为激活强制实时模式,执行下面中的一个:
. 当调试命令失败时,从显示窗口中选择执行强制模式。
. 当实时模式激活后,在调试菜单里选择激活强制实时模式。当强制实时模式激活后,主程序窗口
底部的状态栏显示强制实时模式。要取消强制模式,在调试菜单里撤销激活强制模式按钮即可。状态
栏此刻显示温和实时模式。假如激活了强制实时模式,且暂停了 CPU,可能会发生这种即时调试被
阻止了,CPU还是处于停止状态。这可能发生在一些时间紧急的中断服务程序里。这阻止了 CPU 在
合时的时间里完成中断服务程序,因为在对断点响应之前,CPU 不能运行。为避免此问题,必须撤消
强制模式返回至温和模式。通过选择 Debugging→Real Time Debugging 的网上帮助,了解更多的该主
题的信息。
4.3 实时数据交换(RTDX)
DSP/BIOS 实时分析工具使用实时数据交换(RTDX)连接以实时获得或监测目标系统的数据。
你可以利用 RTDX 连接和 RTDX API 库,创建自己的同 DSP 目标系统通信的用户接口。
RTDX 在没有干扰目标系统的程序下,在主机和目标系统之间传送数据。这个双向的通信通路提
供了主机和正在运行程序的目标系统之间数据采集和发送。从目标系统上采集的数据可以被分析和显
示在主机上。可以在不停止目标系统的程序下,用主机调整其参数。RDTX也使主机能够提供对目标系
统程序和算法的数据仿真。
RTDX 包括主机部分和目标系统部分,一个小的 RTDX 软件库运行在目标系统程序里,目标系统
程序调用该库的 API 函数来发送或接收数据。该库使用基于扫描的仿真器,通过JTAG 口接收或发
送数据至主机。目标系统程序执行的同时,数据实时发送到主机。在主机平台上,一个 RTDX 主机库
和 CCS IDE 连接起来,数据可视化和分析工具通过COM APIs 和 RTDX 通信,获得目标系统数据或
发送数据到 DSP 程序。
主机库支持两种接受数据的方式:连续和非连续。连续模式下,数据仅被 RTDX 主机库简单
缓存起来,没有写入日志文件。连续模式用于开发人员想从目标系统程序里连续获得并显示数据,而
不需要保存数据到日志文件里的场合。非连续模式下,数据写入到主机的日志文件里,该模式用于开
发人员想捕获一定量的数据且保存起来的场合。要获得使用 RTDX 更多的细节,看网上帮助。
4.3.1、RTDX 数据流
RTDX 在主机和目标系统之间建立两通道的数据管道。数据管道由如下图所示的硬件和
软件的结合。
4.3.2、图形化配置 RTDX
RTDX 工具允许图形化配置 RTDX,建立 RTDX 通道,开始 RTDX 诊断。这些工具允许你在传
输数据时候增强 RTDX 函数。
RTDX 拥有三个菜单选项:诊断控制器、配置控制器、通道视图控制器。
诊断控制器:RTDX 提供了 RTDX 诊断控制器来诊断 RTDX 在系统里正常工作与否。诊断器测
试基本的目标系统到主机,主机到目标系统数据传输的函数。
选择Tools→RTDX→Diagnostics Control,打开RTDX诊断控制器。这些测试只有在RTDX
激活才可用。
配置控制器:下面是 RTDX 控制器窗口,它允许你完成下面事:
. 查看当前的 RTDX 配置
. 激活或关闭 RTDX
. 打开 RTDX 配置属性页面,重新配置 RTDX,选择点配置设置属性。
选择 Tools→RTDX→Configuration Control.,打开配置控制器。
通道视图控制器:RTDX 通道视图控制器是一种主动 X 控制器(Active X Control),它
自动检测目标系统声明的通道,并将其加入到可视的列表里。RTDX 通道视图控制器允许你
完成下面事:
. 从可视的列表里删除或增加目标系统声明的通道。
. 激活或关闭该列表里的通道。
选择 Tools→RTDX→Channel Viewer Control,在 CCS IDE 里打开 RTDX 通道视图控
制器,通道视图控制器窗口如下:
点击输入和输出通道标签显示相应通道的列表。输入和输出通道窗口都可以允许你查看、删除、
重加载通道。
选择 Auto-Update,可以自动更新所有通道的数据,即使你没有刷新显示窗口。假如你不使用自动刷新,
手动右击标签,选择刷新,这样也可以刷新所有通道的数据。
注意:要使 RTDX 通道视图控制器接受一个特殊的扩展通道信息,必须要 RTDX 主机
将该通道打开。
4.3.3、发送一个整数至主机
RTDX 的一个基本函数是发送整数到主机。下面步骤提供了目标系统到主机、主机到目标系统的
发送数据过程的概述。传送不同类型的数据所需的命令和细节请参阅网上RTDX帮助。
从目标系统程序发送数据到主机:
1. 准备目标系统程序以获取实时数据,通过插入特殊的 RTDX 参数在程序里,来实时传送数据
到主机。虽然准备目标系统程序的过程对于所有类型的数据传输都一样,但不同的数据类型所需不同
的函数。所以,发送一个整数到主机需要添加特定的函数仅适用传送一个整数的,而不能发送一个整
型数组。
2. 准备主机程序接受数据,为每一个所需的通道初始化相应的 RTDX 目标,打开特定目标的通
道,调用所需的函数。
3. 打开 CCS IDE
4. 加载目标程序到 TI 处理器。
在 Tools—>RTDX—>Configuration Control 选择激活 RTDX。
6. 运行目标系统程序,实时捕获数据,发送到 RTDX 主机库。
7. 运行主机程序处理数据。
8. 欲获的更多使用 RTDX 细节,参考网上 RTDX 帮助。
4.3.4、接受主机数据
主机程序通过往目标系统写数据来传送数据。从主机传送过来的数据首先缓存在 RTDX的主机库
里。在来自目标系统的数据请求到来之前,数据保存在 RTDX 主机库里。一旦 RTDX主机库有足够
多的数据满足请求时,在不干扰目标系统程序运行下将数据写入目标系统。缓存的状态返回至缓存状
态变量里,正值表示在目标系统请求到达之前,RTDX 主机库里缓存的字节数。负值表示目标系统请
求已到达,RTDX 库还缺少的字节数。从主机发送数据到目标系统程序:
1. 准备好目标系统程序的接受数据,通过写一个简单的从主机读数据的 RTDX 目标程序来完
成。
2. 准备好主机发送数据程序,为每个需要的通道初始化一个 RTDX 目标,打开特定目标的通道,
调用其它所需函数。
3. 打开 CCS IDE。
4. 加载目标程序到 TI 处理器。
在 Tools→RTDX→Configuration Control 里选择激活 RTDX。
6. 运行目标系统程序,实时捕获数据,发送到 RTDX 主机库。
7. 运行主机程序处理数据。
8. 欲获的更多使用 RTDX 细节,参考网上 RTDX 帮助。
5 自动控制(Automation for Debug)
1 使用通用扩展语言 (GEL)
像前面讲述的一样,在 CCS 中,GEL 脚本可以用来创建常用的 GEL 菜单和自动运行步骤。4.6.1
节讲述了怎样使用 GEL 的构造函数来自动运行各种工程管理步骤。另外还有许多的 GEL 构造函数,
可以用来自动调试,例如设定断点、向观察窗口增加变量、开始运行、停止和设定输入输出文件 I/O。
2 脚本效用 (Scripting Utility for Debug)
脚本效用(4.6.2 节)也有许多可以自动运行调试步骤的命令。通过在线帮助可以查看关于脚本语言
效用的更多的信息。
6 重置选项(Reset Options)
有时有必要使用 CCS IDE 中的附加命令,实现目标芯片或者仿真器的重置。这些重置命令的适用
性取决于 IDE 与目标芯片的联系。要得到更多的关于目标芯片连接的信息,可以查看 3.1.3 节。
6.1 目标芯片重置(Target Reset)
目标芯片的重置把寄存器的内容初始化为上电状态,同时中断程序的执行。如果目标板没有响应
这条命令,而且用户正在使用以内核为基础的设备驱动,这时 CPU 核可能已经损坏,这种情况下,需
要重载 CPU 内核。 模拟器会初始化所有寄存器的内容到上电状态,这可以参照目标芯片仿真的说明。
要重置目标芯片,选择 debug 的 Reset CPU 选项。
注意:必须把目标芯片做好连接,以确保 Reset CPU 选项可用。
6.2 仿真重置(Emulator Reset)
在硬件重置工作之前,有些处理器需要把处理器调整到功能性的运行状态。在这种情况下,把处
理器返回到功能性状态的唯一方法就是重置仿真器。一个仿真器的重置需要把TRST 管脚激活,使设
备进入到功能性的运行模式。
在CCS 没有连接到目标芯片的时候,重置仿真器的选项可用。重置仿真器时,选择Debug->Reset
Emulator 的选项。在运行仿真器重置时,硬件处于空转状态,此时可以手动进行目标芯片的硬件重置,
方法是:按 reset 按钮,或者选择 Debug-> Reset CPU 选项。但这种方法不适合于 ARM 设备。