VxWorks使用說(shuō)明書(shū)(2)
使用Tornado集成環(huán)境一般需要經(jīng)過(guò)以下步驟:
運行TCP/IP端口管理器Portmapper(portmap.exe)
運行注冊器Tornado Registry(wtxregd.exe)。如果使用的是試用版,注意是否注冊成功,是否修改了日期
運行并配置Ftp Server(wtfpd32.exe)。點(diǎn)擊菜單命令Security | Users | rights彈出配置窗口,點(diǎn)擊New User,在New User彈出窗口加入需要加入的用戶(hù)名(注意:要與目標機bootrom或啟動(dòng)軟盤(pán)設置一致),在改變密碼彈出窗口設置該用戶(hù)的密碼(注意:要與目標機bootrom或啟動(dòng)軟盤(pán)設置一致),在Home Directory中設置相應的目錄,MCP750為c:tornadotargetconfigmcp750,MCPN750為c:tornadotarget configmcpn750,X86為c:tornadotargetconfigpc486 ,配置結束。
目標板上電或復位
在控制臺(MCP750/MCPN750為超級終端,X86為目標機顯示器)上可以看到啟動(dòng)信息。如果需要修改,在等待用戶(hù)配置時(shí),按c鍵,進(jìn)行相應修改。(注意:配置信息要與主機配置、Ftp服務(wù)器配置一致),修改結束后,按@鍵重新啟動(dòng)目標機。
運行Tornado(tornado.exe)
執行菜單命令Tools | Target Server | Configure,彈出目標服務(wù)器設置對話(huà)框,點(diǎn)擊New產(chǎn)生一個(gè)新的配置。設置Description域(可以任意設置);設置Target Server域(可以任意設置);在Change Property域選取Back End項(該項設置主機與目標機如何連接,缺省為網(wǎng)口連接,如果使用串口連接,需要修改configall.h文件,重新編譯鏈接VxWorks映象),如果使用網(wǎng)口調試,選擇wdbrpc,在目標IP名或地址域中給出目標機的IP名或地址(建議給出IP名,因為這樣會(huì )快得多),如果給出的是IP名,需要在HOSTS文件中給出IP名與IP地址的對應關(guān)系,如果用串口調試,選擇wdbserial,選擇相應的串口和波特率(注意:此處的串口是指主機的串口不是目標機的串口);在Change Property域選取Core File and Symbols項,選中File項輸入相應的文件(MCP750c:tornadotargetconfigmcp750vxWorks,MCPN750為c:tornadotarget configmcpn750vxWorks,在X86平臺上為c:tornadotargetconfigpc486vxWorks),點(diǎn)擊Launch,運行目標服務(wù)器。
執行菜單命令File | New 創(chuàng )建一個(gè)新的文件,并打開(kāi)編輯器Editor(該編輯器功能不是很強大,可以使用其它編輯器如Source Insight)。
單獨編譯生成的源文件,生成目標文件(.o),編譯連接過(guò)程的詳細介紹請見(jiàn)后面。
選取相應的目標服務(wù)器。
執行菜單命令Tools | Debugger運行調試器。
執行菜單命令Debug | Download下載要調試的目標文件(.o)
在Editor窗口設置斷點(diǎn)。
執行菜單命令Debug | Run彈出對話(huà)框,要求輸入調試入口函數,輸入要調試的函數。
進(jìn)行源碼級調試
執行菜單命令Tools | Shell運行Shell??梢栽赟hell窗口查看/修改全局變量、內存,查看任務(wù)列表、各模塊使用內存的情況、對象(如任務(wù)、隊列、信號量、定時(shí)器、內存分區)等信息。
執行菜單命令Tools | Browser運行Browser。在Browser中可以查看任務(wù)列表、各模塊使用內存的情況、對象(如任務(wù)、隊列、信號量、定時(shí)器、內存分區)等信息。
6、編譯鏈接
VxWorks的開(kāi)發(fā)調試環(huán)境可以把VxWorks內核和應用分開(kāi),分別加載。 VxWorks內核在目標機啟動(dòng)過(guò)程中通過(guò)ftp協(xié)議加載到目標機中運行,應用模塊在調試中動(dòng)態(tài)下載,目標代理把下載的應用模塊動(dòng)態(tài)鏈接到系統中,應用模塊的調試是通過(guò)在用戶(hù)執行運行命令時(shí)提供入口函數實(shí)現的。這樣做的好處是需要調試哪個(gè)模塊就下載那個(gè)模塊調試,不需下載其它模塊,前期調試一般使用這種編譯方式。
VxWorks的開(kāi)發(fā)調試環(huán)境也提供把應用模塊與系統內核鏈接在一起,通過(guò)ftp協(xié)議加載執行。這需要經(jīng)過(guò)兩個(gè)步驟:把應用模塊的入口代碼加到usrConfig.c文件中的usrRoot函數的尾部;把應用模塊編譯鏈接到VxWorks內核中,這種編譯鏈接方式一般用于后期調試。
下面分類(lèi)對編譯鏈接進(jìn)行介紹
6.1 單個(gè)應用模塊的編譯
單個(gè)應用模塊的編譯可以通過(guò)使用菜單命令Project | Make Current Source File進(jìn)行編譯,要編譯的源文件必須已經(jīng)用Editor打開(kāi)并且為當前窗口。如果要編譯的源文件所在目錄沒(méi)有makefile文件,系統會(huì )提示創(chuàng )建一個(gè)新的makefile文件,確定。在彈出的創(chuàng )建缺省makefile窗口的CPU域選擇相應的項(MCP750/MCPN750選擇PPC604,X86選擇I80486),在A(yíng)DDED_FLAGS域輸入-g,確定。系統對源文件進(jìn)行編譯,生成目標文件(.o)。生成的目標文件在Debugger環(huán)境中動(dòng)態(tài)加載,與內核動(dòng)態(tài)鏈接到一起。
6.2 系統內核vxWorks的編譯鏈接
系統內核vxWorks是調試中使用最多的內核映象。它被通過(guò)Ftp協(xié)議從主機加載到目標機中。它的作用通常是進(jìn)行軟硬件初始化,等待加載應用模塊,進(jìn)行程序調試。
在Project菜單下,選擇相應硬件平臺的生成vxWorks的命令,進(jìn)行編譯鏈接。在編譯鏈接之前先使用clean命令刪除以前生成的文件。
6.3 應用模塊與系統內核一起編譯鏈接
VxWorks的開(kāi)發(fā)調試環(huán)境也提供把應用模塊與系統內核鏈接在一起,通過(guò)Ftp協(xié)議加載,vxWorks內核自動(dòng)執行應用模塊。這需要經(jīng)過(guò)兩個(gè)步驟:把應用模塊的入口代碼加到usrConfig.c文件中的usrRoot函數的尾部;在makefile中把待生成的應用模塊的目標文件名加到宏定義MACH_EXTRA中,再把相應的編譯規則加到makefile中。編譯鏈接生成vxWorks映象。
6.4 Project菜單下其它編譯鏈接命令介紹
* vxWorks_rom :可以寫(xiě)到ROM的、沒(méi)有帶符號表和Shell的、沒(méi)有壓縮的vxWorks。
* vxWorks.st :帶有符號表的vxWorks。
* vxWorks.st_rom:可以寫(xiě)到ROM的、帶有符號表和Shell的、壓縮的vxWorks。
* vxWorks.res_rom :可以寫(xiě)到ROM的、帶有符號表和Shell的、只有數據段拷貝到內存的、沒(méi)有壓縮的vxWorks。
* vxWorks.res_rom_nosym:可以寫(xiě)到ROM的、只有數據段拷貝到內存的、沒(méi)有壓縮的vxWorks。
* bootrom:壓縮的 bootrom
* bootrom_uncmp:沒(méi)有壓縮的bootrom
※ 作 者: helpyou 01-2-8 下午 08:29:03 ※
7、調試時(shí)的常用方法
下面是一些調試手段在調試器中的相應命令(操作)
調試手段
相應操作
設置斷點(diǎn)
菜單命令Debug|Toggle BreakPoint
刪除斷點(diǎn)
菜單命令Debug|Toggle BreakPoint
運行
菜單命令Debug|Run
單步執行(進(jìn)入函數)
菜單命令Debug|Step
單步執行(不進(jìn)入函數)
菜單命令Debug|Next
繼續執行(停下后的程序)
菜單命令Debug|Continue
執行完當前的函數,停在調用它的函數的下一條語(yǔ)句
菜單命令Debug|Finish
查看變量的值
菜單命令Debug|Inspect
查看當前函數的所有局部變量
菜單命令Debug|Locals
查看內存
菜單命令Debug|Memory
查看寄存器
菜單命令Debug|Registers
修改內存
Shell命令m
修改寄存器
Shell命令mRegs
修改變量
在Shell中直接給該變量賦值(局部變量無(wú)法用此方法修改)
卸載一個(gè)加載的模塊
Shell命令unld
刪除任務(wù)
Shell命令td
復位目標機
Shell命令reboot
用該命令的好處:目標服務(wù)器自動(dòng)與目標代理重新鏈接,Shell自動(dòng)重啟
查看任務(wù)
在Browser對象信息窗口輸入待查看的任務(wù)名或ID
查看信號量
在Browser對象信息窗口輸入待查看的信號量名或ID
查看消息隊列
在Browser對象信息窗口輸入待查看的消息隊列命或ID
內存分區
在Browser對象信息窗口輸入待查看的內存分區ID
看門(mén)狗
在Browser對象信息窗口輸入待查看的看門(mén)狗ID
類(lèi)(class)
在Browser對象信息窗口輸入待查看的類(lèi)的ID
查看內存使用(模塊使用內存的情況)
Browser的內存使用窗口
查看任務(wù)列表(系統里的所有任務(wù))
Browser的任務(wù)列表窗口
查看CPU占用率
Browser的Spy窗口
查看堆棧使用情況
Browser的堆棧檢查窗口
注:
* Shell可以通過(guò)菜單命令Debug | Shell啟動(dòng)
* Shell的原語(yǔ)可以通過(guò)在Shell中輸入help列出
* Browser可以通過(guò)菜單命令Debug | Browser啟動(dòng)
* Debugger命令窗口的命令可以通過(guò)在命令窗口輸入help列出
8、任務(wù)調試模式下的多任務(wù)調試
在任務(wù)調試模式下,在一個(gè)集成環(huán)境中,在一個(gè)任務(wù)中調試,在另一個(gè)任務(wù)中設置斷點(diǎn),設置的斷點(diǎn)不起作用。這是因為一個(gè)調試器只能處理一個(gè)TCB(任務(wù)控制塊),每個(gè)任務(wù)都有一個(gè)TCB,因此一個(gè)調試器只能調試一個(gè)任務(wù),要調試幾個(gè)任務(wù)就要啟動(dòng)幾個(gè)調試器。一個(gè)集成環(huán)境只能啟動(dòng)一個(gè)調試器,所以要調試幾個(gè)任務(wù)就要啟動(dòng)幾個(gè)集成環(huán)境。另外,需要在被調試的任務(wù)的待調試的第一條語(yǔ)句前加入taskSuspend(0)語(yǔ)句,掛起該任務(wù),否則任務(wù)就可能會(huì )在調試前被執行。
下面是多任務(wù)調試的測試用例的源代碼
/* VxWorks includes */
#include quot;vxWorks.hquot;
#include quot;taskLib.hquot;
#include quot;stdio.hquot;
#include quot;msgQLib.hquot;
int g_lTaskATid;
int g_lTaskBTid;
MSG_Q_ID g_MsgQ1id;
MSG_Q_ID g_MsgQ2id;
void MultiTaskTestTaskA(void)
{
char cMsgToTaskB[100];
char cMsgFromTaskB[100];
sprintf(cMsgToTaskB,quot;To TaskB nquot;);
printf(quot; Hello from MultiTaskTestTaskA nquot;);
/*start point of debugging for MultiTaskTestTaskA*/
taskSuspend(0);
for(;;)
{
printf(quot; Hello from MultiTaskTestTaskA nquot;);
/*Send message to MultiTaskTestTaskB*/
msgQSend(g_MsgQ1id,cMsgToTaskB,sizeof(cMsgToTaskB),WAIT_FOREVER, MSG_PRI_NORMAL);
/*Receive message from MultiTaskTestTaskB*/
msgQReceive(g_MsgQ2id,cMsgFromTaskB,100,WAIT_FOREVER);
printf(quot;%squot;,cMsgFromTaskB);
}
}
void MultiTaskTestTaskB(void)
{
char cMsgToTaskA[100];
char cMsgFromTaskA[100];
sprintf(cMsgToTaskA,quot;To TaskA nquot;);
printf(quot; Hello from MultiTaskTestTaskB nquot;);
/*start point of debugging for MultiTaskTestTaskA*/
taskSuspend(0);
for(;;)
{
printf(quot; Hello from MultiTaskTestTaskB nquot;);
/*Send message to MultiTaskTestTaskA*/
msgQSend(g_MsgQ2id,cMsgToTaskA,sizeof(cMsgToTaskA),WAIT_FOREVER, MSG_PRI_NORMAL);
/*Receive message from MultiTaskTestTaskA*/
msgQReceive(g_MsgQ1id,cMsgFromTaskA,100,WAIT_FOREVER);
printf(quot;%squot;,cMsgFromTaskA);
}
}
/*This function spawns MultiTaskTestTaskA and MultiTaskTestTaskB , creates g_MsgQ1id and g_MsgQ2id , is entry for debugging.*/
void MultiTaskTestInit(void)
{
printf(quot; Hello from MultiTaskTestInit nquot;);
g_MsgQ1id=msgQCreate(20,100,MSG_Q_FIFO);
if(g_MsgQ1id==NULL)
{
printf(quot; ERROR: create g_MsgQ1 error nquot;);
}
g_MsgQ2id=msgQCreate(20,100,MSG_Q_FIFO);
if(g_MsgQ1id==NULL)
{
printf(quot; ERROR: create g_MsgQ2 error nquot;);
}
printf(quot; Spawning a new task called MultiTaskTestTaskA nnquot;);
g_lTaskATid = taskSpawn(quot;MultiTaskTestTaskAquot;, 100,0,10000, (FUNCPTR)MultiTaskTestTaskA, 0,0,0,0,0,0,0,0,0,0);
if(g_lTaskATid == ERROR)
{
printf(quot; ERROR: task did not spawn nquot;);
exit(1);
}
printf(quot; Spawning a new task called MultiTaskTestTaskB
nquot;);
g_lTaskBTid = taskSpawn(quot;MultiTaskTestTaskBquot;, 100,0,10000, (FUNCPTR)MultiTaskTestTaskB, 0,0,0,0,0,0,0,0,0,0);
if(g_lTaskBTid == ERROR)
{
printf(quot; ERROR: task did not spawn nquot;);
exit(1);
}
exit(0);
}
多任務(wù)調試步驟:
* 用-g選項編譯源代碼產(chǎn)生目標文件
* 下載產(chǎn)生的目標文件
* 在MultiTaskTestInit函數的開(kāi)始設置斷點(diǎn)
* 把MultiTaskTestInit設置為調試任務(wù)的人口函數
* 單步執行產(chǎn)生MultiTaskTestTaskA任務(wù)的語(yǔ)句后可以在串口(超級終端)上看到字符串Hello from MultiTaskTestTaskA,用Browser查看任務(wù),可以看到任務(wù)MultiTaskTestTaskA出于掛起態(tài)(suspended),表明程序執行了taskSuspend(0)語(yǔ)句。
* 運行另一個(gè)Tornado集成環(huán)境
* Attach任務(wù)MultiTaskTestTaskA,
* 在語(yǔ)句msgQReceive(g_MsgQ2id,cMsgFromTaskB,100,WAIT_FOREVER)的下一條語(yǔ)句處設置斷點(diǎn)
* 運行任務(wù)MultiTaskTestTaskA??梢钥吹?jīng)]有執行到斷點(diǎn)處,用Browser查看任務(wù)狀態(tài),MultiTaskTestTaskA出于阻塞態(tài)(pended),因為它在等待消息。
* 單步執行MultiTaskTestInit到產(chǎn)生MultiTaskTestTaskB任務(wù)的下一條語(yǔ)句,可以看到MultiTaskTestTaskB任務(wù)處于掛起態(tài)
* 再運行另一個(gè)Tornado集成環(huán)境
* Attach任務(wù)MultiTaskTestTaskB,
* 在語(yǔ)句msgQReceive(g_MsgQ1id,cMsgFromTaskA,100,WAIT_FOREVER)下一條語(yǔ)句處設置斷點(diǎn)
* 運行任務(wù)MultiTaskTestTaskB??梢钥吹綀绦械綌帱c(diǎn)處停下。這是因為MultiTaskTestTaskA任務(wù)已經(jīng)發(fā)送一條消息到MultiTaskTestTaskB的接收隊列中。
* 此時(shí),可以看到MultiTaskTestTaskA任務(wù)也運行到斷點(diǎn)處,因為為MultiTaskTestTaskB任務(wù)已經(jīng)發(fā)送一條消息到MultiTaskTestTaskA的接收隊列中。
酸菜 (1899-12-30)
9、系統調試模式下程序的調試
Tornado集成環(huán)境提供兩種調試模式:任務(wù)調試模式和系統調試模式。在任務(wù)調試模式下,在一個(gè)集成環(huán)境下一個(gè)時(shí)間內只能調試一個(gè)任務(wù)。調試只影響當前被調試的任務(wù),其它任務(wù)正常運行。在系統調試模式下,可以同時(shí)調試多個(gè)任務(wù)、中斷服務(wù)程序(ISR),調試影響整個(gè)系統。
Tornado1.0集成環(huán)境下,在系統模式下進(jìn)行程序調試,主機與目標機之間必須使用串口通信。Tornado2.0集成環(huán)境提供了通過(guò)網(wǎng)口進(jìn)行系統模式調試的功能。
系統缺省使用網(wǎng)口通信,如果需要使用串口通信,需要修改文件C: Tornado target config
} all configAll.h的一些宏定義,修改為:
#define WDB_COMM_TYPE WDB_COMM_SERIAL /*使用串口通信*/
#define WDB_TTY_CHANNEL 0 /*使用第一個(gè)串口*/
#define WDB_TTY_BAUD 38400 /*波特率:38400bps*/
重新編譯鏈接vxWorks。
在啟動(dòng)目標服務(wù)器時(shí),要選擇串口通信,并進(jìn)行相應配置。
9.1 系統調試模式下多任務(wù)的調試:
調試使用的源代碼與任務(wù)調試模式中使用的代碼相同。但是,需要去掉為了能夠在任務(wù)調試模式下進(jìn)行多任務(wù)調試的MultiTaskTestTaskA和MultiTaskTestTaskB中的語(yǔ)句taskSuspend(0);。
多任務(wù)調試步驟:
* 用-g選項編譯源代碼產(chǎn)生目標文件。
* 下載產(chǎn)生的目標文件。
* 在MultiTaskTestInit函數的開(kāi)始設置斷點(diǎn)。
* 在Debugger命令窗口輸入命令attach system進(jìn)入系統調試模式。
* 在Shell窗口輸入命令sp MultiTaskTestInit產(chǎn)生一個(gè)以MultiTaskTestInit為入口函數的任務(wù),因為整個(gè)系統都停下了,新產(chǎn)生的任務(wù)還沒(méi)有執行,這可以通過(guò)在Debugger命令窗口輸入命令info threads顯示當前系統中的任務(wù)列表看出來(lái)。
* 執行菜單命令Debug | Continue繼續運行程序。
* 系統在設置的斷點(diǎn)處停下。
* 在函數MultiTaskTestTaskA中的語(yǔ)句msgQReceive(g_MsgQ2id,cMsgFromTaskB, 100,WAIT_FOREVER)的下一條語(yǔ)句處設置斷點(diǎn)。
* 在函數MultiTaskTestTaskB中的語(yǔ)句msgQReceive(g_MsgQ1id,cMsgFromTaskA, 100,WAIT_FOREVER)的下一條語(yǔ)句處設置斷點(diǎn)。
* 執行菜單命令Debug | Continue繼續運行程序。
* 程序在任務(wù)MultiTaskTestTaskB中的斷點(diǎn)處停下(為什么不是在任務(wù)MultiTaskTestTaskA中停下?請考慮)。
* 執行菜單命令Debug | Continue繼續運行程序。
* 程序在任務(wù)MultiTaskTestTaskA中的斷點(diǎn)處停下。
* 執行菜單命令Debug | Continue繼續運行程序。
* 程序又一次在任務(wù)MultiTaskTestTaskA中的斷點(diǎn)處停下(為什么停兩次?請考慮)。
* 執行菜單命令Debug | Continue繼續運行程序。
* 程序在任務(wù)MultiTaskTestTaskB中的斷點(diǎn)處停下。
9.2 中斷服務(wù)程序的調試
中斷服務(wù)程序只能在系統調試模式下調試,不能在任務(wù)調試模式下調試。因為中斷服務(wù)程序是作為系統的一部分運行,不是以任務(wù)方式運行,因此不需要為它產(chǎn)生任務(wù)。
中斷服務(wù)程序調試步驟:
* 用-g選項編譯源代碼產(chǎn)生目標文件。
* 下載產(chǎn)生的目標文件。
* 在MultiTaskTestInit函數的開(kāi)始設置斷點(diǎn)。
* 在Debugger命令窗口輸入命令attach system進(jìn)入系統調試模式。
* 執行菜單命令Debug | Continue繼續運行程序。
* 如果產(chǎn)生相應的中斷,程序就會(huì )在中斷服務(wù)程序的斷點(diǎn)處停下。進(jìn)行需要的調試。
------------------------全文完------------------------------
linux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂)
評論