如果你做嵌入式开发,那你一定得对程序断点(program breakpoint)和数据断点(data breakpoint)有所了解。程序断点你可能还听说过,但数据断点就有可能不是很了解了,更有可能不知道如何去用了!现在,就让我们去了解所有类型的“断点”吧!
程序断点就是指处理器指令断点,通俗的说就是:当程序运行到某个地方时,我们希望程序停下来,即程序“断”了!停下来的目的,就是给我们检查当前程序运行的状态的机会。对于软件开发人员来说,对于程序断点一点都不陌生,它是我们调试程序的必需手段。但对于嵌入式开发,我们还得对程序断点进行区分:软件程序断点和硬件程序断点。
为了说明硬件程序断点,我们先要了解软件程序断点是如何实现的。你想过了吗?软件程序断点到底是如何实现的?当你用Visual Studio进行软件开发时,你可以设置很多的断点,对不?我们知道,如果处理器在运行的过程中,如果碰到了一条非法的指令,那会出现一个异常中断,程序也会停了下来。软件程序断点就是利用这个特性来实现的,当我们设置一个断点时,调试工具就在我们所想设置的程序位置上放置一条非法的指令,同时保留原来的指令。当程序运行时,一旦运行到了我们设置了断点的地方,即现在指令是非法的位置,处理器就会产生一个异常中断从而停了下来。当然,调试工具会接管这一中断,并在中断服务程序中,将保存的原来的指令恢复回去。当然,于此同时也会给程序员调试程序的机会,并由程序员决定什么时候继续运行程序。从理论上说,软件程序断点可以设n个,这里的n趋近于无穷(当然内存不允许?)。
有了软件程序断点的概念,那么就好理解硬件程序断点了。在介绍硬件程序断点时,我们先要问一问,为什么要引入硬件程序断点。引入一种新的概念,往往意味着老的概念存在一定的局限性。那软件程序断点存在什么局限性呢?想想看,在嵌入式系统中,如果我们想调试一个boot loader(参见《什么是boot loader》一文),而此时处理器还在运行位于FLASH中的程序,此时软件程序断点这种方法还有效吗?当然不行,因为FLASH中的内容并不能像内存一样,被处理器通过一个写操作直接更改。在FLASH中更改内容(或称对FLASH进行编程)存在一定的协议,而显然处理器不会去实现这一协议的,这会严重影响处理器的通用性。此外,即使实现了,其效率也不会高。即然这样,软件程序断点不能运用到boot loader的调试中去。解决方法时什么呢?就是处理器提供一定的寄存器用于存放程序的断点位置,当我们通过调试工具设置断点时,调试程序会将所需中断的指令地址放入到处理器的程序中断寄存器中。显然,处理器的这种寄存器是有限的,因此,我们不能设置n个。
现在让我们说一说数据断点。试想想,当我们在调试程序时,如果发现所定义的一个数据结构中的某一个值总是被意外的更改。根据我们的经验,这种意外更改是因为程序中存在bug的缘故。在这种情况下,我们很难找出根源在哪儿。如果处理器有一种功能,当某块内存区或具体的地址被意外更改时,停下来就好了。这就是数据断点的作用!处理器如果提供这种功能,我们能更方便的找出出错的根源。高级的处理器往往提供这种功能!类同的是,处理器的数据断点也是通过处理器提供相应的设置寄存器来实现的,当然也是有限的!
现在让我们看一看,处理器处理硬件程序断点与数据断点的区别是什么。对于硬件程序断点,我们知道,处理理器需要从内存中取指,而处理器也有一个程序指针PC(program counter),通过将PC值与我们所设置的程序断点位置值相比较,处理器就可以实现硬件程序断点了。但数据指令就不一样了,处理器必须监听地址总线,当发现有向关心的地址写数据时,就中断程序的运行。
相信读过这篇文章后,你听到软件程序断点、硬件程序断点和数据断点时,一定很坦然了。最后,我想指出的是,如果你正在为你的嵌入式产品选择处理器,考虑处理器是否支持数据断点是很有必要的!
本文出自 “至简李云” 博客,请务必保留此出处http://yunli.blog.51cto.com/831344/196353