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