0 引言
國內(nèi)外各類構(gòu)的嵌入式芯片在競爭激烈的市場環(huán)境不斷突破技術(shù)壁壘,飛速提升性能。芯片配套的集成開發(fā)環(huán)境(IDE,Integrated Development Environment)作為開發(fā)中的關(guān)鍵工具,其提供的交叉編譯和交叉調(diào)試功能解決了嵌入式開發(fā)中目標(biāo)機(jī)的運(yùn)算能力和存儲(chǔ)空間有限的缺陷,對芯片嵌入式開發(fā)的重要性不言而喻。
近年來,各芯片廠商都在大力研發(fā)自己芯片的配套IDE,力圖打破 KEIL和IAR兩個(gè)行業(yè)標(biāo)桿的壟斷局面。這些免費(fèi)IDE(如ST的 CubeIDE和TI的CCS)大部分是基于Eclipse深度定制的,包含 Eclipse、SDK插件、代碼生成插件、編譯工具鏈,以及調(diào)試工具鏈的開發(fā)環(huán)境。目前,這些IDE存在僅針對各自產(chǎn)品的定制化開發(fā)、源碼封閉導(dǎo)致二次開發(fā)困難等問題?;谏鲜鲈颍律鲜械?a href="http://ttokpm.com/v/tag/1751/" target="_blank">硬件產(chǎn)品移植適配工作量巨大,不利于IDE的推廣使用。
本文主要由Eclipse、GDB、OpenOCD(采用JTAG標(biāo)準(zhǔn))組成的自主方案實(shí)現(xiàn)了IDE。鑒于交叉調(diào)試的重要性,本文重點(diǎn)介紹基于GDB和OpenOCD的技術(shù)選型,實(shí)現(xiàn)了目標(biāo)機(jī)(芯片型號為基于RISC架構(gòu)的RAC102)的交叉調(diào)試方案。在該方案中,對GDB和OpenOCD源碼進(jìn)行自主編譯移植后,兩者采用遠(yuǎn)程通信協(xié)議(RSP,Remote SerialProtocol)進(jìn)行通信,完成可執(zhí)行程序的調(diào)試操作。通過此案例驗(yàn)證了IDE設(shè)計(jì)方案中交叉調(diào)試的可行性,為后續(xù)其余架構(gòu)的IDE適配提供了指導(dǎo)思路。在此技術(shù)基礎(chǔ)上,提供支持多架構(gòu)芯的通用且開放的嵌入式開發(fā)集成環(huán)境。
1 設(shè)計(jì)思路
1.1 器件選型
1.1.1 編輯器選型
Eclipse平臺(tái)為更好地為C/C++開發(fā)人員服務(wù),衍生出了Eclipse CDT 擴(kuò)展套件。該套件可以為嵌入式開發(fā)者提供C/C+ +程序的編輯、編 譯、運(yùn)行及本地調(diào)試等功能[1]作為利用機(jī)器接口(MI,Machine Interface)支持C/C++源碼調(diào)試最好的開源工具,采用CDT套件作 為交叉調(diào)試的前端,通過MI接口使CDT和GDB相互通信,構(gòu)建了可視化的嵌入式遠(yuǎn)程調(diào)試軟件,提高了開發(fā)效率。
1.1.2 調(diào)試器選型
GDB是GNU工具集中的開源且高適配性的調(diào)試器,根據(jù)可執(zhí)行程序的運(yùn)行位置分為本地調(diào)試和遠(yuǎn)程調(diào)試兩種模式。在遠(yuǎn)程調(diào)試模式下,GDB與調(diào)試代理(OpenOCD、GDBServer等)通過RSP協(xié)議進(jìn)行信息交互,完成目標(biāo)機(jī)上可執(zhí)行文件的調(diào)試控制。注意,若目標(biāo)機(jī)架構(gòu)與宿主機(jī)架構(gòu)不同,則稱為交叉調(diào)試。此外,GDB支持兩種外部調(diào)試工具接口:MI和CLI(CommandLineInterface),其多樣化的接口、完善的目標(biāo)處理機(jī)制等特點(diǎn)為后續(xù)IDE的架構(gòu)適配打下了基礎(chǔ)。
1.1.3 調(diào)試代理選型
OpenOCD(Open On Chip Debugger)是一個(gè)開源、通用的片上調(diào)試器,并且可作為支持JTAG標(biāo)準(zhǔn)的調(diào)試代理。目前,可與GDB聯(lián)合為RISC V、ARM、MIPS等架構(gòu)的芯片提供在線調(diào)試工具[2]。OpenOCD開源的好處在于,可自主改寫函數(shù)源碼進(jìn)而適配目標(biāo)芯片的特性。因此,基于GDB和OpenOCD搭建的調(diào)試系統(tǒng)具備功能拓展簡單靈活、架構(gòu)兼容性強(qiáng)的優(yōu)勢。此外,OpenOCD支持各種商用JTAG仿真器、直接讀寫物理地址和核內(nèi)部寄存器等特點(diǎn)也是技術(shù)選型時(shí)考慮的因素。
1.1.4 調(diào)試標(biāo)準(zhǔn)選型
JTAG(JointTest Action Group)邊界掃描調(diào)試標(biāo)準(zhǔn)主要提供微處理器的電氣特性測試和目標(biāo)機(jī)可執(zhí)行程序調(diào)試兩大功能,適用于配置了JTAG接口的芯片電路?;贘TAG標(biāo)準(zhǔn)的微處理器在調(diào)試模式下中斷可執(zhí)行程序,上層的GDB和OpenOCD發(fā)送調(diào)試命令到調(diào)試模塊,完成后續(xù)程序調(diào)試工作。采用JTAG標(biāo)準(zhǔn)的主要原因是:①基于ARM、RISCV、Intel等主流架構(gòu)的微處理器實(shí)現(xiàn)了JTAG調(diào)試接口,該標(biāo)準(zhǔn)適配性高。②基于該標(biāo)準(zhǔn)的調(diào)試具備程序無侵入、依賴簡單、高穩(wěn)定性的特點(diǎn)。
1.2 整體框架
本文自主設(shè)計(jì)的IDE以主流嵌入式開發(fā)類似的宿主機(jī)目標(biāo)機(jī)通用結(jié)構(gòu)為基礎(chǔ)進(jìn)行整體框架設(shè)計(jì),如圖1所示??紤]到目標(biāo)機(jī)存儲(chǔ)資源的局限性,目標(biāo)機(jī)端放置調(diào)試代理(GDB Server或GDB STUB)的傳統(tǒng)方案被摒棄。本框架方案中,目標(biāo)機(jī)端僅運(yùn)行可執(zhí)行程序,宿主機(jī)端由Eclipse、GDB和OpenOCD組成,其中OpenOCD完成了傳統(tǒng)方案下目標(biāo)機(jī)端的調(diào)試代理工作。在框架中,首先CDT圖形界面通過UI操作來調(diào)用MI接口與GDB,進(jìn)行調(diào)試命令發(fā)送和調(diào)試信息獲取。GDB通過MI接口獲取調(diào)試命令后,在RSP序列包封裝和解析機(jī)制下與Open-OCD進(jìn)行調(diào)試命令傳遞和調(diào)試信息反饋。
最后,JTAG仿真器通過宿主機(jī)通信端口接收到OpenOCD的指令,將其轉(zhuǎn)換為標(biāo)準(zhǔn)的JTAG信號并通過調(diào)試訪問端口(DAP,Debug Access Port)發(fā)送給目標(biāo)機(jī)端。JTAG進(jìn)入調(diào)試模式讀取內(nèi)存和寄存器,按照需求進(jìn)行可執(zhí)行程序調(diào)試,目標(biāo)機(jī)完成調(diào)試后再將調(diào)試結(jié)果反饋給宿主機(jī)。通過上述流程,IDE完成目標(biāo)機(jī)可執(zhí)行程序的交叉調(diào)試。
圖1 IDE設(shè)計(jì)框圖
2實(shí)現(xiàn)方式
2.1 驅(qū)動(dòng)適配
為了目標(biāo)機(jī)的可執(zhí)行程序被順利調(diào)試,首先要保證目標(biāo)機(jī)和宿主機(jī)之間的傳輸正常。由于使用默認(rèn)驅(qū)動(dòng)時(shí),通過USB端口與仿真器 通信會(huì)發(fā)生異常錯(cuò)誤,因此,采用Zadig工具更新宿主機(jī)的USB驅(qū)動(dòng),從而保證目標(biāo)機(jī)可以與宿主機(jī)進(jìn)行正常通信。其驅(qū)動(dòng)安裝步驟如下:
①在菜單欄中選擇“Options”->“List All Devices”,查看當(dāng)前連接到計(jì)算機(jī)上的所有USB設(shè)備。
②在接口復(fù)合框中分別選中目標(biāo)機(jī)對應(yīng)的“Dual RS232-HS (Interface 0)”接口,并在驅(qū)動(dòng)復(fù)合框選擇“WinUSB”驅(qū)動(dòng)。
③選擇“Replace Driver”進(jìn)行驅(qū)動(dòng)更新即可。
④重復(fù)上述3個(gè)步驟,步驟②中接口選擇“Dual RS232-HS (Interface 1)”,完成該接口的驅(qū)動(dòng)安裝。
2.2 操作系統(tǒng)適配
由于IDE設(shè)計(jì)方案中交叉調(diào)試的調(diào)試器選用了GDB,因此運(yùn)行在 Unix/Linux系統(tǒng)下的GDB適配宿主機(jī)系統(tǒng)(Windows系統(tǒng))是需要完成的目標(biāo)。為了實(shí)現(xiàn)上述目的,可以采用Cygwin工具,其功能就是 在Windows上仿真Linux操作系統(tǒng),使得GNU工具鏈可以運(yùn)行在Linux模擬環(huán)境。在運(yùn)行Windows的同時(shí),僅依賴Cygwin核心的動(dòng)態(tài) 庫(如cygwin1.dll)也可以使用VIM、GCC、make、GDB等Linux工具。注意,安裝Cygwin時(shí)并沒有缺省安裝GNU工具鏈,應(yīng)根據(jù)需求安裝 相應(yīng)的工具。本文根據(jù)操作系統(tǒng)的配置需要安裝了binutils、gcc-core、gcc-g++、gdb、make等工具。
2.3 源碼編譯調(diào)試
2.3.1 GDB工作目錄建立
首先通過Cygwin進(jìn)入GDB源碼根目錄,新建文件夾build,用來存儲(chǔ) 源碼編譯后的可執(zhí)行文件。注意,Win- dows目錄在Cygwin進(jìn)行了掛 載,如D盤路徑變成/cyg- drive/d等。因此,進(jìn)入GDB源碼根目錄時(shí)要注意目錄路徑的變換。命令行操作如下:
//查看磁盤掛載情況,識(shí)別掛載后磁盤路徑
#df-h
//進(jìn)入 GDB源碼根目錄
#cd/cygdrive/d/gdb-source/gdb-10. 2
//創(chuàng)建 build工作目錄
#mkdirbuild
2.3.2 GDB源碼編譯
編譯源碼的主要流程由./configure(腳本文件配置)、make(工具編譯)、make install(工具安裝)3個(gè)步驟構(gòu)成。具體而言,首先,運(yùn)行configure腳本檢查當(dāng)前的配置選項(xiàng)和系統(tǒng)環(huán)境設(shè)置,檢查正確 后根據(jù)源碼中Makefile.in模版文件的引導(dǎo)生 成 Makefile文件;然后,make工具根據(jù)Makefile文件的進(jìn)行預(yù)處理、編譯、鏈接等項(xiàng)目構(gòu)建工作,生成二進(jìn)制文件;最后,make install命令根據(jù)執(zhí)行con-figure腳本時(shí)傳遞的prefix等參數(shù)將生成的二進(jìn)制文件安裝到指定路徑。
執(zhí)行./configure需要進(jìn)行各種參數(shù)配置,GDB交叉編譯中使用的參數(shù)配置如表1所列。
表1 configure腳本參數(shù)說明
GDB源碼編譯的操作如下:
//建立交叉調(diào)試環(huán)境之前檢查 config. sub腳本是否支持目標(biāo)機(jī)架構(gòu)的編譯 。若支持 ,則返回相應(yīng)的架構(gòu)類型 ,否則會(huì)報(bào)錯(cuò)
# sh config. sub riscv64 unknown elf gcc
//執(zhí)行 configure腳本 ,其中 CFLAGS= " g"的作用為后續(xù)調(diào)試 GDB源碼顯示調(diào)試信息。build和 host參數(shù)默認(rèn)均為
本機(jī)架構(gòu),不再顯性指定
#./configureCFLAGS=" g"
target=riscv64 unknown elf
prefix=/cygdrive/d/gdb source/gdb 10.2/build
//make編譯與安裝
#make
#makeinstall
2.3.3 GDB源碼調(diào)試
前面的工作已經(jīng)編譯生成了基于RISC V架構(gòu)的GDB可執(zhí)行程序,可以進(jìn)行目標(biāo)機(jī)上被調(diào)試程序的交叉調(diào)試工作。若GDB調(diào)試過程中出現(xiàn)了BUG或者需要進(jìn)一步理解內(nèi)部運(yùn)行機(jī)制,則需要進(jìn)入GDB源碼調(diào)試模式。為了方便閱讀調(diào)試源碼,選擇VSCode進(jìn)行GDB源碼調(diào)試,需配置launch.json文件,該配置文件主要作用是添加GDB調(diào)試任務(wù)并運(yùn)行可執(zhí)行文件。launch.json文件配置流程主要分為以下幾個(gè)步驟:
①生成launch.json文件。菜單欄選擇“運(yùn)行”->“添加配置”->“C++(GDB/LLDB)”,即可生成一個(gè)配置為空的launch.json文件。
②添加默認(rèn)配置模版。在"configurations"字段域中輸入“GDB”可以自動(dòng)生成默認(rèn)配置。
③修改默認(rèn)配置。"program"字段代表調(diào)試器的路徑,該字段設(shè)置為Cygwin的GDB路徑;"miDebuggerPath"字段代表被調(diào)試的可執(zhí)行文件路徑,該字段設(shè)置為前面編譯生成的GDB程序。
完成launch.json文件配置后,在VSCode中選擇“gdb啟動(dòng)”就可以在調(diào)試模式下運(yùn)行GDB調(diào)試器。
此外,調(diào)試代理OpenOCD的編譯和調(diào)試與GDB源碼編譯和調(diào)試工作步驟基本一致,在此不再重復(fù)說明。目標(biāo)機(jī)的被調(diào)試的可執(zhí)行程序?yàn)镽AC102芯片自帶示例程序。
2.4 交叉調(diào)試
首先,運(yùn)行OpenOCD程序后,會(huì)彈出運(yùn)行終端窗口,顯示JATG標(biāo)準(zhǔn)選擇、芯片架構(gòu)信息、監(jiān)聽端口等第一階段信息,表示OpenOCD運(yùn)行正常,與目標(biāo)機(jī)的RAC102芯片連接成功。
之后,以調(diào)試模式或者運(yùn)行模式打開GDB程序,彈出運(yùn)行終端窗口,在終端中依次設(shè)置指定RAC102芯片的架構(gòu)、遠(yuǎn)程調(diào)試的連接端口以及加載調(diào)試信息文件,命令執(zhí)行如下:
(gdb) set architecture riscv:rv32
The target architecture is assumed to be riscv:rv32
(gdb)target extended-remote localhost:3333
Remote debugging using localhost:3333
(gdb)file D:\led\led_debug.elf
Reading symbols from D:\led\led_debug.elf…
完成上述操作后,OpenOCD運(yùn)行終端會(huì)輸出端口連接成功、中斷地址等第二階段信息,表示OpenOCD與GDB連接成功。此時(shí)可以在GDB調(diào)試終端中輸入continue、step、break等常用的調(diào)試命令進(jìn)行交叉調(diào)試。
3 功能驗(yàn)證與協(xié)議分析
在交叉調(diào)試中,GDB所有的調(diào)試命令和調(diào)試信息反饋均通過RSP協(xié)議來實(shí)現(xiàn)。該協(xié)議通過串口或網(wǎng)口等媒介傳輸ASCII消息。RSP包的基本格式為:$數(shù)據(jù)包#校驗(yàn)和[3-4]。其中,數(shù)據(jù)包由若干ASCII數(shù)據(jù)組成,該校驗(yàn)和是數(shù)據(jù)包所有字符的ASCII碼之和取256的模后得到的值,用兩位十六進(jìn)制ASCII表示。若OpenOCD正確接收數(shù)據(jù),則會(huì)返回‘+’,否則返回‘-’表示發(fā)生錯(cuò)誤,要求重新發(fā)送消息[5]。
由GDB和OpenOCD源碼調(diào)試分析可知,GDB作為RSP客戶端,在remote.c源文件中完成了讀寫、運(yùn)行控制、查詢及設(shè)置、追蹤點(diǎn)以及停止通知等RSP常用類型通信包的接口實(shí)現(xiàn);OpenOCD作為RSP服務(wù)端,在server.cc源文件完成了GDB發(fā)送的通信包的解析與處理。在此基礎(chǔ)上,通過RSP通信包的組合實(shí)現(xiàn)常用的GDB調(diào)試命令。
在上述前提下,通過調(diào)試命令對應(yīng)的RSP協(xié)議分析來驗(yàn)證在GDB+OpenOCD的方案中基于RISC-V架構(gòu)的RAC102芯片交叉調(diào)試的功能正確性。參照第2.4小節(jié)的交叉調(diào)試流程,區(qū)別在于在執(zhí)行target extended-remote localhost:port命令之前,需要使用set remotelogfile filename命令配置好遠(yuǎn)程串行通信記錄日志,日志文件名為filename,GDB會(huì)將與OpenOCD的交互數(shù)據(jù)寫入該日志文件中。通過表2給出了驗(yàn)證后常用的調(diào)試命令以及對應(yīng)RSP協(xié)議指令集,證明了交叉調(diào)試方案設(shè)計(jì)的正確性與可行性。
表2 GDB命令與RSP協(xié)議對照指令集
G D B 命 令 | RSP請求序列 | RSP應(yīng)答序列 |
target extended- remotelocalhost: port |
①qSupported ②vMustReplyEmpty ③QStartNoAckMode ④! ⑤Hg thread-id ⑥qXferread ⑦qTStatus ⑧? ⑨qXferread ⑩Hc thread-id ?qC ?qAttached ?qOffsets ?g ?qXferread ?qSymbol |
①qSymbol::Size; qXferread; QStartNoAckMode; vContSupported ②空 ③OK ④OK ⑤OK ⑥m data ⑦空 ⑧S signal-id ⑨1 data ⑩OK ?QC thread-id ?1(注:數(shù)字1) ?Text =xx;Data=yy; Bss=zz ?XX..(注:寄存 器數(shù)據(jù)內(nèi)容) ?1 data ?OK |
file filename |
①qSymbol ②g |
①OK ②XX.. |
run |
①vKill;pid ②k和?組合包 ③vRun ④qC ⑤qAttached ⑥qOffsets ⑦Hg thread-id ⑧qXferread ⑨g ⑩vCont;c ?x03 ?g ?qXferread |
①空 ②W00 ③S signal-id ④QC thread-id ⑤1(注:數(shù)字1) ⑥Text=xx;Data=yy; Bss=zz ⑦OK ⑧m data ⑨XX.. ⑩ ?T siganal-id ?XX.. ?1 data |
continue |
①m ②ZO ③vCont? ④yCont;c ⑤g ⑥qXferread ⑦z0 |
①XX.. ②OK ③vCont;c;C;s:S ④T signal-id ⑤XX.. ⑥1 data ⑦OK |
next |
①m ②ZO ③vCont;s:thread - id;c ④g ⑤qXferread ⑥z0 |
①XX.. ②OK ③T thread-id ④XX.. ⑤1 data ⑥OK |
step | ||
break lineNo | ①m(若干包) | ①XX..(若干包) |
watchval | ||
print yal | ||
backtrace | ||
diassemble | ||
quit |
①D ②? |
①OK ②S siganal-id |
4 結(jié)語
本文自主設(shè)計(jì)了一套集成開發(fā)環(huán)境方案,該方案中基于自行編譯的GDB和OpenOCD實(shí)現(xiàn)了基于RSIC-V架構(gòu)的RAC102芯片的交叉調(diào)試,并且通過RSP協(xié)議分析進(jìn)行了調(diào)試功能的驗(yàn)證。交叉調(diào)試方案的實(shí)現(xiàn)為后續(xù)其余架構(gòu)芯片的集成開發(fā)環(huán)境設(shè)計(jì)與實(shí)現(xiàn)提供了指導(dǎo)思路。進(jìn)一步,為自研架構(gòu)芯片設(shè)計(jì)開發(fā)的自主可控提供了保障。
審核編輯:劉清
-
寄存器
+關(guān)注
關(guān)注
31文章
5294瀏覽量
119816 -
仿真器
+關(guān)注
關(guān)注
14文章
1014瀏覽量
83591 -
嵌入式開發(fā)
+關(guān)注
關(guān)注
18文章
1018瀏覽量
47470 -
GDB調(diào)試
+關(guān)注
關(guān)注
0文章
24瀏覽量
1432 -
RISC-V
+關(guān)注
關(guān)注
44文章
2204瀏覽量
45958
原文標(biāo)題:RISC-V架構(gòu)的交叉調(diào)試系統(tǒng)設(shè)計(jì)
文章出處:【微信號:麥克泰技術(shù),微信公眾號:麥克泰技術(shù)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論