JTAG最初是用來對(duì)芯片進(jìn)行測試的,基本原理是在器件內(nèi)部定義一個(gè)TAP(Test Access Port?測試訪問口)通過專用的JTAG測試工具對(duì)進(jìn)行內(nèi)部節(jié)點(diǎn)進(jìn)行測試。JTAG測試允許多個(gè)器件通過JTAG接口串聯(lián)在一起,形成一個(gè)JTAG鏈,能實(shí)現(xiàn)對(duì)各個(gè)器件分別測試。現(xiàn)在,JTAG接口還常用于實(shí)現(xiàn)ISP(In-System Programmable?在線編程),對(duì)FLASH等器件進(jìn)行編程。
JTAG編程方式是在線編程,傳統(tǒng)生產(chǎn)流程中先對(duì)芯片進(jìn)行預(yù)編程實(shí)現(xiàn)再裝到板上因此而改變,簡化的流程為先固定器件到電路板上,再用JTAG編程,從而大大加快工程進(jìn)度。JTAG接口可對(duì)PSD芯片內(nèi)部的所有部件進(jìn)行編程
簡單地說,JTAG的工作原理可以歸結(jié)為:在器件內(nèi)部定義一個(gè)TAP(TestAccessPort,測試訪問口),通過專用的JTAG測試工具對(duì)內(nèi)部節(jié)點(diǎn)進(jìn)行測試和調(diào)試。
邊界掃描
邊界掃描(Boundary-Scan)即在芯片的每個(gè)輸入輸出管腳上都增加一個(gè)移位寄存器單元(Boundary-Scan Register Cell),因?yàn)檫@些移位寄存器單元分布在芯片的邊界上,所以被稱為邊界掃描寄存器。在JTAG 調(diào)試中,邊界掃描是一個(gè)很重要的概念,當(dāng)需要調(diào)試芯片時(shí),這些寄存器將芯片與外圍電路隔離,實(shí)現(xiàn)對(duì)芯片輸入輸出信號(hào)的觀察和控制:對(duì)于輸入管腳,可以通過與之相連的邊界掃描寄存器單元把數(shù)據(jù)加載到該管腳中;對(duì)于輸出管腳,可以通過與之相連的邊界掃描寄存器“捕獲”(CAPTURE)該管腳上的輸出信號(hào);正常運(yùn)行狀態(tài)下,這些邊界掃描寄存器單元對(duì)芯片是透明的,所以正常的運(yùn)行不會(huì)受到影響。另外,芯片輸入輸出管腳上的邊界掃描(移位)寄存器單元可以相互連接起來,在芯片的周圍形成一個(gè)邊界掃描鏈(Boundary-Scan Chain),它可以串行的輸入和輸出,通過相應(yīng)的時(shí)鐘信號(hào)和控制信號(hào),實(shí)現(xiàn)對(duì)處在調(diào)試狀態(tài)下的芯片的輸入和輸出狀態(tài)的觀察和控制。
在CPU外圍,處理器內(nèi)部包含了JTAG的硬件實(shí)現(xiàn),并且向外界提供接口,也就是上面所說的TMS、TCK、TDI、TDO四個(gè)引腳。
這里的CPU:是指運(yùn)算處理單元,只包含了內(nèi)部寄存器以及運(yùn)算單元等基本部件。
這里的處理器:是指CPU 擴(kuò)展芯片,不是SoC。
JTAG如何用于芯片測試呢? 其中用到的最主要部件就是邊界掃描鏈。命名為邊界掃描鏈,是由于它位置處于處理器的邊界上。
我們知道CPU是通過引腳與外圍交流的,所有的數(shù)據(jù)都會(huì)通過引腳輸入或者輸出,而JTAG就是通過監(jiān)控引腳的信號(hào)達(dá)到芯片測試的目的。而邊界掃描鏈就是在引腳上的一個(gè)部件。如下圖:
通過邊界掃描鏈,當(dāng)有信號(hào)輸入的時(shí)候,邊界掃描鏈就能獲取信號(hào),當(dāng)CPU要輸出信號(hào)的時(shí)候,邊界掃描鏈也能獲取要輸出的信號(hào)。另外,也可以通過邊界掃描鏈來直接向外部輸出信號(hào)。
無論是信號(hào)的抓取還是輸出,都需要有接口來保存這些信號(hào),TDI 跟 TDO 就是做這樣一些工作的。如圖:
本來邊界掃描鏈保存著引腳上的信號(hào),當(dāng)通過TDI引腳輸入我們自己的信號(hào)的時(shí)候,會(huì)發(fā)生沿上面紅線方向的移位操作,
TDI ——〉 邊界掃描鏈 —— 〉 TDO
就能從TDO獲取邊界掃描鏈上的信號(hào),我們從TDI輸入的信號(hào)也會(huì)到邊界掃描鏈上去。
在CPU跟外界通信的引腳上的數(shù)據(jù)無非就是 指令 跟 數(shù)據(jù)信號(hào)(包括地址跟數(shù)據(jù)) 兩種。但是這兩者的結(jié)合形成了一個(gè)完整的程序,能對(duì)它們進(jìn)行監(jiān)控就表明我們能進(jìn)行程序的調(diào)試。一般的芯片都會(huì)提供幾條獨(dú)立的邊界掃描鏈,對(duì)邊界掃描鏈的控制主要是通過 TAP(Test Access Port) Controller來完成的。
上面的只是jtag最基本的原理,要對(duì)程序更好的調(diào)試還需要控制部件,還有更多寄存器的結(jié)合等等。
下面是一個(gè)完整的jtag調(diào)試部件:
下面來講講arm上的jtag調(diào)試,openocd就是一個(gè)jtag的調(diào)試工具
我們在調(diào)試程序的時(shí)候,通常需要設(shè)置斷點(diǎn),斷點(diǎn)也就是指令所在的位置,
斷點(diǎn)分為兩種:硬件斷點(diǎn)跟軟件斷點(diǎn)
硬件斷點(diǎn):指令的地址。當(dāng)cpu要去某個(gè)地址取指令的時(shí)候,就暫停cpu的運(yùn)行。在s3c2440上只支持兩個(gè)硬件斷點(diǎn)
軟件斷點(diǎn):軟件斷點(diǎn)不限制斷點(diǎn)的個(gè)數(shù),因此硬件斷點(diǎn)的方法是不可用的。當(dāng)我們需要在某個(gè)指令上打斷點(diǎn)的時(shí)候,openocd會(huì)先去取得斷點(diǎn)的地址,然后把每個(gè)斷點(diǎn)處的值替換成某個(gè)特定的值(如deeedeee),當(dāng)cpu取數(shù)據(jù)的時(shí)候得到該特定的值,就知道到達(dá)了斷點(diǎn)地址,暫停cpu的運(yùn)行,去除斷點(diǎn)的時(shí)候再把原本的值換回去。如果沒指定硬件斷點(diǎn)的話,一般都默認(rèn)是軟件斷點(diǎn)。
另外openocd對(duì)于軟件斷點(diǎn)有特定的要求:
1.程序必須位于它的鏈接地址上,即如果指定了。 = 0x30000000,那么程序必須實(shí)際上是位于0x30000000這個(gè)地方,也就是說程序必須已經(jīng)重定位好,位于它的鏈接地址。
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調(diào)試就是基于軟件斷點(diǎn)的調(diào)試,我們可以用gdb對(duì)程序代碼的某一行進(jìn)行斷點(diǎn)設(shè)置,那么它是如何定位到某個(gè)指令的地址的?
這就需要有調(diào)試信息,也就是在編譯的時(shí)候加上 -g 給程序添加調(diào)試信息。
eclipse對(duì)gdb進(jìn)行了進(jìn)一步的封裝(GUI),我們可以通過對(duì)eclipse進(jìn)行某些設(shè)置達(dá)到調(diào)試arm程序的目的。
1.首先把文件加入工程
2.設(shè)置調(diào)試配置:
點(diǎn)工具欄上的小蟲子
Debug Configurations.。。
新建一個(gè)調(diào)試配置
選擇選項(xiàng)卡Main,在C/C++ Application: 選項(xiàng)上選擇要調(diào)試的elf文件
選擇選項(xiàng)卡Debugger,GDB debugger: 選擇為arm-elf-gdb
選擇選項(xiàng)卡Commands, ‘Initialize’conmmands 下輸入命令:
target remote 127.0.0.1:3333 //連接openocd
load //加載程序到內(nèi)存
break _start //設(shè)置斷點(diǎn)到_start
c //continue繼續(xù)執(zhí)行
然后Apply ,最后Debug開始調(diào)試
3.當(dāng)然,上述程序是在內(nèi)存執(zhí)行的,但是開發(fā)板一開始的時(shí)候內(nèi)存還沒初始化,是不可用的,因此我們需要先設(shè)置內(nèi)存
在openocd的命令控制臺(tái)上(telnet 127.0.0.1 4444進(jìn)入openocd控制臺(tái))
halt //暫停cpu
load_image init.bin 0 //加載內(nèi)存初始化程序 init.bin 到 0 地址
resume 0 //在0地址開始運(yùn)行
halt //暫停cpu
然后就可以Debug了
Debug時(shí),當(dāng)運(yùn)行到斷點(diǎn)處的時(shí)候,我們可以看到某些寄存器或者變量的值,這些值在eclipse上顯示:
測試訪問口TAP
TAP(TestAccessPort)是一個(gè)通用的端口,通過TAP 可以訪問芯片提供的所有數(shù)據(jù)寄存器(DR)和指令寄存器(IR)。對(duì)整個(gè)TAP的控制是通過TAP控制器(TAPController)來完成的。下面先 分別介紹一下TAP的幾個(gè)接口信號(hào)及其作用。其中,前4個(gè)信號(hào)在IEEE1149.1標(biāo)準(zhǔn)里是強(qiáng)制要求的。
TCK:時(shí)鐘信號(hào),為TAP的操作提供了一個(gè)獨(dú)立的、基本的時(shí)鐘信號(hào)。
TMS:模式選擇信號(hào),用于控制TAP狀態(tài)機(jī)的轉(zhuǎn)換。
TDI:數(shù)據(jù)輸入信號(hào)。
TDO:數(shù)據(jù)輸出信號(hào)。
TRST:復(fù)位信號(hào),可以用來對(duì)TAPController進(jìn)行復(fù)位(初始化)。這個(gè)信號(hào)接口在IEEE1149.1標(biāo)準(zhǔn)里并不是強(qiáng)制要求的,因?yàn)橥ㄟ^TMS也可以對(duì)TAPController進(jìn)行復(fù)位。
STCK:時(shí)鐘返回信號(hào),在IEEE1149.1標(biāo)準(zhǔn)里非強(qiáng)制要求。
簡單地說,PC機(jī)對(duì)目標(biāo)板的調(diào)試就是通過TAP接口完成對(duì)相關(guān)數(shù)據(jù)寄存器(DR)和指令寄存器(IR)的訪問。
系統(tǒng)上電后,TAPController 首先進(jìn)入 Test-LogicReset 狀態(tài),然后依次進(jìn)入Run-Test/Idle、Selcct-DR- Scan、Select-IR-Scan、Capture-IR、Shift-IR、Exitl-IR、Update-IR狀態(tài),最后回到 Run- Tcst/Idle 狀態(tài)。在此過程中,狀態(tài)的轉(zhuǎn)移都是通過TCK信號(hào)進(jìn)行驅(qū)動(dòng)(上升沿),通過TMS信號(hào)對(duì)TAP的狀態(tài)進(jìn)行選擇轉(zhuǎn)換的。其中,
在 Capture-IR狀態(tài)下,一個(gè)特定的邏輯序列被加載到指令寄存器中;
在Shift-IR狀態(tài)下,可以將一條特定的指令送到指令寄存器中;
在 Update—IR狀態(tài)下,剛才輸入到指令寄存器中的指令將用來更新指令寄存器。
最后,系統(tǒng)又回到Run—Test/Idle狀態(tài),指令生效,完成對(duì)指令寄存器的訪問。
當(dāng)系統(tǒng)又返回到Run—Test/Idle狀態(tài)后,根據(jù)前面指令寄存器的內(nèi)容選定所需要的數(shù)據(jù)寄存器,開始執(zhí)行對(duì)數(shù)據(jù)寄存器的工作。其基本原理與指令寄存器的訪問完全相同,依次為seIect—DR—Scan、Capture—DR、Shift—D、Exitl一DR、Update—DR, 最后回到 Run-Tcst/Idle 狀態(tài)。通過TDl和TDO,就可以將新的數(shù)據(jù)加載到數(shù)據(jù)寄存器中。經(jīng)過一個(gè)周期后,就可以捕獲數(shù)據(jù)寄存器中的數(shù)據(jù),完 成對(duì)與數(shù)據(jù)寄存器的每個(gè)寄存器單元相連的芯片引腳的數(shù)據(jù)更新,也完成了對(duì)數(shù)據(jù)寄存器的訪問。
Keil、IAR、DS-5、ADS開發(fā)工具軟件等都有一個(gè)公共的調(diào)試接口RDI,那么我們?nèi)绾瓮瓿?RDI -》JTAG調(diào)試協(xié)議的轉(zhuǎn)換呢?兩種做法:
在電腦上寫一個(gè)服務(wù)程序,把Keil、IAR、DS-5中的RDI命令解析成相關(guān)的JTAG協(xié)議,然后通后一個(gè)物理轉(zhuǎn)換接口(注意,這個(gè)轉(zhuǎn)換只是電氣物理層上的轉(zhuǎn)換,就像RS232那樣的作用)發(fā)送你的的目標(biāo)板。H-JTAG就是這樣的。H-JTAG的硬件就僅是一個(gè)物理電平的轉(zhuǎn)換接口,所以很簡單。 而電腦中裝的H-JTAG軟件就是前面說到的服務(wù)程序,負(fù)責(zé)協(xié)議轉(zhuǎn)換的。
做一個(gè)板,用此板直接接收來自Keil、IAR、DS-5等軟件的調(diào)試命令,由此板做RDI -》 JTAG協(xié)議的轉(zhuǎn)換。然后與目標(biāo)板通信,這就是JLINK、ULINK2等仿真器的工作原理。
由上可以看出,H-JTAG由于是軟件作協(xié)議轉(zhuǎn)換的,所以速度較慢,但是硬件簡單。而第二種方法的JLINK一般帶一個(gè)強(qiáng)勁的CPU,作硬件協(xié)議轉(zhuǎn)換,把以硬件復(fù)雜,但速度快。目前,市場上的JTAG接口仿真器有14引腳和20引腳兩種。其中,以20引腳為主流標(biāo)準(zhǔn),但也有少數(shù)的目標(biāo)板采用14引腳。經(jīng)過簡單的信號(hào)轉(zhuǎn)換后,可以將它們通用。
評(píng)論