我們在 Linux 主機中搭建我們的開發環境,使用 Ubuntu 10.04 LTS 為例。
Eclipse 依賴于Java 環境,是以必須先安裝 JRE 或 JDK。
我們一般選擇 C/C++ 版本(Eclipse IDE for C/C++ Developers),這個版本自帶了CDT,不用另行安裝CDT插件。下載下傳時選擇 Linux 的版本,如:eclipse-cpp-juno-linux-gtk.tar.gz
直接把下載下傳下來的壓縮包(eclipse-cpp-juno-linux-gtk.tar.gz)解壓到某一目錄,運作可執行檔案eclipse即可。
運作 eclipse 後,可先進行Eclipse使用環境Workspace的配置。
在 Eclipse 主界面點選菜單 File > New > C/C++ Project,在彈出的“C/C++ Project”對話框中,輸入項目名稱。選擇一個項目類型(如Executable/Empty Project),在 Toolchains 中一定要選 Cross GCC,這是CDT對交叉環境的支援,提供了額外的功能,以友善嵌入式應用程式的開發。
點選下一步,來到“Select Configurations”頁面,我們采用預設,直接下一步,來到“Cross GCC Command”的設定。這裡我們可以填寫交叉編譯工具鍊的交綴和路徑,如:
上例的情況是在我們已經安裝好了ARM晶片商提供的交叉編譯包。一般來說,晶片商都提供了這樣一個交叉編譯環境,包括目标平台的編譯工具鍊、Glibc庫、二進制工具和其它常用工具。上例是TI提供的DM3730的開發包的安裝路徑和程式的字首(真實程式為:arm-arago-linux-gnueabi-gcc、arm-arago-linux-gnueabi-ld等)
最後點選完成,一個交叉項目就建立好了。關于交叉編譯字首和路徑的設定,在項目建立後,可以在項目的屬性中改變它。
這裡我們寫一個簡單的測試程式,如:
點選建構,對它進行編譯。編譯後,我們可以在左側的“Project Explorer”中,項目目錄下的Binaries中看到編譯出來的程式。把它拷貝到目标ARM開發闆上,運作,結果正确。
程式編譯成目标平台的二進制碼後,怎麼拷貝到目标闆上運作調試是個問題。
我們可以通過TFTP把編譯好的程式下載下傳到目标闆上,即在開發主機安裝TFTP伺服器,在目标闆上使用tftp指令向主機取檔案。
終極的解決辦法是搭建GUI的線上調試環境,即寫完代碼後,點選調試,Eclipse自動編譯程式,然後把程式下載下傳到目标闆,然後運作打開GDB線上調試,這樣就可以單步調試了,就像調試本地程式一樣。
遠端調試環境由主控端GDB和目标機調試stub共同構成,兩者通過序列槽或TCP連接配接。使用 GDB标準程串行協定協同工作,實作對目标機上的系統核心和上層應用的監控和調試功能。調試stub是嵌入式系統中的一段代碼,作為主控端GDB和目标機調試程式間的一個媒介而存在。
就目前而言,嵌入式Linux系統中,主要有三種遠端調試方法,分别适用于不同場合的調試工作:
普通清單項目用ROM Monitor調試目标機程式
用KGDB調試系統核心
用gdbserver調試使用者空間程式
這三種調試方法的差別主要在于,目标機遠端調試stub 的存在形式的不同,而其設計思路和實作方法則是大緻相同的。
而我們最常用的是調試應用程式。就是采用gdb+gdbserver的方式進行調試。在很多情況下,使用者需要對一個應用程式進行反複調試,特别是複雜的程式。采用GDB方法調試,由于嵌入式系統資源有限性,一般不能直接在目标系統上進行調試,通常采用gdb+gdbserver的方式進行調試。
再次強調一次,GDB遠端調試套件包括Host端的gdb和Target端的gdbserver,對于gdb,主控端上發行版本自帶的PC版gdb是不能用的,它沒有目标架構(ARM)相關的調試支援。是以我們應該使用gdb的源碼,針對ARM平台編譯一個(toolchain還是Host上的)特别的版本。當然,如果晶片商提供的交叉編譯套件中已經包含了arm-linux-gdb,我們就不用重新編譯gdb了,直接用它即可。不管怎麼說,gdbserver還是需要用目标闆的toolchain重新編譯一遍,因為晶片商提供的交叉開發套件通常不包括gdbserver。
下載下傳完後,解壓:
建立配置檔案,編譯:
上面指令中,–target配置gdb的目标平台,–prefixp指定了編譯結果的存放位置,也就是安裝目錄。編譯完後可以在/opt/arm-gdb/bin目錄下找到可執行的arm-linux -gdb, arm-linux -gdbtui, arm-linux-run。 拷貝arm-linux-gdb 到/usr/bin目錄:
下面把 gdbserver 移植到ARM平台。要點是指定目标平台的交叉編譯鍊(gcc和ar)。我們建立一個臨時的編譯目錄,以避免弄髒原代碼。
上面指令中,–target=arm-linux表示目标平台,–host表示主機端運作的是arm-linux-gdb,不需要配置—prefix,因為gdbserver不在主機端安裝運作。臨時環境變量CC和AR用于指定交叉編譯和彙編選項,在同一行指令的configure執行時将應用這些選項。
沒有錯誤的話就在/home/kim/gdb-build目錄下生成gdbserver可執行檔案,注意此時要更改其屬性,否則可能會出現無法通路的情況,chmod 777 gdbserver将其更改為任何人都可以讀寫執行;使用arm-linux-strip指令處理一下gdbserver,将多餘的符号資訊删除,可讓elf檔案更精簡,通常在應用程式的最後釋出時使用;然後把它燒寫到flash的根檔案系統分區的/usr/bin(在此目錄下,系統可以自動找到應用程式,否則必須到gdbserver所在目錄下運作之),或通過nfs mount的方式都可以。隻要保證gdbserver能在開發闆上運作就行。
編譯好gdbserver後,把它拷貝到目标闆上的 /usr/bin 目錄下,運作,如果能顯示幫助資訊,則交叉編譯成功,如:
如果提示其它錯誤資訊,如二進制檔案無法執行,則表示編譯不成功。注意我們交叉編出來的gdbserver是無法在開發主機上運作的。
在目标闆上,運作 gdbserver 指令啟動測試程式的調試,并指定目标闆的IP和監聽端口号,如:
我們看到gdbserver已經正常啟動了,正在等待用戶端程式gdb的連接配接。
此時我們在開發主機上運作 arm-linux-gdb,指定gdbserver的IP和端口,連接配接上去,如:
顯示“0x400b57f0 in ?? ()”表示已經連接配接到遠端的gdbserver并且開始調試了,此時目标闆終端會顯示“Remote debugging from host 192.168.188.201”,再次确認遠端調試連接配接成功。接下來的調試方法與普通本機的gdb使用相同。
我們可以直接使用 arm-linux-gdb 對應用程式進行遠端調試,但指令行界面實在是不夠友好。這裡我們想辦法在Eclipse上,通過CDT使用GDB進行遠端線上調試。
在Eclipse中選擇一個項目,點選菜單 Run > Debug Configurations,在左側的Dubug類型中找到“C/C++ Remote Application”,右擊點“New”,建立一個遠端調試配置,如下圖:
Eclipse的C/C++插件CDT已經很好的支援gdb在遠端調試了。調試一個應用程式時,CDT有三種運作方式:
Automatic Remote Launcher :遠端自動運作,這是最友善好用的一種方式
Manual Remote Launcher : 遠端手動運作。使用者自己在目标闆上運作gdbserver,然後在開發主機上指定遠端連接配接的方式(如IP位址和端口),連接配接到gdbserver
Remote Attach Launcher :遠端依附運作。類似于上一種,但它不是重新運作程式開啟一個debug會話,而是直接Attach到一個已經運作的程式,然後調試
在Debug Configurations 對話框中,建立一個遠端調試配置,這個配置在建立時會根據項目情況提供一個預設的配置,預設将使用第一種Automatic Remote Launcher方式,這在Main标簽中下方“GDB (DSF) Automatic Remote Debugging Launcher”可以看出,點選右邊的“Select other…”可以切換其它方式。
我們希望Eclipse每次生成一個項目之後,自動把生成出來的二進制程式拷貝到目标闆上,這可以通過NFS挂載共享目錄來實作,我們隻需要配置項目屬性(依次展開:C/C++Build > Settings > Build Steps > Post-build steps,在Command中輸入“cp ProgramBin /mnt/share”)即可。
接下來配置CDT的Debug選項,步驟如下:
選中項目→菜單欄 ”Run“→Debug Configurations…
輕按兩下 C/C++ Remote Application 建立一個配置,Eclipse會根據目前選擇的項目初始化大部配置設定置,這裡隻需修改Debugger配置頁
在右下方點選“Select other”,選擇“GDB(DSF) Manual Remote Debugging Launcher”,确認
選擇進入Debugger配置頁,在Main标簽中,GDB debugger 填寫 arm-linux-gdb,如果未加入PATH環境變量則應該填入絕對路徑
在Debugger配置頁的Shared Libraries标簽中,可以添加庫路徑,比如調試過程中要步入外部函數,就必須在這裡給出帶調試資訊的庫檔案路徑,否則會找不到該函數的定義
在Debugger配置頁的Connection标簽中,Type選“TCP”,并填寫目标闆上gdbserver監聽的IP和端口号(這個在下面文檔會提及)
所有配置完成後,點“Apply”儲存配置,并關掉配置視窗
接下來在目标闆上運作 gdbserver,假如測試程式HelloDm3730已經下載下傳到目前目錄,如:
目标闆的 GDB 服務開啟後,我們就可以在開發主機中,點選Eclipse的調試按鈕(指定調試配置為剛才配置好的),開始應用程式的遠端調試。我們在連接配接目标闆的終端中,可以看到程式的标準輸出;也可以在這裡标準輸入。
當我們結束調試後,目标闆上的gdbserver程序會自動退出。如果我們在修改代碼後想再次調試,仍然需要在目标闆上運作gdbserver,這樣會很麻煩,但畢竟可以進行遠端的圖形化調試了。
我們希望在開發主機上檢視目标闆(遠端主機)的系統狀況,如檢視遠端的檔案,檢視程序清單等,甚至打開終端運作遠端機器上的程式。我們還希望這樣一個工具軟體能內建在Eclipse上,并且提供了API接口讓Eclipse的插件能調用遠端機器上的程式。
我們可以在安裝了TM/RSE的Eclipse上,點選右上角的“Open Perspective”按鈕,打開“Remote System Explorer”,在 Remote System Explorer 上,你可以很友善的管理多個遠端連接配接,檢視遠端檔案和程序,運作遠端程式等。
RSE 支援很多網絡連接配接類型,常用的有:
FTP/sFTP
SSH
Telnet
支援連接配接到Unix/Linux/Windows主機和Local(本地)。要在開發主機上連接配接遠端機器,必須先在遠端機器上安裝并啟動某一遠端控制服務,如 Telnet 服務、FTP服務、SSH服務。如果遠端主機安裝了檔案服務(如FTP、SFTP)和Shell服務(如SSH、Telnet),那麼可以在本地開發主機上,CDT可以調用RSE的API接口拷貝生成的目标程式到遠端,并在遠端目标闆上運作gdbserver,進而做到自動下載下傳和調試程式的功能。
CDT調用RSE的API接口實作遠端調試的過程可分解為:
通過檔案服務接口下載下傳編譯的程式到目标闆(可用的檔案服務有:FTP、SFTP)
通過Shell運作目标闆上的gdbserver加載下載下傳的程式(可用的Shell服務有:SSH、Telnet)
上面的第一步不是必需的,我們可以通過其它手段來實作,如在目标闆上mount一個NFS檔案系統,讓開發主機(也挂載了同一個NFT檔案系統)在編譯後執行一條拷貝指令即可,這可以在項目的編譯選項中配置。需要注意的是,如果想忽略這一步驟,還要在項目的Debug Configuration 中,勾選“Skip download to target path”,這樣CDT才不會每次啟動調試時都嘗試打開檔案服務接口。
為了友善,我們還是希望讓目标闆同時提供檔案服務和Shell服務。我們有兩種選擇:
在目标闆上部署 OpenSSH。OpenSSH 本身帶了SSH服務和SFTP服務,是以一個軟體包可以搞定。缺點是編譯出來的檔案很大
在目标闆上部署 Dropbear 和 vsFTP(或者其它FTP伺服器)
下面将分别介紹這兩種方案。
因為目标闆的資源有限,在目标闆上部署Telnet/FTP/SSH服務有點麻煩。好在Linux社群永遠是開放的,我們有太多選擇,如SSH服務可使用DropBear或OpenSSH,FTP可使用vsftpd等。如果我們的目标闆已經在這些當中的某一服務了,那好辦,直接連接配接即可;如果目标闆上沒有這些服務,我們還得自己編譯和部署——用交叉編譯器編譯出目标平台的程式,然後部署和配置它。這裡我們使用Dropbear來部署SSH服務。Dropbear 依賴 zlib 庫,是以如果目标闆上沒有 libz.so,還得自己編譯。
先在網上下載下傳最新的 zlib 和 dropbear。我下載下傳的版本是:dropbear-2012.55.tar.gz 和 zlib-1.2.7.tar.gz 。
編譯的基本流程是:解壓,配置,編譯,安裝。我們可以在./configure時就指定交叉編譯工具。
對于 zlib,我們指定安裝路徑為~/soft/install,這樣make install後,make就會把編譯後的程式拷貝安裝到這個目錄,友善我們取程式。如:
“安裝”後,可在我們指定的目錄~/soft/install/的lib下找到共享庫檔案(so),我們要用到的是:libz.so libz.so.1 libz.so.1.2.7
對于 Dropbear ,我們需要多指定ranlib和strip,并且要指定目标平台為arm-linux。安裝路徑要使用絕對路徑,雖然我們不安裝。如:
編譯後,在目前目錄可以看到我們需要的程式:
把zlib的三個so(libz.so libz.so.1 libz.so.1.2.7,前兩個是連接配接檔案)拷貝到目标闆上的 /usr/lib;把dropbear生成的四個程式拷貝到目标闆的 /usr/sbin 目錄下。
然後(在目标闆上)建立配置檔案,生成SSH需要的密鑰,如:
最後啟動服務:
最好為目标闆的使用者建立密碼。然後在開發機上,先測試一下我們的SSH服務:
如果輸入正确的密碼,但總是登入不成功(在目标闆上的終端提示:user 'root' has invalid shell, rejected),可能是由于 root 帳号沒有設定正确的登入shell。各大多數程式一樣,Dropbear 隻允許 /etc/passwd 中列舉的使用者登入,并且在/etc/passwd中該使用者需要設定正确的shell(/bin/sh 或 /bin/csh)。有些busybox用的是/bin/bash,是以被Dropbear拒絕了。這裡我們使用 /bin/sh 以後,就可以正常登入了。
vsFTP 暫時沒有編譯成功,它沒有提供 configure 工具。
現在回過頭來看CDT的遠端調試。假設我們已經完成了以下工作:
在遠端部署了SSH或Tenlet服務(Telnet 在目前版本的RSE屬于試驗性質,遠端調試沒調通,不知是什麼原因)
在遠端部署了某一個檔案伺服器(如SFTP或vsFTP)(這項沒有也行,但調試會稍微麻煩點)
本地RSE能通路遠端功能(如Shell)
在遠端部署了 gdbserver,并存放在/usr/bin 中
遠端運作 gdbserver 時,開發主機能用 gdb (指令行)連接配接過去
我們應該先在Remote System Explorer上建立連接配接,讓RSE能連接配接到目标機器和管理目标機器。然後在項目的Debug Configurations中,建立“C/C++ Remote Application”的一個配置,在Main标簽中,Connection選擇RSE上建立的連接配接,然後輸入遠端的程式存放的路徑,這個路徑是包含最終的程式檔案名的,不是目錄。注意:如果在遠端沒有部署檔案服務(SFTP或FTP),那麼還需要勾選“Skip download to target path”,這樣CDT才不會每次啟動調試時都嘗試打開檔案服務接口,造成調試進行不下去。但勾選“Skip download to target path”了後,必須有途徑把最新的程式拷貝到剛才指定的遠端程式路徑,如每次手動拷貝,或者在項目配置中,Post-build steps 中輸入自動拷貝指令,讓項目每次編譯後自動拷貝到目标機器。
<a href="http://bashell.sinaapp.com/archives/eclipse-cdt-gdbserver-arm-remote-debugging-1.html">Eclipse-cdt 配合 gdbserver 進行 arm 程式遠端調試 上</a>
<a href="http://bashell.sinaapp.com/archives/eclipse-cdt-gdbserver-arm-remote-debugging-2.html">Eclipse-cdt 配合 gdbserver 進行 arm 程式遠端調試 下</a>
<a href="http://wiki.eclipse.org/CDT/User/FAQ#How_do_I_debug_a_remote_application.3F">How do I debug a remote application?</a>
<a href="http://blog.sina.com.cn/s/blog_45ef163d0100dx83.html">gdb+gdbserver方式進行ARM程式調試</a>
<a href="http://blog.csdn.net/ce123/article/details/6613850">Remote System Explorer之DropBear移植</a>
<a href="http://blog.csdn.net/ce123/article/details/6613976">Remote System Explorer之FTP移植(vsftpd)</a>
一.使用工程中自帶的Makefile。
3.之後再在Project Name中填入工程名稱
4.最後直接Build All或者Build Project即可
3.之後右鍵工程選擇Properties
經過一段時間的摸索,終于把linux下搭建基于Eclipse的arm的開發環境給搭建起來了,做下筆記,以便日後檢視。
0. 用的linux版本是Ubuntu 9.04
用的闆子是FriendlyARM s3c2440
1. 準備好相應的軟體包:
arm-linux-gcc-3.4.1.tar.bz2(網上現成的交叉編譯工具,有興趣的話也可以自己重頭編譯)
jdk-6u21-linux-i586.bin(其實這裡jre應該也夠了,裝個jdk以備以後開發java程式需要)
eclipse-cpp-helios-linux-gtk.tar.gz
2. 首先建立交叉編譯環境
(1) 将arm-linux-gcc的壓縮包arm-linux-gcc-2.95.3.tar.gz解壓縮;eclipse-cpp-helios-linux-gtk.tar.gzeclipse-cpp-helios-linux-gtk.tar.gz
$ sudo tar vxjf arm-linux-gcc-3.4.1.tar.bz2
(2) 将路徑usr/local下的arm目錄拷貝到你自己系統的/usr/local下;
cd ./usr/local
$ sudo mv arm /usr/local
(3) 修改環境變量,把交叉編譯器的路徑加入到PATH。(有三種方法,強烈推薦使用方法一,我也不知道為啥,網上說的)
方法一:修改/etc/bash.bashrc檔案
$ sudo vi /etc/bash.bashrc 在最後加上:
export PATH=$PATH:/usr/local/arm/3.4.1/bin(注意,這裡的等号前後不能有空格,下同)
export PATH
方法二:修改/etc/profile檔案:(經測試發現,方法二必須重新啟動,使用source的話換個終端就無效了)
$ sudo vi /etc/profile 增加路徑設定,在末尾添加如下:
export PATH=$PATH:/usr/local/arm/3.4.1/bin
方法三:#export PATH=$PATH:/usr/local/arm/3.4.1/bin 注:(這隻能在目前的終端下才是有效的!)
總結:在這裡我們還是用第二種方式吧,第一種方式Eclipse識别不出來的 -- 2010-10-10 9:47
(4) 儲存對profile的修改後,執行source /etc/bash.bashrc 就OK了,該指令能立即使新的環境變量生效,不用重新開機電腦;
用$ echo $PATH 檢查是否将路徑加入到PATH
(5) 測試是否安裝成功:$ arm-linux-gcc -v
3. 安裝Eclipse運作所需的jre,這裡以jdk替代
(1) 安裝jdk-6u21-linux-i586.bin
$ cd /usr/local/lib
$ sudo cp /home/jdk-6u4-linux-i586.bin ./
$ sudo chmod +x jdk-6u4-linux-i586.bin
$ sudo ./jdk-6u4-linux-i586.bin
(2) 設定環境變量
在/etc/profile中加入如下的内容:
(由上面可知這裡用的是第一種方法,其實我暫時也沒搞明白具體差別在哪裡,姑且這樣這着吧)
JAVA_HOME=/usr/local/lib/jdk1.6.0_21
JRE_HOME=/usr/local/lib/jdk1.6.0_21/jre
CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin
export JAVA_HOME JRE_HOME CLASSPATH
(3) source /etc/profile
(4) java -version
4. 安裝Eclipse
(1) 解壓Eclipse
sudo tar zxvf eclipse-cpp-helios-linux-gtk.tar.gz -C /usr/local/dev
(2) 把Eclipse的編譯器配置成arm-linux-gcc
解壓完以後我們就能在相應的目錄找到Eclipse檔案了,輕按兩下打開運作。
建立一個工程以後選擇工程的Properties,在彈出的頁面上進行如下圖設定:
加了一個名為arm的編譯方式以後,将它下面GCC C Compiler和GCC C Linker的Command改成arm-linux-gcc,然後就萬事OK了,你現在就可以通過Eclipse利用arm-linux-gcc來進行交叉編譯了。
5.PC開啟NFS與開發闆連結
PC上編譯好的東西必須拿到闆子上才能運作,拿U盤拷來拷去好像有點不太現實,我們利用NFS挂載就可以輕松解決這個問題。
(1) 安裝
在Ubuntu系統下,使用NFS需要首先安裝以下NFS的軟體包
伺服器端 : nfs-common、nfs-kernel-server、portmap;
用戶端:nfs-common、portmap;
在伺服器端安裝軟體包的指令式:$sudo apt-get install nfs-kernel-server
(安裝nfs-kernel-server時,apt會自動安裝nfs-common和portmap)
目标闆上的Linux系統由Linux核心和busybox共同提供對NFS的支援,不必安裝其他的NFS用戶端。
(2) 配置
NFS的配置檔案是/etc/exports。
在該檔案後面加一行:/home/xxx/workspace *(rw,no_root_squash) 使目錄/home/xxx/workspace允許所有的IP以讀寫的權限來通路。
(3) 使用
使用之前必需開啟NFS服務:$sudo /etc/init.d/nfs-kernel-server start
當然,使用之後可以關閉NFS服務:$sudo /etc/init.d/nfs-kernel-server stop
首先在Linux伺服器上進行NFS伺服器的回環測試,驗證共享目錄能否被通路。
$ mount -t nfs 192.168.1.1:/home/xxx/workspace /mnt
$ ls /mnt
啟動開發闆後在目标系統的Linux Shell下
$ mount -t nfs 192.168.1.1:/home/xxx/workspace /mnt/nfs -o nolock
$ ls /mnt/nfs
如果成功開發闆就可以直接運作主機上的程式了。