本系列前3篇文章介紹硬件設計與實現,但光有硬件,再好的東西也跑不起來。因此,本篇將介紹如何搭建軟件開發環境。本文所使用的軟件均為開源軟件。
軟件開發環境的搭建分為2個部分:
(1)Arduino 端軟件開發環境;
(2)NDS端軟件開發環境。
一、搭建Arduino軟件開發環境
可以說搭建Arduino端開發環境幾乎沒有一點技術含量。只需要從Arduino官網站下載最新版(盡量不要使用beta版)軟件,然后在Windows或Mac OS的電腦上安裝即可使用,自帶IDE。而Linux版相對復雜一些,可以參考官方的Linux安裝文檔:Installing Arduino on Linux,這里不再詳述。
另外一點,由于設計方案中使用最小Arduino系統,上傳程序有兩種方案:
(1)使用另一塊無CPU的Arduino主板提供串口實現程序燒寫;
(2)使用一個USB轉串口的線(帶FDTI芯片)實現程序燒寫,如圖1。
以上兩種方案任選其一即可。使用Arduino主板燒寫程序可以參考擴展NDS掌機連接Arduino (1)--Arduino端最小系統實現 中的第三步。
二、搭建NDS軟件開發環境
NDS開發環境分為兩部分:(1)編譯環境;(2)調試環境。下面先講編譯環境的建立。
NDS開發使用開源開發套件:devkitPro。devkitPro分為好幾個部分,其中GBA,NDS,GP32都是基于ARM的CPU,因此都使用devkitARM子套件。然后再配套使用一些庫。
2.1,需要安裝的內容
對于NDS開發必要安裝的如下:
(1)devkitARM:含gcc, g++, objcopy, as, ld, gdb等必要工具。
(2)ndstool:用于將NDS的ARM7和ARM9二進制代碼進行合并成一個可以運行在NDS上的nds文件的工具。
選擇安裝的庫和工具如下:
(3)libnds:定義了各寄存器必要的宏和相關的常量以及大量實用的庫函數,一般開發都需要。
(4)default_arm7:NDS的ARM7端運行的代碼。
(5)dswifi:WiFi代碼庫。
(6)libfat:FAT文件系統庫函數,支持各燒錄卡文件讀寫。
(7)libfilesystem:NDS的nitro文件系統的支持庫。
(8)maxmod:音頻支持庫。
(9)dlditool:用于給ndstool產生的nds文件打dldi補丁的工具。如果程序沒用到FAT文件讀寫功能,不需要打dldi補丁,另外一部分燒錄卡有自動打dldi補丁的功能,也不需要。
(10)general-tools:提供了幾個有用的工具:bin2s, bmp2bin, padbin, raw2c。
(11)dstools:提供r4denc這個工具。
(12)mmutil:提供mmutil這個工具,用于將 MOD, S3M, XM, IT, and/or WAV文件轉換成可以運行用的GBA或NDS ROM。
(13)nds-examples:nds的很多例子程序,非常實用,可以對照自己寫。
2.2,編譯環境安裝過程
安裝過程在不同操作系統上有明顯區別。如果在Windows上安裝,devkitPro提供了自動安裝文件可自動完成安裝。對于Linux和Mac OS X則需要手動安裝,下面重點講解在這兩個系統上的安裝過程。安裝以上內容,可以選擇編譯源碼安裝,也可以下載編譯好的二進制文件手動復制到相應目錄內完成安裝。我這里選擇編譯源碼安裝。
步驟一:首先下載以上11個內容。除了devkitARM下載二進制文件外,其余全下載源碼進行編譯安裝。
在相應目錄下創建devkitPro文件夾,并將解壓后的devkitARM文件夾拷到里面。例如我的Mac OS上創建的路徑如下:/Users/Vincent/Documents/OS_Dev/devkitPro/devkitARM。devkitARM文件夾內的內容如下圖:
步驟二:設置環境變量。根據自己使用的操作系統編輯不同的文件:Linux在~/.bashrc文件,Mac OS X在~/.bash_profile文件(“.“開頭的是默認隱藏文件,所以手工用命令行創建)中最后加入以下代碼(實際路徑按你自己來寫):
#Set Variables for DEVKIT_PRO
export DEVKITPRO=/Users/Vincent/Documents/OS_Dev/devkitPro
export DEVKITARM=${DEVKITPRO}/devkitARM
保存后,重啟Terminal終端,路徑已經完成設置。
步驟三:安裝libnds。將libnds庫源碼解壓到devkitPro文件夾內,和devkitARM同級,即devkitPro文件夾內有libnds-src-x.x.x文件夾,其中x.x.x是版本號。進入該文件夾運行 make,以上步驟沒出錯的話,稍等片刻libnds庫就編譯好了,然后運行 make install 進行安裝。安裝完成后會在devkitPro文件夾下創建libnds文件夾,相應的.a庫文件被拷到這里。
步驟四:安裝各個庫。將2.1小節內下載的(4)~(8)源代碼按步驟三的方式解壓,進入子目錄,然后make, make install,完成安裝。因為這些庫依賴libnds,所以要確保libnds先安裝好。特別要注意一點是maxmod庫如果用make命令,會同時編譯NDS, GBA兩個板本,而要成功編譯GBA版本需要安裝libgba。如果只需要使用NDS版的maxmod庫,則需要執行:make dist-nds, 然后執行:make install-nds。細節可參考相應的Makefile文件。
步驟五:安裝ndstool, dlditool, general-tools, dstools, mmutil,其中ndstool是必須的。按2.1小節內下載的這些源碼按步驟三的方式解壓,進入相應子目錄,然后先運行 .configure, 然后運行 make, 最后運行sudo make install,完成安裝。最后一步因為要安裝到系統文件夾路徑下,需要管理員權限,所以加sudo運行。
步驟六:編譯nds-examples:按2.1小節內下載的這些源碼按步驟三的方式解壓,進入相應子目錄,然后先運行make。不出意外的話,所有例子程序就會編譯成功,在nds-examples-xxxxxxxx文件夾(xxxxxxxx是日期版本號)內會多出一個bin子文件夾,里面是編譯出來的nds程序。如果有模擬器就可以運行了。
至此,NDS的編譯環境安裝完成,下面講解相對復雜的調試環境。
2.3,調試環境建立過程
可以說不使用價格昂貴的任天堂官方開發套件,構建NDS的調試環境是比較復雜的,該部分也是本文最復雜部分。
NDS調試環境搭有幾種方案選擇:
(1)選擇任天堂官方開發套件:價格昂貴,個人幾乎不可能購買。
(2)使用no$gba debugger版模擬器:收費,最便宜的$15的個人版功能有限,功能強大的企業版上千美元。而且只支持Windows系統。我用過個人版,調試過程是在no$gba軟件內部進行,非常不方便使用,不符合一般開發人員的使用習慣,而且功能實在有限。
(3)使用DeSmuME模擬器 + Insight。devkitPro提供編譯好的Insight,只支持Windows系統。
(4)使用DeSmuME模擬器 + GDB + DDD。這是我用過最習慣的最舒服的環境,而且支持Linux, Mac OS X系統。
主張開源,免費的我,方案(1)和(2)直接淘汰。對于方案(3),因為Insight是內部集成GDB調試器的,兩者不能獨立,而且在Linux和Mac OS X系統下Insight默認使用的GDB是i386架構的版本,讀者需要自行配置arm版本進行重新編譯,這種捆綁形式對我不是很感冒。因此,本文推薦方案(4),一方面由于DDD體積小,和GDB獨立,另一方面這個方案擴展性好。擴展性很重要,以后如果3DS, PSV等掌機破解后,可開發自制程序,都可以使用這個方案進行配置。
下面以Mac OS X系統上如何配置調試方案(4)進行詳述。
2.3.1 DeSmuME模擬器及調試功能的使用
DeSmuME是一款NDS模擬器,從玩游戲角度來說沒no$gba好,但對開發人員來說支持GDB調試接口。模擬器的Windows和Linux發行版直接集成了GDB stub接口,可直接使用。而且Mac OS X發行版默認不支持GDB stub,因此需要自行編譯源碼來支持。這不是本文的目的,因此我這里直接采用國外一高手編譯好的版本來使用。Mac OS X上的具體編譯過程可以參考:Installing DeSmuME from source on OS X 這個官方教程。
使用DeSmuME調試功能,需要命令行帶參數執行:
your_path/DeSmuME.app/Contents/MacOS/DeSmuME -arm9gdb 20000
兩點說明:
(1)Mac OS X的軟件實質上都是.app文件夾,真正的可執行程序在其Contents/MacOS/路徑下。因此,Windows版本和Linux版本無需前面部分,直接運行your_path/DeSmuME -arm9gdb 20000。這里的your_path是你電腦上存放DeSmuME的路徑。
(2)這里的參數-arm9gdb 20000:前面的 -arm9gdb 是指啟動arm9的代碼調試功能。20000是GDB遠程調試的IP端口號,按約常規的方式不要使用0?1023這1024個保留端號口。因為NDS有兩個CPU,如果要調試arm7部分的代碼,則使用-arm7gdb xxxx,即可。
按上面的命令行執行后,模擬器就會啟動,見圖3左。然后選擇菜單選擇相應的需要調的.nds自制程序,加載后效果見圖3右。
圖3. 左:帶GDB調試功能啟動模擬器。右:加載NDS可執行文件后的模擬器。
圖3右,模擬器顯示白色,下方顯示"Executing",這說明此時模擬器已準備就緒,等待GDB調試器的遠程連接,并接受GDB發來的命令進行操作。至此,模擬器部分準備工作就緒。
2.3.2 GDB調試器功能的使用
一般一個特定平臺(如ARM或MIPS)的工具鏈中除了提供gcc, as, ld, objcopy等工具外,也同時會提供相應的gdb。devkitARM中提供的GDB位于路徑: devkitARM/bin/arm-none-eabi-gdb 。
要使用GDB調試程序,首先被調試程序必須含有可調試信息。這要求在編譯程序源碼時必須添加 -g 命令行參數,如:
gcc -g hello_world.c
在devkitARM工具鏈中生成的二進制文件中含有elf格式文件,后綴名也為.elf。這個elf文件就可以用來在GDB中進行調試。執行如下命令:
your_path/arm-none-eabi-gdb file_path/hello_world.elf
然后會進入GDB命令行。因為我們的程序需要和DeSmuME配合調試,程序本質上是在模擬器上運行,因此,GDB需要和DeSmuME建立IP連接,所以在GDB命令行中輸入以下命令:
target remote :2000
這條命令的原型為:target remote IP:port 。IP為需要被調試的目標的IP地址,port為端號口。因為我們的目標(模擬器)也在本機上,因為IP可以不寫,端口號一定要與模擬器運行時的一致。執行上述命令后,如果DeSmuME已經按上述設置好,GDB就能成功連接上模擬器,顯示圖4內容:
此時,可以輸入GDB命令控制模擬器,比如單步執行(Step, Next),執行到下一個斷點(Continue),顯示代碼(List),設置斷點(Break)等等,具體可以參考GDB使用手冊。圖5為我讓顯示讓程序執行到斷點(37行)時的模擬器和GDB調試窗口的截圖。
這個例子中我調試的程序使用以下代碼,并使用-g參數編譯:
#include
#include
volatile int frame = 0;
//---------------------------------------------------------------------------------
void Vblank() {
//---------------------------------------------------------------------------------
frame++;
}
//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------
touchPosition touchXY;
irqSet(IRQ_VBLANK, Vblank);
consoleDemoInit();
iprintf(" Hello DS dev'rs\n");
//iprintf(" \x1b[32mwww.devkitpro.org\n");
//iprintf(" \x1b[32;1mwww.drunkencoders.com\x1b[39m");
iprintf("\n blog.congao.net\n");
iprintf(" Vincent(c_gao)'s Blog");
while(1) {
swiWaitForVBlank();
touchRead(&touchXY);
// print at using ansi escape sequence \x1b[line;columnH
iprintf("\x1b[10;0HFrame = %d",frame);
iprintf("\x1b[16;0HTouch x = X, X\n", touchXY.rawx, touchXY.px);
iprintf("Touch y = X, X\n", touchXY.rawy, touchXY.py);
}
return 0;
}
2.3.3 DDD功能的使用
DDD (Data Display Debugger)是一個圖形化調試前端工具,其本身沒有調試功能,需要配合GDB一起使用。Linux系統下安裝DDD非常方便,但在Mac OS X下就比較麻煩。首先講解如何在Mac OS X下如何安裝DDD,對于Linux系統這部分內容可以省略。
OS X上安裝DDD
DDD是標準的X11應用程序,X11和OS X系統之前有著很大關系,Apple公司專門有一個項目叫XQuartz,為使X11應用程序在OS X系統運行作努力。為使DDD能在OS X上運行,需要安裝以下兩個軟件:
(1)XQuartz:OS X 10.7自帶不用裝, 10.9需要另行安裝。
(2)Fink:引用wikipedia的一句話,The Fink project is an effort to port and package open-source Unix programs to Mac OS X.
這里我就不講如何安裝這兩個軟件了。假設你已安裝好這兩樣。
Fink使得你可以使用Debian的很多pkg安裝包,還帶了非常有用的ap-get命令。因此,熟悉Linux命令的讀者很容易上手。首先執行sudo apt-get update,然后sudo apt-get install ddd,即可完成DDD的安裝。
安裝好DDD后,我們現在使用它來配合DeSmuME調試程序(而不是命令行的GDB)。安照2.3.1節DeSmuME準備就緒后,運行如下代碼啟動DDD:
ddd --debugger your_path/arm-none-eabi-gdb file_path/hello_world.elf
這里的
(1)第一個參數--debugger,指定后面的your_path/arm-none-eabi-gdb作為DDD的調試用GDB;
(2)第二個參數file_path/hello_world.elf為需要被調試的帶-g編譯出來的elf文件,這和2.3.2節一樣。
如果輸入沒有錯誤,回車進入DDD調試窗口,窗口下方是GDB命令行子窗口。在這個命令行子窗口內同樣輸入以下命:
target remote :2000
此時,DDD內的GDB就能連接上模擬器,就可以進行圖形化調試之旅了。圖6是調試過程載圖:
至此,本篇主要內容講完了。
后記:
(1)在OS X 10.9的系統中安裝Fink有點繁雜,但只要仔細按要求一步步操作就不會有問題。
(2)我在寫這篇博文時,用的OS X系統自帶的五筆中文輸入法,在按了caps lock鍵后可以轉換為英文輸文。但是在這樣的英文輸入狀態下,命令行啟動DDD時,DDD下方的GDB子窗口輸入英文就會變成亂碼,即使這時把中文關了也會輸入亂碼。最后發現必需在命令行啟動DDD時,輸放法狀態就得是標準英文輸入狀態。
(3)我一開始在DDD下方的GDB子窗口中不管輸入什么GDB命令都提示“waiting until GDB gets ready“錯誤,后google之后發現這是DDD的一個bug,只要按照這篇文章DDD - Bugs: bug #32949, "waiting until GDB gets...,先關閉DDD,然后修改~/.ddd/init文件內的一行:將set extended-prompt not set\n\ 改為 set extended-prompt (gdb) \n\ 最后重啟DDD便可。
請待下篇....