尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

TRACE32适配Arm CoreSight SoC-600:嵌入式调试新能力解析

TRACE32适配Arm CoreSight SoC-600:嵌入式调试新能力解析 最近在调试一块新芯片的时候我发现Lauterbach把TRACE32的更新日志里专门加了一条支持Arm CoreSight SoC-600。可能你觉得这不过是工具厂商又刷了个版本号但对天天跟底层调试打交道的人来说这条更新其实是把一块难啃的骨头提前给啃下来了。TRACE32是嵌入式调试领域用得最多的工具之一尤其在做SoC验证、BSP移植、驱动调试和安全认证的时候几乎绕不开它。而CoreSight SoC-600是Arm新一代调试追踪架构的核心组件很多新出的Cortex-A、Cortex-R平台以及异构SoC都在往这套架构上迁移。两者一接上意味着从老平台迁到新平台的团队不需要再为调试器不认芯片、trace采不全、多核拓扑扫不出来这些事折腾好几周了。这篇文章主要围绕这次支持展开从CoreSight SoC-600到底是什么讲起再解释TRACE32为什么要专门适配它然后给出一套实际操作中可用的配置步骤和问题排查记录。内容偏底层但我会尽量用大家熟悉的方式讲清楚适合芯片验证、嵌入式底层驱动、BSP开发以及硬件调试的工程师参考。如果你只是用过J-LINK刷个固件也能看个大概至少以后遇到调试器连不上、trace丢数据的时候心里能有个方向。1. CoreSight SoC-600到底是个什么来头1.1 从CoreSight调试架构说起如果你在ARM平台上做过调试应该接触过CoreSight。它不是某一个具体模块而是一整套用于片上调试和追踪的架构负责把处理器内核的调试接口、追踪数据、时间戳、性能计数器这些东西统一管理起来。打个比方如果说CPU内核是公司里的各个业务部门那CoreSight就是行政和IT系统它把每个部门需要的门禁、监控、日志系统统一搭建好并对外提供一套标准接口。CoreSight里包含很多组件各有分工。DAP是调试端口访问器外面的调试器通过JTAG或SWD连到DAP然后访问芯片内部的寄存器ETM是嵌入式追踪宏单元用来采集CPU执行的指令流和事件TPIU或ATB把追踪数据送到外部trace接口或片上缓冲区ETF/ETB则负责暂存trace数据。还有CTI/CTM这类交叉触发组件用来在多个内核或多个子系统之间同步事件。早年间各家芯片设计厂商的调试接口很不统一A厂商的调试器往往没法直接拿到B厂商芯片上的调试寄存器更别说做系统级的追踪分析。Arm为了解决这个问题把调试组件标准化成CoreSight架构这样芯片设计公司只要按照规范把组件接入SoC调试工具厂商就能用统一的思路去访问这些组件而不是每个芯片单独适配。这也是为什么现在大多数调试器都能识别不同品牌的ARM芯片但要真正完整支持trace和复杂调试功能还是得对CoreSight的细节下功夫。1.2 SoC-600相比SoC-400的关键变化SoC-600是CoreSight架构演进到新一代的实现。像很多IP产品一样Arm先有CoreSight SoC-400后来为了适应更高性能、更复杂的安全需求推出了SoC-600。从公开资料和实际使用经验来看两者之间的差异主要体现在几个方面。一是追踪带宽明显提高了。SoC-400时代trace数据经过总线进入外部接口时带宽有限多核平台或高性能CPU全速跑起来很容易丢trace。SoC-600在互连和数据通路设计上做了改进能支撑更长时间、更完整指令流追踪。二是DAP的设计更灵活。SoC-600的DAP支持更丰富的访问端口配置多个调试主机可以通过不同端口同时访问也更适合虚拟化场景。调试器访问AP时的寄存器映射和状态位也有变化如果工具不认识这些新寄存器就无法完成初始化。三是对安全隔离和虚拟化支持更好。SoC-600把调试资源按TrustZone安全状态和异常等级做了更细粒度的控制。这意味着调试器不仅要能访问寄存器还要能判断自己当前有没有权限并在无权限时给出明确提示而不是一头撞到总线错误上。四是在多核、异构系统的拓扑描述上更清晰。通过新的CoreSight组件ID和连接方式调试器能自动扫出哪些核是Cortex-A、哪些核是Cortex-M以及它们和trace组件之间的拓扑关系。这让多核调试和交叉触发配置变得更加傻瓜化。我可以给个粗略的对比表格方便大家理解维度CoreSight SoC-400CoreSight SoC-600追踪带宽相对有限高负载时易丢数据更高吞吐支持更长时追踪DAP设计经典DP/AP结构拓扑较固定更灵活支持多调试主机访问安全控制有基本隔离增强TrustZone和虚拟化隔离时钟域管理传统全局时钟方案多时钟域协同低功耗调试更友好调试工具适配需要较多手动配置支持自动拓扑识别配置更简单这个表格不是官方规格书只是我根据自己的经验做的归纳。真正拿到具体芯片时还是要看对应技术参考手册但整体趋势是这样的。1.3 为什么调试工具必须跟着适配看到这里你可能会想既然CoreSight还是那套组件调试器改改寄存器地址不就行了没那么简单。调试器连接目标板后第一步是发送JTAG或SWD指令把DAP激活。接下来要读取DPIDR、目标AP的IDR识别芯片型号和核的架构版本。这些ID寄存器的值在新老SoC上可能不同工具不识别就没法继续。再往后要配置AP的CSW、TAR访问内存映射的调试寄存器还要扫描CoreSight组件通过它们ID寄存器建立一张系统拓扑图。最后才能读写内核寄存器、设置断点、配置trace。在这条链路里任何一个环节发生变化整套流程都要跟着适应。SoC-600改了DAP的访问序列改了trace组件的基地址布局甚至改了多核事件的同步方式。调试器如果还是按老办法直接硬编码地址轻则识别不到组件重则把数据写错位置导致目标板死机。TRACE32这次增加支持表面上只是多了个设备ID实际上是把整套初始化、扫描、访问、trace配置的流程都做了适配这才是价值所在。2. TRACE32支持SoC-600重要在哪2.1 TRACE32在ARM调试中的角色调试工具市面上有不少J-Link、OpenOCD、ST-LINK各有各的用途。但如果你做的是复杂SoC的调试TRACE32几乎是绕不开的选择。它分为调试访问硬件和软件IDE两部分硬件上PowerDebug提供JTAG/SWD等接口PowerTrace专门做高带宽实时trace采集。软件上它能解析大量ARM架构细节把寄存器、内存、trace数据变成可视化的信息。TRACE32强在几个地方一个是支持多核和异构系统的调试比如Cortex-A和Cortex-M混合的SoC它能同时连接不同核并统一控制另一个是trace能力通过PowerTrace可以连续记录程序执行流配合时间戳定位偶发性问题再一个是对SoC内部复杂组件的访问能力能够直接操作CoreSight的DAP、ETM、TPIU等部分这是很多轻量调试器做不到的。所以当Arm推出CoreSight SoC-600之后TRACE32的支持力度直接影响很多团队的研发进度。如果调试器迟迟不认新架构那芯片验证和BSP开发就会卡在第一步连不上、看不见、跑不动。2.2 新支持的核心能力清单Lauterbach这次更新从使用效果来看主要覆盖了以下几个能力。自动探测和识别SoC-600拓扑。启动后TRACE32会扫描DAP下面的所有CoreSight组件自动识别出哪些是CPU核心哪些是ETM/ETF/TPIU并建立拓扑关系。这减少了手动指定地址的繁琐和出错概率。新增调试组件和寄存器定义。比如SoC-600里新出现的配置寄存器和状态位TRACE32能正确解析并在调试视图中显示出来。这样你在修改配置时能看到芯片真实的反馈而不是面对一串不可读的数字。支持基于SoC-600的ETF/ETB缓冲区配置与读取。老工具可能只会默认把缓冲区当作一块内存来读如果忘了初始化采回来的数据就是乱的。新版本能自动初始化缓冲区并按正确的格式解析trace包。支持多核和异构场景下的交叉触发。CTI/CTM这类组件的配置在新版本里变得更直观你可以很方便地设置一个核触发事件、另一个核作出响应用来分析多核协作问题。安全调试方面TRACE32能识别当前调试访问是否被TrustZone阻止并给出明确提示而不是在所有寄存器访问上统一报错帮你更快判断问题出在权限还是别的地方。2.3 对开发团队的实际收益这些能力落到实际项目中收益是很直接的。我举一个例子上一家公司做一颗集成多个Cortex-A核和Cortex-M核的SoCBSP阶段最痛苦的就是把不同核的调试环境弄通。老版本TRACE32连接时经常需要手动指定CoreSight组件的基地址而每个核的地址表还不太一样一旦写错工具就连接不上。升级到支持SoC-600的版本后自动扫描功能帮了大忙。连接后工具会把核、trace组件、调试端口全部列出来我们只需要核对一遍然后保存成配置文件团队其他人就可以基于这个配置直接调试。原来新同事上手要学半天现在照着配置打开就行省下来的时间不是一两天。另外由于SoC-600支持更高的trace带宽我们以前在几个核同时跑业务时经常遇到的trace丢数据问题明显减少了。这对定位多核交互的偶发死锁、cache一致性导致的奇怪现象非常有帮助。能在现场复现并抓取完整trace比事后猜要高效太多。3. 实操在TRACE32中对接CoreSight SoC-6003.1 环境准备与版本确认如果你手头已经有TRACE32第一步要做的是确认版本号。Lauterbach的软件更新比较频繁有些新功能只在特定版本之后才提供。你可以打开TRACE32的Help菜单查看About或者在命令行里输入SYStem.Info查看版本信息。如果版本较老建议先从官网下载最新版。下载更新时要注意TRACE32分不同处理器系列的许可证和软件包ARM相关的包通常是TRACE32 for ARM安装时选择对应的组件即可。另外调试探针固件也最好同步升级。PowerDebug这类硬件的固件版本和软件版本需要匹配否则可能出现连得上但功能缺失的情况。目标板方面SoC-600本身是一个IP最终还要看你的芯片厂商是否把相关调试端口引出来。大多数评估板会在板上放置标准JTAG/SWD排针或者接一个调试连接器。连接方式上新的SoC通常支持JTAG和SWD两种模式SoC-600的DAP设计对SWD支持得很好所以如果你只是做单核程序调试SWD是更简单高效的选择。3.2 连接配置从config.t32到自动探测TRACE32启动时会加载一个配置文件一般是config.t32。这个文件里会指定调试接口类型、目标芯片相关信息、脚本路径等。下面是一个常见的配置片段注意不同版本命令名称可能有差异以你安装版本的帮助文档为准; 选择调试接口类型 SYStem.CONFIG.DEBUGPORTTYPE SWD ; 如果目标芯片CoreSight基地址不是默认值手动指定 SYStem.CONFIG.DAP.CORESIGHT.BASE 0x80000000 ; 指定CPU类型 SYStem.CPU.CORTEXA53 ; 连接模式先以Attach方式避免复位板子 SYStem.Mode Attach这个配置文件里最需要注意的就是SYStem.CONFIG.DAP.CORESIGHT.BASE。CoreSight组件的寄存器空间一般在系统内存映射的高地址区域不同SoC厂商会在基地址上有自己的选择。如果默认值探测不到你可以在芯片参考手册里找到CORESIGHT base address一类的描述然后手动填进去。连接成功后TRACE32会在命令窗口输出DAP的状态包括读到的DPIDR、目标AP编号等。如果支持SoC-600通常能看到类似CoreSight SoC-600 detected或者组件ID列表。这时候输入SYStem.Mode Up工具就会初始化CPU进入可调试状态。在命令行里可以输入SYStem.DAP这个命令会显示当前DAP下的所有AP以及每个AP对应的存储器接口。如果你看到AP列表里有很多个说明SoC-600的DAP确实扩展了访问端口这也是新架构的一个特征。3.3 读取寄存器、下断点、采集Trace连接成功后日常调试其实和以前差不多。使用Register View窗口可以查看当前核的PC、SP、LR等寄存器。如果你想快速在命令行里看PCR.S PC实际读取PC的时候很多人不理解SWD协议在背后做了什么。如果你自己写过SWD驱动就会知道并不是直接在物理线上读一帧数据就能得到PC。整个过程需要先唤醒调试端口发送DP的访问请求建立连接然后通过AP去访问内存映射的调试寄存器组最后从某个寄存器里取出PC值。这个过程中AP选择、Bank选择、传输长度、字节序都可能出错。TRACE32把这些细节都封装好了你只需要关心结果但理解原理有助于判断异常。断点方面TRACE32支持硬件断点和软件断点。嵌入式开发中在Flash里运行代码时常用硬件断点因为不能随便改写Flash内容。使用SoC-600的新平台硬件断点数量可能比老平台更充裕但也不是无限的所以关键路径上要省着用。用Break.Set命令可以设置断点Break.Set 0x10000000 /Program这个命令表示在地址0x10000000处设置程序断点。如果地址有别名或者映射关系工具会自动处理。trace采集是TRACE32最核心的功能。在支持SoC-600的平台上你可以通过ETM或ETB采集指令流。最基本的方式是先用Trace.Init初始化trace系统然后配置trace模式Trace.Init Trace.Set.Mode Fill Trace.Set.ETM On这里Fill模式表示环形缓冲缓冲区满了之后新的数据会覆盖旧数据适合采集最近一段时间执行的历史。如果要长时间连续录制需要PowerTrace这种外置跟踪硬件并把TRACE32的工作模式切换为流模式。启用trace后运行目标程序结束后用Trace.List查看指令流或者用Trace.Chart查看时间相关的执行图。在SoC-600新架构下trace数据的时钟域和同步处理比老架构更复杂。如果你发现采集回来的trace有乱码或者时间戳错乱先检查配置里的trace时钟源是否正确再看看缓冲区是否被正确初始化。这些细节处理好了trace数据才可靠。3.4 多核与异构调试的配置思路现代SoC很少只有一个核SoC-600的一个重要应用场景就是多核调试。在TRACE32里多核调试通常有两种模式一种是同时连接多个核每个核都有独立的调试视图另一种是联合调试通过事件触发把多个核同步起来。连接多核时你需要在config.t32里把CPU类型和核心数配置清楚。例如如果目标芯片有四个Cortex-A53SYStem.CPU.CORTEXA53 CPU.NUMCORE 4连接后TRACE32会为每个核创建独立的调试会话你在命令行里可以用CPU.Select切换当前操作的核CPU.Select 0这会切到核0。如果切换到核2就执行CPU.Select 2。异构调试更复杂一点。比如芯片里同时有Cortex-A和Cortex-M它们各自有独立的调试域但通过CTI/CTM连接在一起。TRACE32在支持SoC-600后对这类拓扑的识别更准确。你可以先分别连接到两个调试域然后配置交叉触发让一个核的断点触发另一个核的暂停。这个功能在做异步通信和共享内存调试时非常有用。多核调试时经常会遇到一个问题多个核同时运行断点命中后有的核停下来了有的核还在跑导致系统状态不一致。利用TRACE32的Break.Set配合多核同步选项可以让所有核同时响应用户事件。这个功能在做死锁分析时几乎是救命的。4. 常见问题速查与避坑记录4.1 连接失败从ID检测到电压问题日常调试中最打击人的就是明明线接好了TRACE32却报Cannot read ID或者DAP not found。遇到这种情况我建议按顺序排查。先检查物理连接。JTAG/SWD信号线有没有接反TMS/TCK或SWDIO/SWCLK是不是对上了目标板有没有接Vref也就是参考电压脚。有些调试探针需要参考电压来了解目标板IO电平如果不接就直接失败。再确认TRACE32里选择的接口模式。如果你实际用的是SWD但在config.t32里写的是JTAG那也会连不上。这个看起来低级但忙起来真的容易忽略。输入SYStem.DAP.LockAccess这个命令可以看到调试端口的状态。如果还是读不到DPIDR大概率是物理层问题。可以量一下TCK/SWDCLK上有没有稳定的时钟再看TDI/TDO回环是否正常。对于SWD模式只有一个数据线SWDIO既做输入又做输出所以尤其容易受板端上拉电阻的影响必要时要检查调试端口的上下拉配置。4.2 Trace数据不完整先从缓冲区和时钟域下手trace数据丢失是另一个高频问题。如果你在SoC-600平台上采集trace发现Trace.List里只有开头一段后面全是空白先检查时钟域和缓冲区的配置。很多新平台的ETF缓冲区默认是关闭的或者被Bootloader配置成了其他用途。TRACE32连接后如果你没有执行Trace.Init缓冲区可能无法正确管理导致新数据写入失败或读出来是乱的。我习惯的做法是在每次配置trace之前都先执行一次Trace.Init强制重建缓冲区配置。另外SoC-600支持多个时钟域如果trace时钟和CPU时钟不是同一个来源可能在跨域传输时出现数据丢失或时间戳抖动。这时可以降低trace的带宽需求比如关掉一些不太关键的事件组只保留指令流和核心事件。稳定后再逐步打开直到找到导致丢数据的具体事件类型。4.3 手动指定CoreSight基地址的坑在自动探测失败的时候我们一般会手动指定SYStem.CONFIG.DAP.CORESIGHT.BASE。但这个操作有几个坑。第一基地址不能随便填。你需要找到芯片参考手册里CoreSight组件区域的基地址。如果填了外设寄存器地址TRACE32可能会误识别出一些奇怪的组件导致后续访问异常。我曾经遇到有人填了一个地址后工具把内存控制器识别成了trace组件结果一配置trace就把系统搞挂了。第二基地址要和DAP的AP访问路径对应上。在SoC-600里可能存在多个AP每个AP访问不同的内存区域。如果你的基地址对应的不是DAP所在的AP同样会识别失败。这时候要用SYStem.DAP命令看一下当前选中的AP必要时用SYStem.DAP.SELECT切换到正确的AP。第三手动指定基地址后默认的自动扫描可能被覆盖导致其他组件没有被枚举出来。所以如果手动指定能连上但调试功能缺失别急着怀疑工具先把自动扫描重新跑一遍看看有没有遗漏。4.4 SWD协议读取PC寄存器时容易忽略的点如果你结合网上的一些ARM SWD协议读取PC寄存器教程在做底层调试有几个点容易被忽略。首先是DP和AP的区分。SWD协议里DP是Debug Port负责链路层AP是Access Port负责访问系统总线。你读PC时实际上是通过AP访问CPU核的调试寄存器而不是直接从DP读。很多人的代码死磕DP却发现读不出来数据就是因为跳过了AP层。其次AP访问需要先配置CSW寄存器设置传输大小、地址自增模式等。如果CSW配置得和你后续读取的数据长度不一致读回来的寄存器值可能被截断或错位。TRACE32会自动处理这些但如果你在写自己的SWD驱动这一点尤其重要。第三读回来的数据字节序可能与你的CPU架构有关。大多数ARM平台是小端但有些总线桥会做字节交换所以你在裸驱动中最好先用读ID寄存器的方式验证一下字节序再读PC。如果你用TRACE32这些都已经处理好了。但在定制芯片上如果读PC发现值明显不对可以先读一下CPU的CPUID寄存器确认当前调试会话选中的是不是你预期的那颗核。多核环境下选错核导致读到的PC驴唇不对马嘴也是一个常见坑。4.5 模拟器与真实硬件的差异在等硬件的时候很多人喜欢先用QEMU模拟ARM开发板来跑调试流程。QEMU确实是个好工具可以模拟出ARMv7、ARMv8等架构的CPU配合交叉编译工具链能提前做一些裸机和Linux驱动开发。但要注意QEMU对CoreSight SoC-600的模拟并不完整。目前QEMU里很多ARM虚拟开发板只有基本的调试接口甚至不包含完整的CoreSight组件。你可以用GDB连上QEMU调试程序也能读到PC和内存但TRACE32的trace功能基本用不了。因为trace相关组件在模拟器里要么不存在要么只是空壳没有实际数据输出。所以我的建议是模拟器适合练习交叉编译、启动流程、基础调试命令但不要把它作为验证TRACE32新功能的环境。真正要确认SoC-600的配置和trace功能还是得找一块真实开发板把config.t32和命令行流程跑通。5. 升级后的工作流变化与个人体会5.1 迁移到新版本前要做的事升级TRACE32支持SoC-600不是点了更新就完事。我建议你先在本地备份好旧版本尤其是项目里已经在用的config.t32和启动脚本。新版本虽然兼容大部分老命令但某些底层行为可能有细微变化如果你手头还有老芯片的生产任务别急着全团队切换。接着拿一块最简单的SoC-600开发板跑一遍全流程。从SYStem.Mode Attach开始确认自动扫描出来的CoreSight组件和你预期一致再往下做读寄存器、设断点、采集trace最后再看看多核切换是否正常。把这个流程固化成团队内部的一个checklist后续新成员照着做就能上手。还有一点TRACE32许可证有时会限制某些功能比如trace带宽或CPU核数。升级前最好确认一下你的许可证是否覆盖了新的SoC-600相关功能否则可能出现软件识别了、但功能被锁住的情况。这个坑最容易被人忽略最好去Lauterbach官网或直接找技术支持确认。5.2 在Linux驱动开发与安全认证中的价值支持CoreSight SoC-600对跑Linux和进行安全认证的团队尤其有价值。Linux内核的启动阶段很多时候要调试MMU、GIC、时钟和功耗管理这些与硬件紧密结合的部分。如果调试器不能稳定访问CoreSight组件的寄存器在启动早期出现异常时你根本没有办法拿trace只能靠printk一点点试效率极低。SoC-600在安全方面的增强也让调试器在安全认证场景中更有优势。比如在做ARM TrustZone相关开发时你经常需要判断某些寄存器访问是确实没有权限还是工具没配置对。TRACE32能区分这类错误并给出提示可以节省大量排查时间。在TEE开发或者安全启动调试中这个能力很重要。我在实际使用中发现新版TRACE32对这些复杂场景的适配让整个调试体验平滑了很多。以前遇到网络包都是黑盒现在能看到更详细的状态和原因团队内部对问题的讨论也从猜变成了看证据。5.3 一点个人建议说了这么多最后分享一个我在实操里的体会。每次拿到新调试设备或者新版本工具我都会先花半天时间用一个最小的测试工程把所有功能过一遍。这个测试工程不需要复杂就是控制GPIO翻转、跑一个简单的任务调度再加一个定时器中断。把它跑通了再上真正的业务代码。原因很简单新工具链和新芯片组合时问题往往出在配置上而不是业务逻辑上。先在最小工程上把连接、下载、断点、trace、多核切换全部验证一遍等真正调试复杂问题时你只需要关注逻辑不用再分心处理环境问题。另外多读目标芯片手册里CoreSight相关的章节。调试器再先进也只是把手册里的寄存器操作封装起来。如果你能看懂DAP、AP、ETM、ETF之间的连接关系使用TRACE32时会更有底气。特别是在自动扫描失败的情况下手动配置需要你对架构有清晰理解这时手册就是最好的老师。
返回列表