摘 要: 在研究了JTAG調(diào)試原理和ARM920T調(diào)試模型的基礎(chǔ)上,提出了Linux系統(tǒng)下NAND Flash在線燒寫系統(tǒng)的軟硬件實(shí)現(xiàn)方案。硬件采用了簡(jiǎn)易并口JTAG,軟件分為4個(gè)層次。程序在Linux系統(tǒng)下成功編譯并運(yùn)行,實(shí)現(xiàn)了Flash的在線編程。
??? 關(guān)鍵詞: Linux;JTAG;Flash;燒寫系統(tǒng)
?
?? 隨著電子技術(shù)的迅速發(fā)展,芯片以及系統(tǒng)越來(lái)越復(fù)雜,體積越來(lái)越小,系統(tǒng)測(cè)試、故障排除的難度和成本不斷增加,邊界掃描技術(shù)為以上問(wèn)題提供了一個(gè)行之有效的解決途徑。IEEE 1149.1標(biāo)準(zhǔn)俗稱JTAG調(diào)試標(biāo)準(zhǔn),最初由JTAG(Joint Test Action Group)小組提出,最終由IEEE 批準(zhǔn)并標(biāo)準(zhǔn)化。人們一般用JTAG代表IEEE 1149.1規(guī)范。JTAG調(diào)試標(biāo)準(zhǔn)極大地推動(dòng)了邊界掃描技術(shù)的發(fā)展,在電子產(chǎn)品設(shè)計(jì)及調(diào)試的各個(gè)階段得到廣泛應(yīng)用。
1 JTAG調(diào)試原理
1.1 邊界掃描技術(shù)
邊界掃描是邊界掃描技術(shù)的核心概念,其基本思想是在芯片的輸入輸出管腳上增加一些邊界掃描寄存器單元(boundary-scan register cell),邊界掃描寄存器單元其實(shí)是移位寄存器單元。芯片有兩種工作狀態(tài):調(diào)試狀態(tài)和正常運(yùn)行狀態(tài)。調(diào)試狀態(tài)下,邊界掃描寄存器單元將芯片與外圍的輸入輸出隔離開(kāi),通過(guò)這些邊界掃描寄存器單元可以實(shí)現(xiàn)芯片輸入輸出信號(hào)的觀察與控制。對(duì)于芯片輸入管腳,通過(guò)與之相連的邊界掃描寄存器單元可把信號(hào)加載到該管腳中去;對(duì)芯片輸出管腳,通過(guò)與之相連的邊界掃描寄存器單元可實(shí)現(xiàn)對(duì)該管腳上的輸出信號(hào)的捕獲(capture)。正常運(yùn)行狀態(tài)下邊界掃描寄存器單元對(duì)芯片來(lái)說(shuō)是透明的,對(duì)芯片的正常工作不會(huì)造成任何影響[1]。這樣邊界掃描寄存器就提供了一個(gè)便捷的方式實(shí)現(xiàn)芯片輸入輸出信號(hào)的觀察和控制。此外,芯片輸入輸出引腳上的邊界掃描寄存器單元可以相互串起來(lái)在芯片周圍形成一個(gè)邊界掃描鏈。一般芯片中會(huì)提供幾條邊界掃描鏈,實(shí)現(xiàn)數(shù)據(jù)的串行輸入和輸出,在時(shí)鐘信號(hào)和控制信號(hào)的作用下,方便地觀察和控制調(diào)試狀態(tài)下的芯片。
芯片在調(diào)試狀態(tài)與正常運(yùn)行狀態(tài)由不同的時(shí)鐘信號(hào)驅(qū)動(dòng):正常運(yùn)行時(shí)由系統(tǒng)主時(shí)鐘(MCLK)驅(qū)動(dòng),調(diào)試狀態(tài)下由調(diào)試時(shí)鐘(DCLK)驅(qū)動(dòng)[2]。調(diào)試時(shí)鐘DCLK一般要比系統(tǒng)主時(shí)鐘MCLK慢。
1.2 TAP(Test Access Port)
??? 邊界掃描鏈可實(shí)現(xiàn)數(shù)據(jù)的輸入輸出,從而實(shí)現(xiàn)對(duì)芯片的觀測(cè)與控制。TAP是一個(gè)通用端口,并在IEEE1149.1標(biāo)準(zhǔn)中定義,實(shí)現(xiàn)對(duì)邊界掃描鏈的控制。IEEE1149.1標(biāo)準(zhǔn)里,寄存器分為數(shù)據(jù)寄存器(DR)和指令寄存器(IR)。邊界掃描鏈只是數(shù)據(jù)寄存器中的一種。TAP提供了4個(gè)強(qiáng)制信號(hào)TDI、TDO、TMS、TCK和一個(gè)可選信號(hào)TRST。通過(guò)這些控制信號(hào)實(shí)現(xiàn)對(duì)數(shù)據(jù)寄存器(DR)和指令寄存器(IR)的訪問(wèn)。JTAG結(jié)構(gòu)示意圖如圖1所示。
?
??? (1)TCLK(Test Clock Input):TAP時(shí)鐘驅(qū)動(dòng)信號(hào)。
??? (2)TMS(Test Mode Select):TAP的模式選擇信號(hào),用來(lái)控制狀態(tài)機(jī)的轉(zhuǎn)換。
??? (3)TDI(Test Data Input):數(shù)據(jù)串行輸入接口。
??? (4)TDO(Test Data Output):數(shù)據(jù)串行輸出端口。
??? (5)TRST(Test Reset Input):TAP Controller復(fù)位信號(hào)。
??? TAP是芯片與仿真器的接口,對(duì)芯片的任何訪問(wèn)都是通過(guò)TAP來(lái)實(shí)現(xiàn)。TAP Controller通過(guò)TMS控制信號(hào)和TCLK時(shí)鐘驅(qū)動(dòng)信號(hào)實(shí)現(xiàn)狀態(tài)轉(zhuǎn)換,其狀態(tài)轉(zhuǎn)換機(jī)如圖2所示[1]。狀態(tài)轉(zhuǎn)換機(jī)共有16個(gè)狀態(tài),每一個(gè)狀態(tài)在TCLK上升沿根據(jù)TMS信號(hào)的高低電平來(lái)決定是否進(jìn)入下一個(gè)狀態(tài)。
通過(guò)TAP訪問(wèn)數(shù)據(jù)寄存器(DR)的步驟為:(1)通過(guò)指令寄存器(IR)選擇待訪問(wèn)的數(shù)據(jù)寄存器;(2)指定的數(shù)據(jù)寄存器連接在TDI和TDO之間;(3)在時(shí)鐘信號(hào)TCLK的驅(qū)動(dòng)下,由TDI實(shí)現(xiàn)新數(shù)據(jù)輸入,由TDO實(shí)現(xiàn)數(shù)據(jù)輸出[3]。
2 ARM920T調(diào)試系統(tǒng)
ARM920T處理器與調(diào)試相關(guān)的模塊有ARM CPU core(提供調(diào)試的硬件支持)、Embedded ICE(產(chǎn)生調(diào)試中斷,設(shè)置斷點(diǎn)和觀察點(diǎn))和TAP Controller等。
?ARM920T常用掃描鏈[2]有:
??? Scan chain 0,長(zhǎng)度為184 bit,可實(shí)現(xiàn)芯片連接檢查和芯片內(nèi)部邏輯測(cè)試。
??? Scan chain 1,長(zhǎng)度為67 bit,其中包括32 bit數(shù)據(jù)位、32 bit指令位和3 bit控制信號(hào)。
??? Scan chain 2,可訪問(wèn)EmbeddedICE中的硬件寄存器。
??? Scan chain 3,長(zhǎng)度用戶自定義,可以訪問(wèn)外部邊界掃描鏈。默認(rèn)使用的掃描鏈。
??? Scan chain 6,包括32 bit數(shù)據(jù)位、7 bit地址位、1 bit讀寫控制位,可對(duì)ETM9中的寄存器編程。
ARM920T中常用指令有:
??? IDCODE(b1110):主要用來(lái)讀取CPU ID號(hào)。
??? SCAN_N(b0010):主要用來(lái)實(shí)現(xiàn)不同掃描鏈的選擇,ARM920T默認(rèn)選擇掃描鏈3。
??? EXTEST(b0000):將掃描鏈置于外部測(cè)試模式。
??? INTEST(b1100):將掃描鏈置于內(nèi)部測(cè)試模式。
??? RESTART(0100):使ARM920T處理器由調(diào)試態(tài)返回正常運(yùn)行態(tài)。
3 燒寫系統(tǒng)實(shí)現(xiàn)
NAND Flash燒寫系統(tǒng)分為硬件系統(tǒng)和軟件系統(tǒng)。硬件系統(tǒng)負(fù)責(zé)JTAG協(xié)議轉(zhuǎn)換,實(shí)現(xiàn)對(duì)TAP的硬件控制;軟件系統(tǒng)負(fù)責(zé)JTAG工作時(shí)序的模擬以及TAP的軟件控制,是燒寫系統(tǒng)的核心。
3.1 硬件實(shí)現(xiàn)
一般JTAG仿真器并不具有Flash燒寫功能,且其價(jià)格比較昂貴,因此文中采用了目前較為流行且比較簡(jiǎn)單的WIGGLER小板,實(shí)現(xiàn)JTAG Flash在線燒寫的硬件支持。這種WIGGLER小板是一種簡(jiǎn)易并口JTAG,可方便地實(shí)現(xiàn)并口對(duì)TAP的直接控制。硬件原理圖如圖3所示。其中74HC244是一款三態(tài)緩沖器,其作用是實(shí)現(xiàn)電平轉(zhuǎn)換。
3.2 軟件實(shí)現(xiàn)
軟件系統(tǒng)總體上分為4個(gè)層次:并口驅(qū)動(dòng)層、JTAG控制層、數(shù)據(jù)處理層以及應(yīng)用程序層。軟件的層次結(jié)構(gòu)如圖4所示。
并口驅(qū)動(dòng)層實(shí)現(xiàn)軟件最底層的操作,本軟件基本的思想就是通過(guò)對(duì)PC機(jī)上標(biāo)準(zhǔn)并口的直接操作實(shí)現(xiàn)對(duì)TAP的控制,從而達(dá)到觀測(cè)和控制芯片的目的。JTAG控制層是整個(gè)軟件的關(guān)鍵部分,它利用并口驅(qū)動(dòng)層底層操作接口,實(shí)現(xiàn)TAP操作和狀態(tài)機(jī)不同狀態(tài)的循環(huán)控制。數(shù)據(jù)處理層相對(duì)于底層和上層的功能,可視為數(shù)據(jù)處理緩沖層,這一層并沒(méi)有牽扯到任何底層的操作,僅是為了方便應(yīng)用程序的實(shí)現(xiàn),定義了一些關(guān)鍵的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)處理函數(shù)。應(yīng)用程序?qū)邮擒浖诵墓δ軐?shí)現(xiàn)層,主要實(shí)現(xiàn)了NAND Flash工作時(shí)序的軟件模擬以及有關(guān)的讀、寫及擦除等操作。
3.2.1 Linux下并口操作
Linux程序運(yùn)行在保護(hù)模式下,不能直接對(duì)并口進(jìn)行操作,可通過(guò)函數(shù)調(diào)用ioperm(unsigned long port,unsigned long num, bool on_off)來(lái)獲得并口的訪問(wèn)權(quán)。參數(shù)port代表要訪問(wèn)并口的地址,在程序中共定義了三個(gè)并口地址:#define LPT1 0x378、#define LPT2 0x278和#define LPT3 0x3bc;參數(shù)num代表連續(xù)的端口數(shù)目,一般包括數(shù)據(jù)寄存器端口、控制寄存器端口和狀態(tài)寄存器端口;邏輯變量on_off代表對(duì)端口操作方式,1代表打開(kāi)0代表關(guān)閉。并口可用性可通過(guò)向端口寫入數(shù)據(jù)再讀回?cái)?shù)據(jù)的方式來(lái)檢查,讀回的數(shù)據(jù)如果和寫入的數(shù)據(jù)相同則端口可用。并口驅(qū)動(dòng)層提供的訪問(wèn)接口有:
int Getvalidppt(void);?????? //取得可用并口地址
??? void Setpptcompmode(void);?? //設(shè)置并口工作模式
此外還有兩個(gè)宏定義:
??? #define Outputppt(value) outb(unsigned long validPort,value) //并口數(shù)據(jù)輸出
??? #define Inputppt() inb((unsigned long) (validPpt+0x1))??????? //并口數(shù)據(jù)讀入
3.2.2 JTAG控制層
??? JTAG控制層主要實(shí)現(xiàn)TAP CONTROLLER控制,其中涉及TCK、TMS、TDI、TDO 4個(gè)控制信號(hào)和狀態(tài)機(jī)的實(shí)現(xiàn)。輸出信號(hào)控制接口由如下宏實(shí)現(xiàn):
??? #define JTAG_SET(value) Outputppt(value)
其中value為輸出數(shù)據(jù),組合模式為TDI|TMS|TCK,TDI、TMS、TCK分別有兩種狀態(tài),如:TDI_H、TDI_L,TMS_H、TMS_L,TCK_H、TCK_L,分別代表三種信號(hào)的高低電平。
??? 輸入信號(hào)(TDO)接口由如下宏實(shí)現(xiàn):
??? #define JTAG_GET_TDO() ((Inputppt()&(1<<7)) ? LOW:HIGH )
??? TDO輸出信號(hào)與狀態(tài)寄存器第7位相連,此位使用了反相器,故在讀入數(shù)據(jù)時(shí)需要取反。
??? JTAG控制層利用TAP Controller狀態(tài)控制機(jī)主要實(shí)現(xiàn)數(shù)據(jù)的輸出與輸入、指令的輸入、CPU ID號(hào)的讀取等功能。主要的接口函數(shù)有:
??? void JTAG_Shiftdrstate(char *wrDR, char *rdDR);
//同時(shí)實(shí)現(xiàn)數(shù)據(jù)輸出與讀入
??? void JTAG_Shiftdrstatenotdo(char *wrDR);
??? void JTAG_Shiftirstate(char *wrIR);//指令輸出
??? void JTAG_Readid(void); //讀取CPU ID
訪問(wèn)指令寄存器的狀態(tài)轉(zhuǎn)換流程為:
??? Run-Test/Idle->Select-DR-Scan->Select-IR-Scan->Capture-IR->Shift-IR->Exit-IR->Update-IR-> Run-Test/Idle
??? 數(shù)據(jù)寄存器由指令寄存器中的當(dāng)前指令決定,訪問(wèn)數(shù)據(jù)寄存器的狀態(tài)轉(zhuǎn)換流程為:
??? Run-Test/Idle->Select-DR-Scan->Capture-DR->Shift-DR->Exit-DR->Update-DR-> Run-Test/Idle
??? 函數(shù)JTAG_ShiftDRState()同時(shí)實(shí)現(xiàn)數(shù)據(jù)讀入、讀出,其程序流程圖如圖5所示。
3.2.3 數(shù)據(jù)處理層
邊界掃描單元在使用前需要初始化,邊界掃描單元的數(shù)目即為邊界掃描鏈的長(zhǎng)度,s3c2410處理器的邊界掃描鏈的長(zhǎng)度為426。處理器的每個(gè)引腳都對(duì)應(yīng)一個(gè)邊界掃描單元,每個(gè)引腳可視為邊界掃描單元的索引,s3c2410處理器有272個(gè)引腳。對(duì)邊界掃描單元的初始化即是對(duì)處理器引腳賦初值。初始化數(shù)據(jù)放在邊界掃描鏈數(shù)組中,有如下定義:
??? char outcelldata[SC2410_MAX_CELL_INDEX+2];
??? char incelldata[SC2410_MAX_CELL_INDEX+2];
??? 數(shù)組outcelldata[]存放待輸出數(shù)據(jù),incelldata[]存放讀入數(shù)據(jù),數(shù)組的每個(gè)單元對(duì)應(yīng)一個(gè)邊界掃描單元。其中SC2410_MAX_CELL_INDEX為s3c2410處理器邊界掃描單元的數(shù)目426。
??? s3c2410處理器數(shù)據(jù)寬度為32位,地址線27位,為便于數(shù)據(jù)、地址的統(tǒng)一處理定義如下3個(gè)數(shù)組:
??? int? dataoutcellindex[32];
??? int? dataincellindex[32];
??? int? addrcellindex[27];
??? 數(shù)據(jù)輸出與讀入對(duì)應(yīng)不同邊界掃描單元,如:DATA0讀入對(duì)應(yīng)的掃描單元索引為100,輸出對(duì)應(yīng)的掃描單元的索引為99。將數(shù)據(jù)輸出掃描單元的索引組合到具有32個(gè)元素的數(shù)組(dataoutcellindex)中,便于數(shù)據(jù)輸出掃描單元的引用;將數(shù)據(jù)讀入掃描單元的索引組合到具有32個(gè)元素的數(shù)組(dataincellIndex)中,便于數(shù)據(jù)讀入掃描單元的引用;將地址輸出掃描單元的索引組合到具有27個(gè)元素的數(shù)組(addrcellindex)中,便于地址輸出掃描單元的引用。比如數(shù)據(jù)位DATAO要輸出低電平,數(shù)組引用方式如下:
??? outcelldata [dataOutCellIndex[0]]=LOW;
??? 從DATA0讀入一位數(shù)據(jù),數(shù)組的引用方式如下:
??? incelldata[dataInCellIndex[0]]=JTAG_GET_TDO();
??? 數(shù)據(jù)處理層主要接口函數(shù)有:
??? void SC2410_Initcell(void); //邊界掃描單元初始化
??? void SC2410_Setpin(int index, char value);
//處理器引腳電平的設(shè)置
??? char SC2410_Getpin(int index);?? //引腳信號(hào)的讀入
??? void SC2410_Setaddr(U32 addr);?? //設(shè)置地址數(shù)據(jù)
??? void SC2410_Setdatabyte(U8 data);//寫字節(jié)數(shù)據(jù)
??? U8 SC2410_Getdatabyte(void);???? //讀字節(jié)數(shù)據(jù)
3.2.4 應(yīng)用程序?qū)?BR>??? 應(yīng)用程序?qū)又饕獙?shí)現(xiàn)NAND Flash的讀、寫及擦除等上層操作。以K9F1208為例,NAND Flash一般的操作流程是:先向Flash芯片發(fā)操作命令,再發(fā)操作地址,如果Flash芯片準(zhǔn)備就緒再進(jìn)行數(shù)據(jù)的讀/寫或芯片的擦除等操作。K9F1208主要控制信號(hào)有:CLE(芯片命令鎖存,高電平有效)、ALE(地址鎖存,高電平有效)、WE(芯片寫操作,低電平有效)、RE(芯片讀操作,低電平有效)、CE(芯片使能)、R/B(芯片狀態(tài)指示,高電平代表芯片就緒,低電平代表芯片忙)、IO(0~7)數(shù)據(jù)輸入/輸出端口。程序主要接口函數(shù)有:
??? NF_CMD():實(shí)現(xiàn)Flash寫命令操作。
??? NF_ADDR():實(shí)現(xiàn)Flash地址輸出。
??? NF_WRDATA():實(shí)現(xiàn)數(shù)據(jù)寫。
??? NF_RDDATA():實(shí)現(xiàn)數(shù)據(jù)讀。
??? 參考K9F1208芯片寫命令操作時(shí)序,NF_CMD() Flash寫命令函數(shù)實(shí)現(xiàn)為:設(shè)CE片選信號(hào)有效;命令鎖存信號(hào)CLE有效同時(shí)無(wú)效地址鎖存信號(hào)ALE;寫信號(hào)WE有效同時(shí)無(wú)效讀信號(hào)RE;輸出命令;最后無(wú)效WE信號(hào)實(shí)現(xiàn)命令鎖存。其他相關(guān)函數(shù)的實(shí)現(xiàn)都是以軟件的方式模擬NAND Flash的硬件工作時(shí)序,其實(shí)現(xiàn)方法與Flash寫命令函數(shù)NF_CMD()相似。
3.3 測(cè)試及實(shí)驗(yàn)
??? 燒寫軟件在Linux系統(tǒng)下編譯成功,在命令行輸入“./zjx_sjf_linux /f:interrupt.bin”,燒寫程序開(kāi)始運(yùn)行,運(yùn)行界面如圖6所示。其中zjx_sjf_linux是應(yīng)用程序名,/f:為命令行參數(shù),interrupt. bin為待燒寫程序。
??? 從圖6可以看出程序能夠成功運(yùn)行且能夠?qū)崿F(xiàn)程序在Linux系統(tǒng)下的燒寫。
??? 本文研究了JTAG標(biāo)準(zhǔn)和ARM920T,介紹了NAND Flash在Linux系統(tǒng)下燒寫系統(tǒng)的軟硬件實(shí)現(xiàn)方案。硬件采用了簡(jiǎn)易并口JTAG,軟件部分給出了系統(tǒng)的設(shè)計(jì)架構(gòu)、功能模塊和實(shí)現(xiàn)接口。并口JTAG燒寫Flash,速度有較大的限制,進(jìn)一步的工作就是改善Flash的燒寫速度,提高Flash燒寫效率。
參考文獻(xiàn)
[1] IEEE1149.1. IEEE standard test access port and boundary-
scan architecture [S]. 2001.
[2] ARM Corp. ARM920T Technical Reference Manual. http://www.arm.com.
[3] OPEN-JTAG開(kāi)發(fā)小組.ARM JTAG調(diào)試原理[Z].2007.
[4] 陸晗,潘雪增.基于ARM的JTAG調(diào)試器[J].計(jì)算應(yīng)用與軟件,2007,24(2).
?