jlink调试器中你不知道的"那些事"?(ARM篇)
1、日常聊一聊(看文章与听音乐更配)
最近个人微信号添加了挺多小伙伴,一些小伙伴觉得作者文章不错前来为我加油,一些小伙伴可能看不太懂作者的文章并前来咨询,首先非常感谢这些小伙伴,也非常荣幸大家能够添加我为好友,不过可能作者白天有非常多的开发工作,不能及时回复大家,并且有时候可能点开了大家的疑问,忽然一个电话就把一些事情给忘记了,所以希望大伙都能谅解,我也会尽量集中时间统一回复大家。(还有一点大家一些简单的问题多多思考一下,找找其他解决办法,如果实在没办法可以微信我!)
好了,该进入我们的今天的主题了,jlink调试器需要讲得东西真的非常多,可能大部分的小伙伴在日常的开发中只是用它来辅助我们的目标芯片的开发,基本上是把手中的调试器当做一个"黑匣子",不过在使用过程中也会遇到一些与我们思路相悖的现象,所以作者这里用一篇文章带大家了解一下调试器的一般处理过程以便在了解调试器的原理上来解释相关现象。
2、JTAG接口
我们平时使用的jlink调试器就是使用JTAG接口,JTAG以前是用于测试芯片的一种通信方式,现在部分ARM或者DSP等都存在JTAG接口,这样我们就可以通过JTAG接口访问CPU以及其内部状态信息等,JTAG接口其通信信号为JTAG信号,JTAG信号在IEEE相关标准中必须要有TCK、TMS、TDI,TDO四个信号,TRST和STCK不做强制要求。说实在的这几个信号非常类似于SPI信号,而且其JTAG数据传输也是通过数据移位的方式。
如上图所示芯片的的JTAG接口为了提高访问效率设计了转移状态机,这样就能快速访问到芯片内部相应的寄存器,完成调试数据的传输,从而我们的KEIL或者IAR就能通过界面上看到相应状态寄存器及数据等。
3、边界扫描链
我们1)小节说的状态机需要与芯片内部交互,那么实际上是通过边界扫描链进行物理上的串行移位的方式输入或者输出相应的内部状态信息。如下图所示处理器的周围红色区域即为边界扫描链,边界扫描链是由一个个移位寄存器连接而成,并且一般芯片中存在多条,不同的扫描链对应着不同的功能,比如说一些扫描链用于访问内存或者处理器中的数据,有些扫描链用于设置或者访问内部debug模块等。
由于我们扫描链只能访问CPU外围的相关状态信息,对于CPU内部信息需要用另外一种方式,通过JTAG接口传输相关命令让CPU执行相关命令把内部寄存器的数据转移到TAP可以直接访问的位置,然后传递出来,同时也可以通过相关指令把相应数据写入到CPU寄存器中。我们平时在IDE中调试界面看到的全局变量的数据,就是通过在TAP可以访问的位置放置内存的地址,然后让CPU执行相关命令读取地址访问内存并把数据放到TAP可以访问的位置后传输出来直到IDE中显示。
4、调试器进行程序调试过程
我们的程序一般分为在RAM和FLASH上调试运行,然后调试器的下载程序过程是不同的,我们都知道对于内部RAM我们的CPU是可以直接访问的,其RAM直接连接在数据总线、地址总线和控制总线上,并且其接口都是标准化的,那么如果我们把程序放在RAM上运行通过JTAG直接下载程序到RAM运行,然后复位CPU进行调试运行即可,可是由于芯片中的FLASH型号等差异较大,并且对于FLASH的读、写擦除都需要特殊的命令,不同型号存在着较大的差异,所以如果进行FLASH上运行调试程序还不能像RAM上运行一样处理。
那么目前的KEIL,IAR等等IDE工具是如何下载并在FLASH中调试程序的呢?我们熟悉KEIL、IAR进行开发的小伙伴应该知道,我们在进行JLink调试的时候会有一个选择FLASH类型的对话框,(如下图所示)。
那么我们可以大致猜想一下,由于FLASH的驱动不一样,我们进行把对应的FLASH驱动下载到芯片中,然后根据下载的驱动对FLASH进行操作把我们的程序烧录进入即可进行调试了,这里我们一般都会把该驱动程序叫做FlashLoader,我们平时比较熟悉的是BootLoader,其实两种其实原理都是差不多,其中下载部分都是接受程序数据,然后写入到对应的FLASH中,只是两者在通讯方式和作用有所区别罢了,那么我绘制一个大体的过程给大家参考学习:
通过上面的图我们应该清楚的了解到了通过jlink一般如何把固件烧录到FLASH上进行仿真运行的了,然而这个思路我们也可以用在我们的实际开发过程中比如不同芯片的升级软件开发等,来为我们所用。
5、最后小节一下
上面的知识限于篇幅没有讲得太深,很东西可能在我们的开发过程也用不到,大致了解一下其过程即可,如果以后讨论相关问题可以再另外寻找相关资料进行阅读理解。其实说白了JTAG就是一种通信协议,根据该通信协议发送相关命令等通过芯片内部处理便可访问芯片内部状态或者修改相应数据等,如果我们程序全速运行的话其调试模式和脱机模式基本上是一样的性能,不过遇到了断点就需要分情况讨论相关问题了,对于需要连贯操作的通信及相关任务处理等会造成实效或者错乱,比如串口通信当正在接受过程中被断点打断可能就会丢失本帧数据等,大家要注意下。
好了,这里是公众号:“最后一个bug“,感谢大家关注与分享,有什么疑问可以随时向作者咨询,后续将继续为大家带来更实用的编程技巧和技术知识。