JTAG基本原理與調試


JTAG(Joint Test Action Group)聯合測試行動小組)是一種國際標准測試協議(IEEE 1149.1兼容),主要用於芯片內部測試。現在多數的高級器件都支持JTAG協議,如DSP、FPGA器件等。標准的JTAG接口是4線:TMS、 TCK、TDI、TDO,分別為模式選擇、時鍾、數據輸入和數據輸出線。
 
  JTAG最初是用來對芯片進行測試的,基本原理是在器件內部定義一個TAP(Test Access Port?測試訪問口)通過專用的JTAG測試工具對進行內部節點進行測試。JTAG測試允許多個器件通過JTAG接口串聯在一起,形成一個JTAG鏈,能實現對各個器件分別測試。現在,JTAG接口還常用於實現ISP(In-System Programmable?在線編程),對FLASH等器件進行編程。
 
  JTAG編程方式是在線編程,傳統生產流程中先對芯片進行預編程實現再裝到板上因此而改變,簡化的流程為先固定器件到電路板上,再用JTAG編程,從而大大加快工程進度。JTAG接口可對PSD芯片內部的所有部件進行編程

 

上面的信息是從度娘百科引用過來的,對於jtag沒有了解過的人來說,上面的大部分內容都不知道說什么,當然,我是一開始看的時候也看不懂。

不過從上面得出來的信息知道,jtag是一個協議,標准有4個引腳,用於芯片的測試與編程調試。

 

jtag是有硬件實現的。

在cpu(注意:這里的cpu是指運算處理單元,只包含了內部寄存器以及運算單元等基本部件)外圍,處理器(即cpu擴展芯片,不是soc)內部包含了jtag的硬件實現,並且向外界提供接口,也就是上面所說的TMS,TCK,TDI,TDO,四個引腳。

如圖:

 

邊界掃描鏈

jtag如何用於芯片測試呢? 其中用到的最主要部件就是邊界掃描鏈。

命名為邊界掃描鏈,是由於它位置處於處理器的邊界上。

我們知道cpu是通過引腳與外圍交流的,所有的數據都會通過引腳輸入或者輸出,而jtag就是通過監控引腳的信號達到芯片測試的目的。

而邊界掃描鏈就是在引腳上的一個部件。如下圖:

 

通過邊界掃描鏈,當有信號輸入的時候,邊界掃描鏈就能獲取信號,當cpu要輸出信號的時候,邊界掃描鏈也能獲取要輸出的信號。

另外也可以通過邊界掃描鏈來直接向外部輸出信號。

無論是信號的抓取還是輸出,都需要有接口來保存這些信號,TDI跟TDO就是做這樣一些工作的。

如圖:

本來邊界掃描鏈保存着引腳上的信號,當通過TDI引腳輸入我們自己的信號的時候,會發生沿上面紅線方向的移位操作,

        TDI ——〉 邊界掃描鏈 —— 〉 TDO

就能從TDO獲取邊界掃描鏈上的信號,我們從TDI輸入的信號也會到邊界掃描鏈上去。

在cpu跟外界通信的引腳上的數據無非就是 指令 跟 數據信號(包括地址跟數據) 兩種。但是這兩者的結合形成了一個完整的程序,能對它們進行監控就表明我們能進行程序的調試。

 

上面的只是jtag最基本的原理,要對程序更好的調試還需要控制部件,還有更多寄存器的結合等等。

下面是一個完整的jtag調試部件:

更詳細的jtag信息可以看看http://www.micetek.com.cn/technic/jtag.pdf

 

 


下面來講講arm上的jtag調試,openocd就是一個jtag的調試工具

以下基於s3c2440,openocd

 

我們在調試程序的時候,通常需要設置斷點,斷點也就是指令所在的位置,

斷點分為兩種:硬件斷點跟軟件斷點

  硬件斷點:指令的地址。當cpu要去某個地址取指令的時候,就暫停cpu的運行。在s3c2440上只支持兩個硬件斷點

  軟件斷點:軟件斷點不限制斷點的個數,因此硬件斷點的方法是不可用的。當我們需要在某個指令上打斷點的時候,openocd會先去取得斷點的地址,然后把每個斷點處的值替換成某個特定的值(如deeedeee),當cpu取數據的時候得到該特定的值,就知道到達了斷點地址,暫停cpu的運行,去除斷點的時候再把原本的值換回去。如果沒指定硬件斷點的話,一般都默認是軟件斷點。

 

另外openocd對於軟件斷點有特定的要求:

  1.程序必須位於它的鏈接地址上,即如果指定了. = 0x30000000,那么程序必須實際上是位於0x30000000這個地方,也就是說程序必須已經重定位好,位於它的鏈接地址。

  2.程序必須按照某種特定的順序排放:

SECTIONS{

. = 0x30000000;
.text    :{
head.o(.text)
init.o(.text)
nand.o
*(.text)
}
.rodata ALIGN(4)    :    {*(.rodata)}
.data ALIGN(4)    :    {*(.data)}
.bss ALIGN(4)    :    {*(.bss)    *(COMMON)}
}

 

gdb調試就是基於軟件斷點的調試,我們可以用gdb對程序代碼的某一行進行斷點設置,那么它是如何定位到某個指令的地址的?

這就需要有調試信息,也就是在編譯的時候加上 -g 給程序添加調試信息。

 

eclipse對gdb進行了進一步的封裝(GUI),我們可以通過對eclipse進行某些設置達到調試arm程序的目的。

1.首先把文件加入工程

2.設置調試配置:

  點工具欄上的小蟲子

  Debug Configurations...

  新建一個調試配置

  選擇選項卡Main,在C/C++ Application:  選項上選擇要調試的elf文件

  選擇選項卡Debugger,GDB debugger: 選擇為arm-elf-gdb

  選擇選項卡Commands, 'Initialize'conmmands 下輸入命令:

 

    target remote 127.0.0.1:3333    //連接openocd

    load                //加載程序到內存

    break _start            //設置斷點到_start

    c        //continue繼續執行

 

  然后Apply ,最后Debug開始調試

3.當然,上述程序是在內存執行的,但是開發板一開始的時候內存還沒初始化,是不可用的,因此我們需要先設置內存

  在openocd的命令控制台上(telnet 127.0.0.1 4444進入openocd控制台)

 

    halt    //暫停cpu

    load_image  init.bin  0   //加載內存初始化程序 init.bin 到 0 地址

    resume  0    //在0地址開始運行

    halt  //暫停cpu

 

 

  然后就可以Debug了

 

Debug時,當運行到斷點處的時候,我們可以看到某些寄存器或者變量的值,這些值在eclipse上顯示:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM