调试的软硬件手段

jdygrdzh 2012-01-19 08:45:39
这是一个很大的话题,我也只能把我所知道的总结出来,也许还有更好的手段,欢迎大家补充.

首先,我把调试手段分为硬件和软件.

软件手段早为大家所熟知.其中最简单的就是著名的printf().通常这个函数把存在内存中的需要显示的字符传到串口(客户机调试)或者内存(本级调试).再由串口或者显示驱动打印在屏幕上.值得注意的是,如果是打印到内存再显示,必须使用多线程方式,不然本级内存写入速度非常快,而显示速度通常很慢.

更高级一点的方式是利用单步中断.原理是处理器每运行一条指令,就触发一个中断,然后原来的上下文就不动了,中断处理程序接手,这时既可以把各种信息显示出来显示在本机,也可以送到某个串口实现客户机调试.GDB,XGBG,Visual C++,ICE等就是这样的强大的调试工具,可以调试源代码.他们之间的差异是有些可以调试用户态,有些针对内核态代码.

很多时候,我们的代码会调用系统调用,而系统调用是看不到源代码的.但是我们可以通过一个叫做strace命令跟踪系统调用,并了解输入参数.这样,结合printf使用,很多时候我们就不使用GDB等工具而得到程序的运行情况.如果再配合文本分析脚本,那就可以抓取所需要的调试信息.

针对有些通用的协议,如APCI, USB,我们可以找到一些已近做好的分析工具,他们利用strace或者ptrace函数,记录相应协议产生的系统调用序列,并给出有意义的输出.利用这样一些工具我们可以比较容易的分析驱动程序或者操作系统的动作.

硬件手段一般为人所熟知的是JTAG.它的原理是使用一套额外的,处理器控制总线之外的信号,可以独立的控制各个器件或者芯片内模块.由于速度低,结构简单,它非常稳定,哪怕是处理器系统出错,无法访问模块,它也可以提供可靠的手段来控制那个模块.当然,只是简单的控制,而无法做到高速数据传输.这也就是他稳定的原因.通过JTAG,我们可以像单步中断一样控制访问处理器和芯片组,在停掉软件包括中断处理程序的情况下来调试.这里的调试指的是客户机调试,配合强大的软件,我们也可以做到源代码调试.不过JTAG方式有个限制,就是在真正卖出去的芯片上,那些管脚基本是给屏蔽的,就算连上线,芯片内部也会通过熔丝(fuse)等手段使其失效,从而防止破解内部信息.

还有就是把管脚接到示波器或者是逻辑分析仪,协议分析仪来看输出信号.这些仪器提供了丰富的触发和抓取功能,能让我们看到想要看到的那段信号.其中逻辑分析仪和协议分析仪是看逻辑信号的,示波器是看逻辑和模拟信号的.

在此给像我一样软件背景的同学们普及下常识.

逻辑分析仪通常很贵,上百万也不稀奇,它可以设定丰富的触发模式(pattern),抓取想要的那个时间段之内的东西.一般可以同时监测8个信号,并把这些信号记录下来,放在很大的内存中,也可以输出到别的设备.它的采样率可以很高,支持到最新的PCIe 3.0的8G的速度.厂商通常是泰克或者安捷伦.国内也有很便宜的牌子,但是我估计采样率不会高.

协议分析仪相比逻辑分析仪要便宜的多,根据对应协议的复杂度价格也不同.通常有USB, PCIe, SATA等协议.新的高速协议比如PCIe3.0 20万差不多.当然,这个只是analyzer接受输出信号,如果要产生信号那需要买exercisor,再加20万.厂商最著名的也是安捷伦和泰克.如果是网络分析仪,那得去找思博伦,他们的smartbits和其后续产品在网络测试这块很有名.

那既然有了逻辑和协议分析仪,为什么还需要示波器呢?这是因为后者可以看到真正的模拟层信号,而不只是逻辑的零和一.如果USB2.0协议的数据传输率是450M Hz,那么要分析它,至少需要8倍的采样率,这样才能得到有意义的数据.但是8倍采样率并不意味着需要5G Hz的示波器.示波器采用某种机制使得一个采样周期内可以采样几个点.当然,速度越高那自然是越好,不过价格也上来了.20G示波器也得上百万.此外,示波器内通常会自带一些软件,比如协议一致性测试分析等.还有,高速信号通常是使用差分探头的,原因就是信号完整性问题,差分线能更好的在长距离上传输信号,抗干扰能力较强.

说到这里我想到另一个问题,就是并行传输和串行传输哪个更快?初学者肯定是认为并行更快,因为可以同时传更多数据嘛.但是当传输率进一步上升,并行信号之间出现了干扰,这样数据同步就成了一个大问题.串行传输由于使用了2根差分信号线,可以以更高的速度传输而无需同步,并且减少接口复杂度和成本.这样,在现在的很多高速协议里,串行通讯成了主流.

于是,有人就说,串行更快.对么?错.如果解决了并行的干扰和同步问题,把并行的传输率也提高,或者使用更多的传输线,那并行传输岂不是也变快了.DDR内存协议就是一个很好的例子.当然,这样做的后果就是其传输控制器设计非常复杂,非常容易出错.这也就是为什么DDR是一个系统里面最难设计,出了错最难解决的原因.哪怕是主板上相关部分的轻微改动,也会让内存访问出问题.更不用说设计内存控制器了.

接下去继续讲硬件的调试手段.其实在硬件上,调试的目的和方法很简单,就是通过触发某个特殊信号或者模式,从而定位到出错的那段波形.相比软件收到多线程,互斥和信号的干扰,硬件受到的干扰简单的多.如果使用JTAG手段,把处理器停住,排除软件的干扰,只做最简单最直接的寄存器操作来控制硬件,那就更容易了.如果是偶尔发生的错误,那可能就需要设定更复杂的触发条件,这个会相对复杂.

那硬件调试的难点在哪呢?一个就是前面说的排除干扰抓到某个特定点的信号.一个就是,示波器通常只能看到芯片的输出信号,对于片内信号是束手无策的.一般芯片内会有一些状态寄存器来帮助调试.但是,这样仅仅是看到某个事件或者错误之后的寄存器值,并不能抓取发生错误的时候那些信号到底是怎么样的.怎么解决?很简单,把所有的内部信号全都连到外部示波器上来看就是了.但是这样基本不可行,成本太大,也没那么多管脚可以连.一个折衷的方案就是,把每个模块的关键信号连到特殊设计的内部信号网络,然后使用简单的控制器可以切换到不同的模块的关键信号.这样,最终连到外部的可能只有8根线,却可以在不同时间看到不同模块的所有关键信号.这样的信号是真正的实时信号,而不是某个推迟的状态.

对于逻辑信号(逻辑信号和模拟信号的区别前一篇已经提到),由于只是需要直到每个时钟里面某点的状态(零或者一)就可以,所以容易连到外面.对于模拟信号,由于需要在多点采样,才能看到模拟特性,所以需要一个有快的多的时钟的信号去采样,才能看到诸如毛刺等.其原理和示波器采样很像.

有了这个工具,我们完全可以使用正确的触发条件,跟踪关键信号,最终定位到有问题的那个时间,那个模块,那个信号,从而找到错误信号的源头.当然,至于为什么会产生那个错误,可能是逻辑功能设计失误,可能是模拟模块设计问题,也可能是制造过程有问题.那就需要和设计师一起讨论了.

更进一步,我们已经有了实时信号,那是不是可以省掉外部示波器和分析仪,直接在芯片内部把采样到的信号输出到内存,使用软件进行模式识别呢?还有,关于触发功能,也可以做出类似的片内逻辑,把预先定义的模式当作触发条件,从而完全替代示波器?完全可行,而且已经有这样的工具了.在芯片设计阶段,这个工具就需要和整个芯片一起设计.这应该是最终极的调试手段了.还有更强大的么?我想不出了.


...全文
271 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
woshi_ziyu 2012-01-19
  • 打赏
  • 举报
回复
不怎么用调试

21,600

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧