最低成本的ARM除錯解決方案——有關於Wiggler、H-Jtag、OpenOCD、GDB

yazhouren發表於2017-06-22
origin: http://blog.sina.com.cn/s/blog_70bb32080100lx1u.html
又是一個多月沒有動這個Blog嘿嘿,我發現一個有趣的現象,我的Blog在每年的1月底到2月中旬,7月、8月是淡季,每天訪問量基本都在100以下,其它時間都是旺季,尤其9月和3月,每天可以到200以上,最高甚至500。我想因該是因為學生們是EE小站訪問的主力吧——9月和3月是開題的日子,這資料搜尋做的,哈哈。現在是淡季,祝大家假期愉快,多陪陪父母。我現在就很後悔,大學的時候放假都在學校研究東西,就算回家,也揹著全套的裝置回去……現在工作了,根本沒有時間回家看父母,唉。這段時間以來我一直在研究和除錯相關的東西,最開始是想給MPC8313找一個便宜的除錯方案,後來就找出來一大堆東西,但是就是沒有合適8313用的。今天寫的這個話題和學生們有很大關係,嘿嘿,怎樣用最低的成本除錯ARM,包括裸機除錯和除錯ARMLinux相關的東西。轉載請註明來自EE小站,郵件cosine@126.com
 
先給大家介紹個大概情況,現在國內都有什麼著名的ARM開發工具和解決方案,價格從高低排:
 
  • BDI1000/2000/3000
目前我知道的最牛X的除錯工具,可以除錯ARM、MIPS、PPC、ColdFire、XScale等多種處理器。無需更換硬體,只需要買不同的軟體授權就可以除錯不同的CPU。JTAG下載速度可以上兆,乙太網介面。因為太貴了(BDI2000好像要人民幣50000吧),我沒怎麼研究它到底配合什麼軟體來除錯,不過GDB它是肯定支援的,它一直是我心目中的神話啊。
  • J-Link原版
J-Link是IAR公司為ARM開發的除錯工具,支援RDI協議的除錯工具,如Keil、ADS、IAR等;支援GDB除錯;什麼SWD之類的用得很少,有沒有都一樣;但J-Link不支援ARM10以上的核心。JTAG下載的速度可以達到400~500K,正版價格大約5000人民幣(全功能)吧,這麼貴基本也不考慮了。
  • Multi-ICE原版
ARM公司的原創除錯工具,支援全系列ARM晶片,現在多少錢我也不知道了,反正在2000~3000人民幣這個級別。我這裡指的是國內做得比較好的那些,比如Realview之類的。僅僅支援ADS、SDT之類的裸奔程式碼除錯,JTAG下載速度130K左右。雖然這幾年Multi-ICE是國內ARM除錯絕對的霸主,但現在ARM公司已經停止對ADS的維護了,Multi-ICE會開始走向沒落。
  • Multi-ICE盜版
國內有很多Multi-ICE的盜版,功能和Multi-ICE原版一樣,並口的、USB的都有,價錢幾百塊人民幣,淘寶上到處都有。但是和J-Link盜版相比,不推薦購買。
  • J-Link盜版
最近這段時間,J-Link盜版漸漸開始多起來了,淘寶上也很多,功能和原版沒有區別。價格大約在幾百人民幣左右,從價效比來看,推薦購買。我之後還會寫一篇用J-Link除錯ARM的文章,當你入門之後,絕對無法忍受今天介紹的這個低成本方案的JTAG下載速度,那時就買個J-Link來爽爽。
  • U-Link盜版
U-Link是Keil公司做的用於ARM和某些增強型8051除錯的工具,由於Keil公司做U-Link的時候沒有加密,導致現在盜版滿天飛,只需要100多塊錢就可以買到一個。現在Keil已經被ARM收購,U-Link也是ARM一家的了。U-Link正版在盜版的排擠下,根本沒有什麼買的必要;U-Link僅僅支援Keil,而且JTAG下載速度僅有20~30K。
  • Wiggler電纜
Wiggler是世界上最氾濫的一種除錯工具,它非常簡單,只需要一片74HC244,一個9013,幾個電阻就可以。本來Wiggler是Macraigor(http://www.macraigor.com/)製作的,可以支援Macraigor的OCDRemote這個GDBServer,可以支援ARM、PPC、ColdFire、MIPS、XScale等多種CPU。後來因為它結構太簡單,被人破解後搞得全世界都是,於是Macraigor怒了,現在用OCDRemote必須是Macraigor原廠的Wiggler了……儘管如此,後人又在Wiggler的硬體基礎上開發了很多的除錯工具,例如H-Jtag;另外也有其他的除錯工具增加了對Wiggler的支援,例如OpenOCD。Wiggler電纜的成本特別低,當然它的效能也和成本一樣低;用H-Jtag下載速度大約20~30KB/s,用Linux虛擬機器下的OpenOCD下載速度大約2KB/s。不過對於囊中羞澀的學生們來說,是一個非常不錯的入門工具。本文就針對Wiggler進行介紹。
估計看這篇文章的人會有一些是從微控制器起步,轉到ARM上來的,我先梳理下各種CPU除錯的知識。
 
  • 從MCS-51/96、PIC之類的微控制器轉入ARM
這條路是學校教學比較傳統的路子。條件好點的學校開微控制器課的時候都有實驗,用實驗箱和模擬器做實驗,那種模擬器就是一種最早的CPU/MCU模擬器,模擬器通過模擬頭連線電路板,完全模擬CPU/MCU的功能;模擬器通過串列埠或者其他什麼口連線計算機,計算機上有集編譯器、偵錯程式為一體的整合開發環境,可以監控和執行程式。這種模擬器的成本一般比較高,而且模擬不同的CPU/MCU需要不同的硬體,結構也很複雜,使用軟體模擬的斷點。解釋下軟體模擬的斷點——就是用特殊的函式呼叫指令替換斷點所在位置的指令,這些特殊的函式具有和模擬器的監控軟體互動的功能。應該有很多的同學平時沒有條件用上這麼奢侈的裝置,多半是用的是ISP,採用“點燈大法”——就是藉助LED、串列埠之類的除錯程式,每修改一次程式就重新下載一次,除錯非常的艱苦。我剛開始玩微控制器的時候AT的89S52還沒有出來,我花一個月的生活費買了個燒寫器,每次改程式都把晶片撬下來放到燒寫器上,燒完再裝回去繼續點燈……
走這條路,要明白的事情有:ARM的暫存器可不是51那寥寥可數的幾個,是沒有必要也不可能背下來的;ARM晶片一般都內建了JTAG除錯邏輯,不需要CPU模擬器,需要的是一個JTAG協議轉接器(雖然現在大家還叫這種東西為模擬器);整合開發環境在使用者看來和微控制器的沒有任何區別,這點請放心。
  • 從AVR、C8051F之類有JTAG的微控制器轉入ARM
時代是不斷進步的,AVR、C8051F具有JTAG口的微控制器。JTAG(Joint TestActionGroup)組織定了一個最初是用於測試生產出來的晶片是不是良品的測試介面和標準,在晶片的各個管腳上放上鎖存器,然後串起來構成移位暫存器,可以監控晶片管腳的輸入和輸出;後來大家發現這東西用來搞晶片的線上除錯不錯,於是就出現了現在JTAG除錯風行的局面。再說的明白些,也就是利用JTAG可以控制CPU核心,每個CPU都可以成為自己的“模擬器”,而不需要專用的裝置。“人人都是食神。”——周星星語錄。從理論上來說,世界上只需要一種模擬器,哦,確切的說應該叫做JTAG協議轉換器,就可以除錯所有的相容JTAG標準的晶片;BDI2000這種超級貴的“模擬器”以及Wiggler這種什麼都通吃的便宜貨的存在是很合理的事情。
走這條路,應該已經明白了JTAG是什麼,所以不用多說了。
  • GDB是什麼
正像Windows和Linux的對比,整合開發環境比GDB在嵌入式開發領域,擁有更多的使用者,但這並不意味的GDB不好。GDB(GNUProjectDebugger)是開源軟體組織GNU開發和維護的一種除錯工具,它能除錯目前所有的能跑Linux的CPU,當然ARM也是其中一員。對於初學者來說,不建議使用GDB,還是先從整合開發環境入手,例如ADS、SDT、Keil、IAR之類的。其實從編譯器的層面來講,整合開發環境和GDB所用的編譯器GCC沒有什麼區別,但整合開發環境裡面提供了原始檔組織與瀏覽、工程檔案管理、除錯等多種功能,用起來很友好。GCC+GDB光學習寫相當於工程檔案的Makefile就要花很多的時間。但是,一旦你的學習進了一步到了Linux的Loader和核心,整合開發環境就無能為力了。前面已經提到了,本文覆蓋了從剛開始的裸奔程式碼到涉足作業系統的GCC+GDB除錯環境的建立方法。本文關於GDB的部分應該是國內挺難找到的HOWTO,轉載請註明來自EE小站。關於GDB,可以參考下我之前的這篇文章http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!268.entry
在開始之前請先確認你的電腦有並口,如果是筆記本就算了,買個PCMIA轉並口的卡的錢夠買個盜版U-Link了;要是肯下血本買盜版J-Link,那就看我以後寫的文章。
 
  • 首先說程式碼裸奔怎麼做
你需要的東西有:
 
● 帶並口的電腦一臺
● 並口延長線一根
● Wiggler一個
● 隨便什麼ARM7或ARM9的開發板一個
 
如果沒有並口延長線,可以去電腦城買一根。如果沒有Wiggler,你可以選擇DIY,下面這張圖是Wiggler的一種版本:
如果不想DIY,上淘寶淘一個去。ARM開發板也可以在淘寶上淘淘,看你的經濟能力了。
 
你需要的軟體有:
 
● ADS (ARM Developer Suite) V1.2
● H-Jtag
 
ADS在一般學校的FTP上都有,H-JTAG請訪問http://www.hjtag.com。在此再拜一下Twentyone大俠,可以為大家寫出這麼好的免費軟體。
H-Jtag和ADS的使用方法在H-Jtag的網站上的手冊裡寫得很清楚了,我就不再囉嗦了,給出地址http://www.hjtag.com/download/USER%20MANUAL%20(CN).pdf
  • 說說GDB怎麼做
如果你對Linux下ARM的開發沒有概念,先看我還是菜菜鳥的時候寫的這篇文章http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!121.entry
 
GDB使用GDB工具鏈,除錯解決方案的結構是
 
GDB前端<--->GDB<--->GDB服務程式<--->JTAG協議轉換器(模擬器)<--->目標CPU(ARMCPU)
                                     |
                                 控制介面
 
GDB有一個很大的缺點——文字介面,使用非常不方便。但幸運的是,有很多熱心的開發者為GDB寫了一些圖形“外殼”——GDB前端,大大方便了GDB的使用。因為我們做的是交叉開發(即在x86結構的電腦上開發ARM等非x86結構的CPU程式),所以GDB無法直接除錯編譯出來的程式,這就需要一個服務程式。這個服務程式可以是一個可以控制目標CPU的程式(可能執行於計算機上;也可能執行於某些模擬器上,例如如BDI2000就是這樣),也可以是一個執行於目標CPU上的服務程式,由它來裝載被除錯的程式。但是後者一般需要目標CPU上已經執行起了Linux核心;除錯Bootloader和Linux核心本身,需要前一種服務程式。GDB和GDB服務程式之間的連線方式可以是乙太網或者串列埠,而且GDB服務程式一般還有別的控制介面,例如Telnet介面,可以實現對目標CPU的控制,如初始化和程式檔案下載等。比較複雜哦,一會兒說到軟體的時候就會用上這些知識。
 
你需要的東西和裸奔程式碼一樣
 
你需要的軟體有:
 
● 一個可以執行的Linux
虛擬機器裡的、真實的都可以,推薦使用Open Suse 10.3,下載地址http://software.opensuse.org/
● 本機GCC編譯器
Open Suse自己帶的就可以
● 交叉GCC編譯器
可以去下載一個,隨便給個地址把http://www.linux4sam.org/twiki/bin/view/Linux4SAM/SoftwareTools#Cross_Toolchain值得注意的是U-Boot1.2.0之後需要使用支援軟浮點的交叉編譯器,如果沒有,可以用Crosstool製作一個,可以看我之前的這篇文章http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!274.entry
● OpenOCD原始碼
OpenOCD的主頁是http://openocd.berlios.de/web/。OpenOCD是一個執行於PC上的程式,它可以控制包括Wiggler之內的很多JTAG硬體;我們可以將它理解為一種GDB服務程式。OpenOCD的原始碼只能通過SVN下載,地址是svn://svn.berlios.de/openocd/trunk
,在寫這篇文章的時候OpenOCD已經是R818版本了,這個版本對Wiggler的支援有問題,我編譯的是r520版本的,如果沒有SVNClient,這個版本只能通過曲線的方式獲得:先到下載http://www.yagarto.de/download/oldver/openocd-r520-20080322.exe這個由YAGARTO提供的OpenOCDFor Cygwin的版本,安裝它,在安裝目錄例如C:ProgramFilesopenocd-r520source裡找到原始碼壓縮包。
● Insight原始碼
Insight是一個GDB的圖形前端,我感覺它比DDD更適合嵌入式系統程式的除錯。
● 隨便什麼程式的原始碼,例如U-Boot
U-Boot就不用介紹了,如果不知道可以Google下。
U-Boot的下載地址是http://www.denx.de/wiki/UBoot/SourceCode
下面開始編譯,先是OpenOCD,假設原始碼已經解壓縮到了/home/lxz/build-openocd,先設定許可權
# cd /home/lxz/build-openocd
# chmod 755  ./bootstrap
# ./bootstrap
等一會兒,輸入
# ./configure --prefix=/usr/local/arm/openocd--enable-parport
這裡--prefix指定的是安裝的路徑,--enable-parport使能並口,然後
# make
# sudo make install
輸入root密碼,等一會兒,安裝就完成了
 
然後是insight,假設原始碼已經解壓縮到了/home/lxz/insight-6.8,然後
# cd /home/lxz/insight-6.8
# ./configure--prefix=/usr/local/arm/arm-linux-insight --target=arm-linux
這裡--prefix指定的是安裝的路徑,--target指的是為ARM編譯GDB,等一會兒,輸入
# make
等一會兒,輸入
# sudo make install
輸入root密碼,等一會兒,安裝就完成了
 
然後編譯一個U-Boot用於測試,假設原始碼已經解壓縮到了/home/lxz/at91rm9200/u-boot-1.2.0,假設已經修改完了Makefile中的交叉編譯器的選項,假設我為AT91RM9200DK開發板編譯,然後 
# cd /home/lxz/at91rm9200/u-boot-1.2.0
# make at91rm9200dk_config
# make
於是得到了/home/lxz/at91rm9200/u-boot-1.2.0/u-boot這個映像
 
為了能讓OpenOCD正常使用,我們還需要2個指令碼,第一個是OpenOCD的配置指令碼,這個指令碼的作用是配置GDB服務程式、JTAG模擬器。寫這個指令碼可以看OpenOCD的文件http://openfacts.berlios.de/index-en.phtml?title=OpenOCD_configuration。我給出我的AT91RM9200DK開發板的配置檔案at91rm9200.cfg,每一條配置資訊的作用我就不解釋了,請仔細閱讀OpenOCD的文件。
 
# Daemonconfiguration
telnet_port 23
gdb_port 2331
daemon_startup reset
# JTAG interfaceconfiguration
interface parport
jtag_speed 0
reset_config trst_and_srst
jtag_device 4 0x1 0xf 0xe
# parport options
parport_port 0x378
parport_cable wiggler
# Targetconfiguration
target arm920t little run_and_init 0 arm920t
run_and_halt_time 0 1000
target_script 0 reset at91rm9200_init.script
working_area 0 0x00200000 0x1000 backup
 
我還是提一下,上面這段配置資訊中的target_script 0 resetat91rm9200_init.script這句就是指定第二個指令碼的,而且讓OpenOCD在當前目錄下搜尋這個指令碼。也就是說,如果at91rm9200.cfg在/home/lxz/at91rm9200下,那麼你在/home/lxz/at91rm9200下啟動OpenOCD服務程式,OpenOCD就會在/home/lxz/at91rm9200下搜尋at91rm9200_init.script這個指令碼;如果在與at91rm9200.cfg所在路徑不同的路徑下啟動OpenOCD服務程式,OpenOCD就無法找到at91rm9200_init.script,此時,target_script0 reset at91rm9200_init.script這句就應該寫成target_script 0 reset/home/lxz/at91rm9200/at91rm9200_init.script。
第二個指令碼的作用是初始化ARMCPU,因為U-Boot往往是在SDRAM裡執行的,其連線位置也都在SDRAM裡。用GDB或GDB前端下載程式的時候,必須保證SDRAM是可用的。AT91RM9200這個CPU上電的時候如果從片內BootROM啟動(不推薦從外部啟動,因為如果沒有啟動程式,AT91RM9200將執行於慢時鐘,這樣JTAG模擬器可能工作不正常),需要進一步配置PLL,PIO,SDRMC之類的外設之後,SDRAM才可以使用。第二個指令碼就是一系列暫存器讀寫和延時命令的集合,如何編寫請看OpenOCD的手冊http://openfacts.berlios.de/index-en.phtml?title=OpenOCD_commands,給出我的at91rm9200_init.script。
 
mww 0xfffffc280x00000000
mww 0xfffffc2c 0x00000000
mww 0xfffffc20 0x0000ff01
sleep 20
mww 0xfffffc28 0x20263e04
sleep 20
mww 0xfffffc2c 0x10483e0e
sleep 20
mww 0xfffffc30 0x00000000
sleep 20
mww 0xfffffc30 0x00000202
sleep 20
mww 0xfffff870 0xffff0000
mww 0xfffff804 0xffff0000
mww 0xffffff60 0x00000002
mww 0xffffff64 0x00000000
mww 0xffffff98 0x2188c159
mww 0xffffff90 0x00000002
mww 0x20000000 0x00000000
mww 0xffffff90 0x00000004
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0x20000000 0x00000000
mww 0xffffff90 0x00000003
mww 0x20000200 0x00000000
mww 0xffffff94 0x000002e0
mww 0x20000000 0x00000000
mww 0xffffff90 0x00000000
mww 0x20000000 0x00000000
arm7_9 sw_bkpts enable
 
這個指令碼寫起來很複雜,建議從一些樣例程式碼上把暫存器的數值扒過來。另外,有些CPU,例如S3C2410,它上電的時候,SDRAM是預設可以用的,就不需要這個指令碼了。還有一個值得注意的是,由於我們用的是Wiggler這種簡單的JTAG協議轉換器,初始化指令碼里必須加上arm7_9sw_bkptsenable這句。現在終於可以開始除錯了,假設把OpenOCD安裝在了/usr/local/arm/openocd,把Insight安裝在了/usr/local/arm/arm-linux-insight,兩個初始化指令碼都放在了/home/lxz/at91rm9200;你已經正確連線了Wiggler,開發板已經上電。接下來還是用命令來說明
 
# cd /home/lxz/at91rm9200
# sudo /usr/local/arm/openocd/bin/openocd -fat91rm9200.cfg
root's password:
Open On-Chip Debugger 1.0 (2008-07-21-20:15)svn:
$URL:http://svn.berlios.de/svnroot/repos/openocd/trunk/src/openocd.c$
Info:    jtag.c:1329jtag_examine_chain(): JTAG devicefound: 0x05b0203f (Manufacturer:0x01f, Part: 0x5b02, Version:0x0)
Info:   target.c:240 target_init_handler():executing reset script 'at91rm9200_init.script'
Info:   options.c:50configuration_output_handler(): softwarebreakpoints enabled
 
這就說明OpenOCD已經開始工作了。然後啟動Insight
# cd /home/lxz/at91rm9200/u-boot-1.2.0/
#/usr/local/arm/arm-linux-insight/bin/arm-linux-insight
 
出現下面的視窗
 
[轉載]最低成本的ARM除錯解決方案——有關於Wiggler、H-Jtag、Ope 
 
然後選擇選單File>TargetSettings...,在出現的視窗中進行如下設定,然後點OK。
 
[轉載]最低成本的ARM除錯解決方案——有關於Wiggler、H-Jtag、Ope 
 
選擇選單File>Open,開啟/home/lxz/at91rm9200/u-boot-1.2.0/u-boot這個映像;然後選擇選單Run>Download,將U-Boot程式下載到目標CPU。然後在程式執行的必經之路設定一個斷點,如下圖所示。
 
[轉載]最低成本的ARM除錯解決方案——有關於Wiggler、H-Jtag、Ope 
 
選擇選單Control>Continure,程式就會從頭開始執行,並停在斷點處了。Insight還有很多不錯的功能,並且很容易上手,大家研究下就好。補充一點,如果你對你的初始化指令碼是否起作用沒有信心,可以在啟動Insight之後只選擇選單Run>Connecttotarget,然後選擇選單View>Memory檢視各個暫存器和記憶體。最後給出一張我用Insight除錯U-Boot的截圖。
 
[轉載]最低成本的ARM除錯解決方案——有關於Wiggler、H-Jtag、Ope 
 
在使用的過程中就會發現,用Wiggler下載的速度實在不怎麼樣,U-Boot的可執行映像至多隻有200KB,所以還是可以忍受的。
用同樣的方法也可以除錯其他BootLoader,甚至是Linux核心;但是Linux核心的可執行映像一般有2MB之大,用Wiggler除錯也是不現實的。我之前已經做了廣告了,核心的除錯要用J-Link來搞,敬請期待EE小站的後續文章。
我對ARM CPU的線上FlashDownload這件事情不是很感冒,所以H-JTAG和OpenOCD的這部分功能EE小站是不會涉及了,請見諒。今天就到這裡。

相關文章