CCS5.5 .ccxml仿真配置文件与GEL连接排查指南
CCS5.5 这个版本放在今天算得上古董级了但工业现场里还在跑的 C6748、OMAP-L138、F28335 片子多得是配套的维护和二次开发工作一直没断过。我最近就帮人排查过一个换了新的仿真器之后怎么都连不上目标板的问题折腾了大半天根子不在硬件而在仿真配置文件——老工程里的 .ccxml 文件Target Configuration也就是目标配置/仿真配置文件绑定的还是 XDS510 那套东西换成 XDS100v2 之后既没有重新建文件也没有更新 GEL 路径自然全线失效。这类问题在 CCS5.5 上特别常见因为这个版本的 Target Configuration 机制和后来 CCS6 之后差别不小能搜到的完整中文说明又零散。所以我把这几年的实操经验整理一遍从仿真配置文件到底是个什么东西、怎么从零建一个、每个参数分别管什么到连不上板子时怎么一步步往下排查尽量说透。刚接手老项目的学生、被临时拉来救火的工程师看完应该都能自己动手搞定。1. 先把话说清楚CCS5.5 的仿真配置文件到底管什么1.1 一次连不上目标板的真实场景那次的情况很有代表性。目标板是 OMAP-L138仿真器原来配的是 XDS510USB后来手头的 XDS510 坏了换了一只 XDS100v2。同事想当然地觉得仿真器都是 JTAG插上就能用结果一连就报Error connecting to the target连错误码都没走到就断了。我打开 Target Configurations 视图看了一眼就明白了工程里引用的还是几年前建的omap_l138_xds510.ccxml里面写死了 XDS510 的连接描述。CCS 在启动调试会话时会根据这个文件去加载对应的驱动和器件描述 XML仿真器对不上后面的握手根本没法进行。新建一个omap_l138_xds100v2.ccxml之后第一次连接还是失败报的是 GEL 相关错误。原因是这个老工程的同事当年为了省事在 GEL 文件属性里填的是他自己电脑上的绝对路径机器一换文件就找不到了。把 GEL 改成相对路径或者干脆用 CCS 自带器件目录下的标准 GEL之后一切正常。这两件事说明一个问题仿真配置文件不是点两下就能扔一边的东西它是 CCS 调试会话的入口里面同时绑定了仿真器型号、目标器件型号、GEL 初始化脚本、JTAG 时钟、多核连接顺序这几层信息任何一层错位后面的编译下载全部白搭。1.2 .ccxml 文件内部到底存了什么很多人以为 .ccxml 是个二进制或者加密文件其实它就是一个标准 XML 文本。用记事本打开可以看到三层主要结构顶层是configurations一个文件里可以塞多套配置但通常只有一套。中间层是configuration代表一个具体的连接方案。再往下是instance节点分两类一类描述仿真器连接href 指向connections/目录下的 XML一类描述驱动和器件href 指向drivers/和devices/目录下的 XML。这些 href 都是相对路径基准目录是 CCS 安装目录下的ccs_base/common/targetdb。所以你把整个工程从一台电脑拷到另一台电脑只要 CCS 安装版本一致这些路径通常不会失效——真正会失效的是 GEL 文件的引用因为 GEL 经常被放在工程目录甚至某个人的桌面文件夹里。理解这一点很关键仿真配置文件本身是轻的它不包含任何代码也不包含仿真器的固件它只是一张路由表告诉 CCS去哪找驱动、去哪找器件描述、去哪找初始化脚本。1.3 为什么它比工程文件更值得单独管理工程文件.project、.cproject通常跟着代码库走这没什么争议。但仿真配置文件经常被忽略原因是很多人觉得这是我本机的调试设置跟别人没关系。这个想法在小团队里勉强能用一旦人多了就会出事。一块板子可能配过三只不同的仿真器一个项目组可能有五六个人每个人的 CCS 安装路径还不一样。如果每次调试都靠口头传递你要选 XDS100v2、要选 OMAP-L138、GEL 要用哪个哪个出错的概率非常高。我见过最离谱的一次是有人把 ARM 核和 DSP 核的 GEL 挂反了结果程序跑起来 DDR 一直初始化失败查了两天才发现问题出在仿真配置上。所以我的建议是把 .ccxml 当成工程的一部分纳入版本管理放在工程的targetConfigs目录下命名规则带上器件和仿真器信息。这样任何人拉下代码打开 CCS、选一下配置文件就能直接连板子。这一条看似简单但能省掉的沟通成本相当可观。2. 从零建一个可用的仿真配置文件2.1 打开配置编辑器的三条路径在 CCS5.5 里新建仿真配置文件有三个入口用哪个取决于你当时在干什么。第一个是通过菜单File → New → Target Configuration File。这是最通用的入口弹出对话框后需要填文件名、选择是否使用共享位置。这个方式建出来的文件默认挂在工作空间级别不绑定具体工程。第二个是在Target Configurations 视图里右键New Target Configuration。这个视图默认在 CCS Edit 透视图的右下角如果找不到走View → Target Configurations调出来。用这个入口的好处是文件建好之后立刻出现在视图树里双击就能进编辑器。第三个是在工程上右键对应的新建位置会默认落在工程的targetConfigs目录下。如果这个工程是要提交到代码库的我强烈建议用这个入口文件天然跟着工程走后面不会再为文件放哪了扯皮。提示不要在 CCS 运行期间直接用外部编辑器改 .ccxml 并保存CCS 缓存了配置树界面上的内容可能跟你改的对不上需要右键Refresh甚至重启 CCS 才同步。2.2 连接与器件选择选错一步后面全是坑进入编辑器之后界面分左右两栏。左栏是配置树右栏是属性页属性页又分 Basic 和 Advanced 两个标签。最核心的两项选择都在 Basic 页Connection决定用哪只仿真器。列表里能看到的条目取决于你装 CCS 时勾选了哪些仿真器组件常见的有Texas Instruments XDS100v2 USB Emulator、Texas Instruments XDS2xx USB Emulator、Texas Instruments XDS560v2 ...还有 Blackhawk、Spectrum Digital 等第三方仿真器的条目。这里要注意如果你的 CCS 当初是精简安装某些连接条目可能压根不在列表里需要回安装器补装。Board or Device决定目标芯片。这里有个容易被忽略的区别列表里既有板子条目比如某个官方 EVM 的型号也有器件条目比如 TMS320C6748。选板子条目会自动带出该板子上的完整器件拓扑适合官方开发板自己画的板子应该直接选器件条目因为板子上的 JTAG 拓扑和外设跟 EVM 不一样套用 EVM 的配置反而容易出问题。选完之后左栏的树上会生成对应的节点结构。单核 DSP 就是一个节点OMAP-L138 这种 ARMDSP 的异构器件会生成两个核心节点ARM9_0 和 C674x_0Keystone 系列的 C6678 会生成八个 DSP 核节点。树的结构必须跟实际硬件对齐多一个少一个都会导致连接异常。2.3 保存位置与命名的讲究保存位置这件事前面提了原则这里说具体做法。如果新建时勾选了Use shared location文件会落到 CCS 安装目录下的公共配置区好处是所有工作空间都能看到坏处是重装 CCS 或换机器就丢了而且其他人不一定有权限往那个目录写。团队协作场景下一律不勾让它跟着工程走。命名我一般用器件型号_仿真器型号.ccxml这个格式例如C6748_XDS100v2.ccxml、OMAPL138_XDS560v2.ccxml。如果同一块板子有多个变种再补一个后缀比如C6748_XDS100v2_revB.ccxml。别用test.ccxml、new.ccxml这种名字过三个月你自己都想不起来 test1 和 test2 的区别在哪。还有一个细节文件名里不要出现空格和中文。CCS 本身能处理但一旦后面要用命令行脚本去调用这个文件带空格的文件名会让参数解析变得很麻烦得加引号甚至双层转义。从一开始就规规矩矩用下划线能省掉后面的很多麻烦。2.4 Basic 页那些开关分别管什么Basic 页里除了连接和器件还有一组 Connection Properties不同仿真器暴露出来的选项不一样。以 XDS100v2 为例常见的有这么几项属性项作用经验取值JTAG Clock / TCLK FrequencyJTAG 时钟速率板子飞线长、环境干扰大时固定 500kHz~1MHz排线短且屏蔽好可以用 5MHz 以上Reset Type连接时的复位方式优先试 System Reset无效再试 CPU Reset 或 Board ResetTarget Voltage目标 IO 电压按板子的 JTAG 电平选1.8V/3.3V 选错会直接连不上Debug Probe Firmware仿真器固件版本一般保持默认除非官方文档明确要求升级Enable ARM Core Debug是否启用 ARM 核调试通道只在 ARMDSP 异构器件上出现用不到 ARM 时可以不勾TCLK 这一项值得单独说。很多人为了下载快把 TCLK 拉到最高结果偶尔能连、偶尔连不上现象非常随机。JTAG 是串行协议排线一长、旁边有开关电源信号完整性就下降速率越高越容易误码。连不上和偶尔连不上这两种现象八成都能靠降 TCLK 解决代价只是下载慢一点对开发调试体验影响很小。Target Voltage 选错的情况我也见过。有人拿 1.8V 电平的仿真器去接 3.3V 的 JTAG 接口结果不但连不上时间长了还可能损伤接口。选之前一定翻一下板子的原理图看清楚 JTAG 接的是哪个电源域。2.5 Advanced 页GEL、多核与外设初始化Advanced 页是以树的形式展示配置结构功能比 Basic 页强得多但也更容易改坏。三个高频用途挂 GEL 文件。展开到具体的核心节点右键可以添加 GEL。GELGeneral Extension Language是 CCS 的初始化脚本语言负责在连接目标之后配置 PLL、DDR 控制器、引脚复用这些程序还没跑起来就需要就位的东西。不同器件的 GEL 不能混用C6748 的 GEL 拿去给 F28335 用编译器不会拦你但运行起来就是一堆莫名其妙的超时。配置多核连接顺序。异构器件上ARM 核通常要先启动、配置好共享外设DSP 核才能正常工作。Advanced 页里可以调整核心的排列顺序也可以给每个核单独挂 GEL。OMAP-L138 这类器件我一般给 ARM 挂一个负责时钟和外设的主 GELDSP 核挂一个只做本地初始化的精简 GEL避免两边的初始化动作互相打架。手工添加子节点。某些特殊拓扑下CCS 自动生成的树跟实际硬件对不上需要手动 Add CPU 或 Add Device并指定对应的 XML 描述文件。这一步涉及的知识比较深需要参考 TI 的 Emulation 文档和器件数据手册里的 JTAG 扫描链章节不建议在没有把握的情况下乱加。3. 让配置文件真正干活的三种方式3.1 挂到 Debug Configuration 上建好的 .ccxml 只是备好的菜真正上桌要经过 Debug Configuration。打开Run → Debug Configurations左侧找到Code Composer Studio - Device Debugging新建一个配置在Target标签页里选择目标配置文件的路径。这里有个新手常踩的坑Target 标签页里选完文件之后下面还会有一个Program标签页需要指定要加载的 .out 文件。有人只配了前者没配后者点 Debug 之后发现程序没烧进去还以为是仿真配置文件的问题。其实两件事是分开的。另一个值得关注的选项是Load symbols和Reset target during program load。前者决定加载的时候带不带符号表后者决定加载前要不要复位目标。调试裸机程序时我一般两个都勾上保证每次加载都是干净状态调试带 Bootloader 的场景则要小心复位可能把 Bootloader 刚刚建立的运行环境清掉这时候就得把复位选项关掉改用暂停当前核心再加载的方式。3.2 手动启动调试会话时临时切换有时候你只是想快速验证一下某块板子能不能连上没必要建一整套 Debug Configuration。这时候可以直接在 Target Configurations 视图里右键目标配置文件选Launch Selected ConfigurationCCS 会启动一个空白的调试会话只建立连接不加载任何程序。这个操作在排查硬件问题时特别有用。连接成功之后在 Debug 视图里能看到各个核心节点的状态右键某个核可以单独做 Connect / Disconnect / Reset还能查看寄存器和内存。判断是板子坏了还是配置错了这一步就能给出明确答案如果连空白会话都能连上说明硬件和配置都没问题问题出在程序或加载流程上如果连不上那就老老实实回去查仿真配置和硬件。3.3 用脚本批量驱动仿真配置项目做到后期经常要做回归测试或者批量烧录靠手点界面效率太低。CCS5.5 自带一套 Debug Server ScriptingDSS环境可以让外部脚本直接调用仿真配置文件。DSS 的入口脚本在 CCS 安装目录下的ccs_base/scripting/bin/里Windows 下是dss.batLinux 下是dss.sh。一个最简单的 JavaScript 脚本长这样// load_and_run.js importPackage(Packages.com.ti.debug.engine.scripting); importPackage(Packages.com.ti.ccstudio.scripting.environment); var env ScriptingEnvironment.instance(); var ds env.getServer(com.ti.debug.engine, 1.0); var session ds.openSession(C6748_XDS100v2.ccxml); session.target.connect(); session.memory.loadProgram(demo.out); session.target.runAsynch(); // 跑一会儿再断开 java.lang.Thread.sleep(5000); session.target.halt(); session.target.disconnect(); session.terminate();在命令行里执行dss.bat load_and_run.js就能完成一次自动化烧录。脚本里openSession的参数就是 .ccxml 的路径这也是前面强调文件名别带空格和中文的原因。注意DSS 的 API 在不同 CCS 版本之间有细节差异脚本里用到的类名和方法签名以你本机安装目录下scripting/examples里的官方示例为准照抄网上的代码容易卡在版本不匹配上。4. 手动编辑 .ccxml 什么时候该动手改文本4.1 文件结构逐层拆解界面编辑器能覆盖九成场景但有两类活必须在文本层面干一是批量改路径二是对比两个版本的差异。这两种情况都要求你能看懂 .ccxml 的结构。一个典型的单核配置长这样这是简化示意实际生成的内容会包含更多属性?xml version1.0 encodingUTF-8 standaloneno? configurations XML_version1.2 idconfigurations_0 configuration XML_version1.2 idconfiguration_0 instance XML_version1.2 descTexas Instruments XDS100v2 USB Emulator hrefconnections/TIXDS100v2_Connection.xml idTexas Instruments XDS100v2 USB Emulator xmlTIXDS100v2_Connection.xml xmlpathconnections/ connection XML_version1.2 idTexas Instruments XDS100v2 USB Emulator instance XML_version1.2 hrefdrivers/tixds100v2cs.xml iddrivers xmltixds100v2cs.xml xmlpathdrivers/ instance XML_version1.2 hrefdrivers/tixds100v2c6748.xml iddrivers xmltixds100v2c6748.xml xmlpathdrivers/ platform XML_version1.2 idplatform_0 instance XML_version1.2 descTMS320C6748 hrefdevices/c6748.xml idTMS320C6748 xmlc6748.xml xmlpathdevices/ /platform /connection /configuration /configurations每一层的含义是明确的configuration是方案connection是仿真器通道三个instance分别是连接描述、CS 驱动、器件驱动最后的platform里才是真正的芯片节点。多核器件会在platform下挂多个器件实例并且通过core类节点标注每个核的编号。4.2 批量替换与路径迁移假设项目要整体从 XDS100v2 迁到 XDS560v2你有十几个工程要改一个个点界面显然不现实。这时候用文本编辑器的批量替换功能把TIXDS100v2_Connection.xml换成TIXDS560v2_Connection.xml、把驱动文件名的前缀一并改掉比点界面快得多。但替换之前必须做两件事。第一确认新仿真器对应的 XML 文件名到底叫什么最可靠的方法是在界面里手工建一个 XDS560v2 的配置然后把它的文件打开看一眼第二替换前先备份改坏了至少能回退。GEL 路径的迁移是另一个常见需求。如果 GEL 原来写的是绝对路径换成相对路径之后就没那么脆弱了。相对路径的基准是工作空间根目录所以在工程里放 GEL 的时候路径可以写成${PROJECT_ROOT}/gel/target.gel这种形式或者直接写工程相对路径。具体支持哪种写法跟 CCS 版本和配置节点有关改完之后一定要在界面上核对一遍确认路径被正确解析了。4.3 编辑后必须做的校验动作手动改完 .ccxml别急着点 Debug按下面顺序过一遍能省很多时间在 CCS 里右键该文件选Refresh让它重新读取磁盘内容。双击打开切到 Advanced 页看树结构是否完整有没有出现红色的错误标记。做一次空白会话连接Launch Selected Configuration确认硬件层面能通。最后再跑完整的 Debug Configuration验证程序加载和运行。跳过前三步直接上第四步一旦失败你没法判断是配置文件的问题还是程序的问题排查成本会翻倍。5. 连不上、复位失败、GEL 报错排查思路与速查表5.1 常见错误信息对照表下面是这些年攒下来的高频错误和对应的处理方向。错误码的具体定义以 TI 官方的 Emulation 文档为准这里给的是实战中验证过的排查顺序。错误提示关键词最可能的原因先查什么Error connecting to the target FTDI 相关描述仿真器 USB 通信异常、驱动没装好换 USB 口、避开 USB Hub、重装仿真器驱动、查设备管理器有没有黄色感叹号Device is not responding目标板没供电、JTAG 排线接触不良、TCLK 过高量板子电源、重新插拔排线、把 TCLK 降到 500kHz 再试Unable to reset device复位方式跟板子不匹配、看门狗在跑换 System Reset / CPU Reset 逐个试必要时先手动复位板子再连Unable to access the DAP之类芯片处于低功耗模式、被别的进程占着关掉残留的调试进程唤醒芯片后再连器件列表为空 / 找不到目标器件型号选错或者选了板子条目核对芯片丝印和数据手册型号改选器件条目GEL: Error while executing ...GEL 文件丢失、路径失效、时钟频率与实际晶振不符检查 GEL 路径核对板子上的晶振频率和 GEL 里的 PLL 参数扫描链错误 / 只认出部分核心多核器件的扫描链拓扑跟配置不一致检查配置树里核心数量对照原理图确认 JTAG 链路结构5.2 硬件与驱动的排查顺序连不上板子的时候很多人第一反应是改配置其实应该先把硬件和驱动的可能性排掉因为这部分排查成本最低、结论最明确。我的固定顺序是这样的。第一步看仿真器上的指示灯XDS100v2 正常上电后有电源灯连接时会有活动灯闪动如果灯完全不亮先查 USB 线和供电。第二步打开设备管理器确认仿真器被识别成一个正常的 USB 设备没有报错标记。第三步确认目标板已经上电而且 JTAG 接口那一侧的 IO 电压跟仿真器设置匹配。第四步把 TCLK 降到最低再试一次。第五步换一块确认没问题的板子试同一套配置。这五步走完基本能确定问题是在仿真器、线缆、板子还是配置上。跳过这些直接怀疑配置容易在软件层面绕圈子。5.3 多核场景下特有的坑单核器件连不上排查思路相对简单。多核器件的问题会更隐蔽因为连上了和连对了是两回事。第一个坑是连接顺序。OMAP-L138 这类器件ARM 核和 DSP 核共享一堆外设和存储器控制器。如果先连 DSP 并让它跑起来ARM 那边可能因为共享资源被占而挂在初始化阶段。稳妥做法是按 GEL 里的初始化依赖关系决定顺序通常先让 ARM 完成系统级配置再启动 DSP。第二个坑是GEL 重复初始化。有些官方 GEL 会做全芯片复位和时钟配置如果你给每个核都挂了同一个 GEL第二个核连接时会把第一个核刚配好的东西重置掉现象是连上了一个另一个就断了。解决办法是给不同核挂职责不同的 GEL或者只给主核挂完整版其他核挂精简版。第三个坑是断点互相干扰。多核同时运行时某个核上的断点可能触发整个调试会话暂停导致你以为另一个核跑飞了。调试多核程序时建议先单独跑通每个核再做联合调试并且熟悉 Debug 视图里的组暂停Group Suspend相关设置。6. 几条踩出来的经验6.1 团队协作中的文件管理一个项目组共用一块或几块板子的时候仿真配置文件的管理规则最好提前定下来不然后面全是扯皮。我的做法是在工程根目录下建一个targetConfigs目录把该工程用到的所有 .ccxml 都放里面命名带上器件和仿真器信息。同时在这个目录下放一个简短的 README写清楚每个文件对应哪块板子、哪只仿真器、需要装哪些 CCS 组件。新同事入职拉下代码看一遍 README 就能自己把环境搭起来不需要挨个问人。GEL 文件我也建议一起放进工程用相对路径引用。虽然官方 GEL 在 CCS 安装目录里就有但自己改过的 GEL比如适配了不同晶振频率一定要落到工程里不然换台机器就丢了。6.2 长期项目里的版本记录老项目往往要维护好几年中间可能换过好几次仿真器、换过好几版板子。这时候如果你只有一个target.ccxml过两年回头看根本不知道它对应的是哪一版硬件。我的习惯是每次硬件改版就新建一个对应版本的配置文件老文件保留不删文件名里带上版本信息。同时在工程文档里维护一张表记录每个版本配置文件的创建时间、对应硬件版本、使用的仿真器和验证人。这张表看起来有点形式主义但真出问题的时候能让你在三分钟内定位到上一版能用的配置长什么样对比一下就知道这次改了什么。6.3 一些零碎但好用的习惯第一每次成功连接之后把当时的 TCLK、复位方式、GEL 路径记下来。这些参数不写下来过两周就忘了下次连不上又得从头试一遍。第二仿真器固件不要随便升级。有些 TI 官方工具会提示仿真器有新固件可用但只要当前版本能正常工作就不要动它。固件升级失败导致仿真器变砖的情况虽然不常见但一旦发生恢复起来非常麻烦。第三备一只同型号的仿真器。老项目的仿真器一旦坏掉采购周期可能很长手边有备件能直接续上。第四不要把 .ccxml 和 Debug Configuration 混为一谈。前者是硬件连接描述可以跟着工程走后者是本机的调试偏好比如加载哪个 .out、是否复位很多时候不适合共享。分清楚这两者的边界团队协作时能少很多无谓的争论。第五新建配置之后先用空白会话连一次再挂程序。这一步只花十几秒却能让你在后续出问题时立刻分清是硬件连接的问题还是程序加载的问题性价比极高。