初涉學(xué)USB,初學(xué)者USB入門總結(jié)
一,概述
現(xiàn)在很多的主控上都帶有USB的功能,但是對于初學(xué)者來說,這方面應(yīng)用還是比較棘手,因?yàn)閡sb的不但固件程序需要編寫,PC端的驅(qū)動(dòng)也要編寫,而且驅(qū)動(dòng)寫好了還要寫個(gè)上位機(jī)才能看出效果。這樣調(diào)試起來十分困難,建議從USB的鍵盤,鼠標(biāo)開始做,了解清楚了,再做自己的協(xié)議就比較簡單了。
USB的概念歷史啥的這里就不說了。我們先不管具體的數(shù)據(jù)包格式,這一節(jié)先從整個(gè)包的層面上簡單的說,過程是這樣的,
---------------------------------------設(shè)備插入-------------------------------------------------------------
1)??? 主機(jī)會(huì)輪回查詢各個(gè)USB端口,主機(jī)檢測到D+與D-之間有電壓差,就認(rèn)為有新的設(shè)置接入。主機(jī)等待100ms后發(fā)出復(fù)位請求。設(shè)備接到復(fù)位請求后將產(chǎn)生一個(gè)外部中斷信號。
---------------------------------------枚舉過程------------------------------------------------------------
2)??? 主機(jī)這時(shí)候只是知道有新的設(shè)備插入了,但是不知道插進(jìn)來個(gè)什么東西,所以就開始詢問它是什么設(shè)備,怎么用,負(fù)荷能力怎么樣。這個(gè)時(shí)侯就進(jìn)入了枚舉過程。因?yàn)閯倓偛迦氲脑O(shè)備沒有分配地址,就用默認(rèn)地址0,首先發(fā)送一個(gè)Get_descriptor(獲取設(shè)備描述符)指令包,設(shè)備接到包后就開始解析包(其實(shí)就是你在固件程序里判斷處理) ,然后按固定格式返回自己設(shè)備的設(shè)備描述符,這一步主要是主機(jī)知道你的USB設(shè)備的基礎(chǔ)屬性,比如支持的傳輸數(shù)據(jù)長度,電流負(fù)荷多少,支持那個(gè)USB版本,以及以后方便電腦找驅(qū)動(dòng)的PID,VID。
3)??? 這時(shí)候主機(jī)知道你(你做的設(shè)備,簡稱你吧)的數(shù)據(jù)長度還有電流大小后,下一步就是給你分配一個(gè)屬于你的地址。
4)??? 給你一個(gè)地址后就開始詢問你的具體配置。首先發(fā)送一個(gè)試探性的設(shè)備配置請求Get_configuration(要求固定返回9個(gè)設(shè)備配置字),你接到后就開始發(fā)送9字節(jié)的設(shè)備配置字,其中包括你的配置字的總長度,這樣主機(jī)就知道你的配置到底有多長,然后再發(fā)一次設(shè)備配置請求,這時(shí)你就開始上傳所有的配置字。這個(gè)時(shí)侯主機(jī)就已經(jīng)很明白你的工作方式就各種特性,然后就可以正常工作了
5)??? 如果你在前面的某些配置(以后章節(jié)詳細(xì)說明)要求要說明自己的名字什么的,這里還要上傳字符串描述符。
6)??? 如果是鼠標(biāo)或者鍵盤還要上傳報(bào)告描述符
---------------------------------------正常數(shù)據(jù)階段------------------------------------------------------
7)??? 這個(gè)時(shí)侯你已經(jīng)被主機(jī)正式接受并且注冊了,你可以通過自己寫測驅(qū)動(dòng)或通用驅(qū)動(dòng)與電腦進(jìn)行通訊了。
以上是簡單的描述,詳細(xì)的后面章節(jié)再做介紹,學(xué)習(xí)一個(gè)東西關(guān)鍵是首先要知道這個(gè)東西是什么,簡單的工作原理。對于USB的工作我這里做個(gè)比方,
???? 主機(jī)好比一個(gè)公司,你就是USB設(shè)備,要進(jìn)入公司首先要面試(枚舉),你到了面試現(xiàn)場(第一次插入設(shè)備),面試官首先了解到你的外表,性別已經(jīng)你要應(yīng)聘的崗位(設(shè)備描述符),然后給你一個(gè)號,以后就開始按號叫人,當(dāng)你被叫到就開始問你的專業(yè)知識,性格等(配置描述符),如果你比較合適(通過了枚舉)你就會(huì)錄取了,并且注冊一個(gè)你的信息到公司(驅(qū)動(dòng)安裝,并且寫入注冊表)。等你下次來公司,只要把工號(PID,VID)報(bào)上,就知道是你來了。
初涉USB,初學(xué)者USB入門總結(jié)(2) 設(shè)備固件程序
二,實(shí)際數(shù)據(jù)過程測試
(圖片顏色顯示不出,可以到我博客http://blog.csdn.net/arthur05611/archive/2009/02/23/3929778.aspx)
這節(jié)主要是對固件里的USB請求處理有個(gè)概念,還有就是調(diào)試的方法。大篇幅的程序配合,如果不關(guān)心這一塊的話可以跳過,呵呵。
為了更好的說明整個(gè)USB啟動(dòng)過程,我們可以用串口實(shí)時(shí)的跟蹤各個(gè)USB中斷。不過這里先不用串口進(jìn)行測試,只是簡單的用一組變量記錄過程。測試程序如下(以下會(huì)有程序的說明):
uchar test[100];//100長度的變量,記錄過程
uchar conters=0;//記錄計(jì)數(shù)值,
/*------------------------------------------------------------
??????? 高校電子聯(lián)盟--肖繼達(dá)
???? QQ:258347765???
-------------------------------------------------------------*/
void EXT_int(void)//USB中斷響應(yīng)函數(shù)
{
??? /*------------------------------------------------------------
????????? Check interrupt status register to know interrupt
?????? source.
??? ------------------------------------------------------------*/
??? if (USB_BUSRESET_ASS_INT())
??? {?? /* USB bus reset */
??????? /*? for USB Rev.1.1
???????????????????? After USB bus reset released, 10msec recoverly time we have.
???????????????????? Follwing request must be processed normally.
??????? */
??????? CLR_BUS_RESET_STATE();? /* USB bus reset status clear */
??????? /*------------------------------------------------------------
?????????? Endpoint0 setting
??????? ------------------------------------------------------------*/
??????? /* Tx/Rx payload size setting */
??????? /* Rx payload is fixed as 8-byte or 32-byte, therefor the
?????????? setting has no meaninig */
??????? SET_PAYLOAD_EPn(EP0RX, device_descriptor.bMaxPacketSize0);
??????? SET_PAYLOAD_EPn(EP0TX, device_descriptor.bMaxPacketSize0);
??????? /* Stall bit, the value undefined after reset, cleared */
??????? CLR_STALL_EPn(EP0);
?????????????
??????? /*------------------------------------------------------------
?????????? Misceronous status variable initialization
??????? ------------------------------------------------------------*/
??????? usb_status.configuration = NULL;
??????? usb_status.remote_wakeup = 0;
??????? usb_status.address = 0;
??????? usb_status.dvcstate = DEFAULT_STATE;??? /* Device state :DEFAULT */
??????? usb_status.stall_req = 0;
?????????????? #ifdef Debug
???????????????????? test[conters]='!';
???????????????????? conters++;
???????????????????? #endif
??????? /*------------------------------------------------------------
?????????? Callback to application layer
??????? ------------------------------------------------------------*/
??????? (*usb_status.callback)();
??? }
??? else if (SUSPENDED_INT())
??? {?? /* suspended state */
??????? /* for USB Rev.1.1
???????????????????? Transit to suspended state after detect the USB line has kept idle over 3msec.
???????????????????? After resume detected, end suspend state in 3msec to be able to respond
???????????????????? the host request.
??????? */
????????????? CLR_SUSPENDED_STATE();
???????????????????? #ifdef Debug
???????????????????? test[conters]='@';
???????????????????? conters++;
???????????????????? #endif
??? }
??? else if (AWAKE_INT())
??? {?? /* Deveice awake state */
??????? /* AWAKE procedure */
??????? CLR_AWAKE_STATE();????????? /* Request clear */
???????????????????? #ifdef Debug
???????????????????? test[conters]='#';
???????????????????? conters++;
???????????????????? #endif
??? }
??? else if (USB_BUSRESET_DES_INT())
??? {?? /* USB bus reset deassert */
??????? /* Procedure for USB bus reset de-assert */
???????
??????? CLR_BUS_RESET_DES_STATE();? /* Request clear */
???????????????????? #ifdef Debug
???????????????????? test[conters]='$';
???????????????????? conters++;
???????????????????? #endif
??? }
??? else if (SOF_INT())
??? {?? /* SOF interrupt status */
??????? CLR_B_SOF_STATE();??
?????????????? #ifdef Debug
???????????????????? test[conters]='%';
???????????????????? conters++;
???????????????????? #endif
?????? /* SOF interrupt status clear */
??? }?? /* SOF interrupt status */
??? if (SETUP_RDY_INT())
??? {?? /* setup ready */
????????????????? #ifdef Debug
???????????????????? test[conters]='^';
???????????????????? conters++;
???????????????????? #endif
??????? read_Device_Requests();
??? }
??? else if(EP1_PKTRDY_INT())
??? {?? /* EP1 packet ready */????
??????? read_FIFO(EP1);
?????? }
??? else if (EP2_PKTRDY_INT())
??? {?? /* EP2 packet ready */
??????? write_FIFO(EP2);
??? }
??? else if (EP0_RXPKTRDY_INT())
??? {?? /* EP0 receive packet ready */
??????? read_FIFO(EP0RX);
??? }
??? else if (EP0_TXPKTRDY_INT())
??? {?? /* EP0 transmit packet ready */
??????? write_FIFO(EP0TX);
??? }
}
計(jì)錄的結(jié)果在變量查看中顯示如下:
首先我解釋一下,這段程序是我在做USB設(shè)備時(shí)的中斷函數(shù)。主控(就是你往里面寫固件程序的那個(gè)東西)會(huì)在要求設(shè)備進(jìn)行操作時(shí),產(chǎn)生一個(gè)相應(yīng)的中斷(我們可以用中斷的方式,也可以用查詢的方式,中斷的方式的好處就是主機(jī)有需要操作的都會(huì)叫你,而用查詢你必須不斷的問主機(jī)“有事么”,這里采用中斷方式),比如主機(jī)給設(shè)備設(shè)置地址,主機(jī)會(huì)通過固定的通道(point0)發(fā)送一個(gè)‘設(shè)定地址’包,設(shè)備主控接到包后會(huì)產(chǎn)生中斷,并且把響應(yīng)的狀態(tài)保存在相應(yīng)的寄存器中,我們只要在中斷程序判斷各個(gè)寄存器就能完成主機(jī)的任務(wù)。
程序中藍(lán)色字是中斷類型的判斷,其對應(yīng)的宏定義就不列出來了。如果是這個(gè)中斷就會(huì)執(zhí)行相應(yīng)的中斷操作。并且一次中斷只有一種中斷類型,我們在每個(gè)中斷響應(yīng)中加一段紅色字的程序,是為了保存每次中斷的狀態(tài),比如剛插上設(shè)備,來了一次BUSRESET總線復(fù)位中斷,就會(huì)進(jìn)入相應(yīng)的中斷操作,完了后記錄狀態(tài)test[conters]='!'; conters++;意思是進(jìn)入了這個(gè)中斷就在這一組數(shù)的當(dāng)前位置設(shè)成'!',并且位置記錄的變量加一,以便下一次記錄到下一個(gè)位置。這樣USB的過程我們就記錄了下來,
???? 下面看一下記錄結(jié)果(其中的數(shù)字和字母是響應(yīng)標(biāo)準(zhǔn)請求時(shí)的程序產(chǎn)生的這里不羅列程序了)。
file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image002.jpg
可以看到,一開始是一次總線復(fù)位,然后USB bus reset de-assert,然后再掛起總線。重復(fù)了兩次,然后就是上一節(jié)的具體配置了。
這節(jié)主要是對固件里的USB請求處理有個(gè)概念,還有就是調(diào)試的方法。
?
初涉USB,初學(xué)者USB入門總結(jié)(3) 數(shù)據(jù)包闡述
對于USB傳輸大體有個(gè)概念,下一步就來看看到底USB上傳的什么東西,以什么格式傳數(shù)據(jù),先不涉及端點(diǎn)的概念。
各種總線的數(shù)據(jù)傳輸都是以固定的層次協(xié)議進(jìn)行的,USB當(dāng)然也不例外。所謂的層次也只是個(gè)抽象的概念罷了,就是表達(dá)一種依附關(guān)系,上層要依賴與底層,上層以底層為基礎(chǔ),上層只需要關(guān)心自己的東西就行了,如果你還不明白,那就繼續(xù)看,學(xué)習(xí)一個(gè)東西不可能一兩句話說的明白一個(gè)點(diǎn),需要全面了解后才能清楚各個(gè)點(diǎn)。
要實(shí)現(xiàn)兩個(gè)機(jī)器(機(jī)器的范圍比較廣,可以是電腦,交換機(jī),單片機(jī))的通信總是要有一個(gè)載體才可以,對于機(jī)器當(dāng)然是電平高低為載體,具體的說機(jī)器甲要告訴機(jī)器乙一件事情(比如說一條指令),那么機(jī)器甲可以通過一根線(串行數(shù)據(jù)總線)連到機(jī)器乙的一個(gè)IO口上,甲發(fā)送一個(gè)個(gè)的高低電平,乙固定時(shí)間檢測自己的這個(gè)IO口,然后逐個(gè)記錄下放到自己的緩沖里,這樣乙就收到甲送的數(shù)據(jù)了。上述就是一個(gè)簡單的數(shù)據(jù)鏈路層(計(jì)算機(jī)網(wǎng)絡(luò)里這么叫)的描述,這一層要保證的就是甲發(fā)的每一位數(shù)據(jù),乙都可以正確及時(shí)的接受,并且對在傳輸過程中出錯(cuò)的數(shù)據(jù)做出反應(yīng)。其實(shí)比數(shù)據(jù)連路更底層的還有物理層,這就是真正的物理介質(zhì),對于機(jī)器就是電線了,數(shù)據(jù)就是電線上傳輸?shù)碾妷?USB是用的四線,兩個(gè)電源,兩個(gè)數(shù)據(jù)線。
這里也打個(gè)比方,比如人與人進(jìn)行交流,我們當(dāng)然是通過說話了,物理層就是空氣和傳輸?shù)穆暡ǎ瑪?shù)據(jù)鏈路層就是我們說的每一個(gè)字,物理層就是空氣,負(fù)責(zé)把我們說的話轉(zhuǎn)換成聲波傳給對方,數(shù)據(jù)鏈路層負(fù)責(zé)讓對方能正確的聽到每個(gè)字,如果聽的不清可以告訴對方重新說一遍。
經(jīng)過上述的兩個(gè)底層,就可以保證每一位數(shù)據(jù)可以正確的傳到對方那里去。下一步的工作當(dāng)然是解析數(shù)據(jù)代表了什么,一般來說,數(shù)據(jù)都是以一串?dāng)?shù)為單位,一般稱為一個(gè)包,機(jī)器間傳輸都是以一個(gè)包為單位傳出,就像人們說話都是以一句話為單位輸出一樣。每一個(gè)包包含有許多位數(shù)據(jù),這些數(shù)據(jù)又分段表示不同的意義,如圖一,這是一個(gè)USB令牌階段的包,Sync是同步數(shù)據(jù)(相當(dāng)于說話時(shí)先打個(gè)招呼,告訴對方要跟他說話了),PID是包標(biāo)示(告訴對方這個(gè)包是干什么用的),ADDR是對方的地址(叫對方的名字),ENDP是用端點(diǎn)幾通訊(先不介紹這個(gè)),CRC5是校驗(yàn)位(判斷這個(gè)包是否在傳輸中出錯(cuò)),EOP是包結(jié)束。
|--------------------------------------------------------|
|?? Sync? |? PID? |? ADDR? |? ENDP? |? CRC5? |? EOP????? |
|________________________________________________________|
????????????????????? 圖一
USB的數(shù)據(jù)包又分為三種,一個(gè)是令牌包,一個(gè)是數(shù)據(jù)包,另一個(gè)是握手包。每一次的USB通訊事務(wù)處理都是以令牌包開頭,告訴對方要跟誰說話,這句話是用來干嘛的。如果要求有數(shù)據(jù)傳輸,則下一步就是數(shù)據(jù)包,另外如果要求對方要有反饋,則會(huì)發(fā)出握手包。令牌包又簡單的包括OUT,IN,STEP三種類型,OUT是用于主機(jī)告訴設(shè)備主機(jī)要向USB設(shè)備發(fā)送數(shù)據(jù),IN是用于主機(jī)告訴設(shè)備要上傳數(shù)據(jù),而STEUP是用于主機(jī)向USB設(shè)備發(fā)送配置信息,在枚舉過程中會(huì)用到。另外數(shù)據(jù)包和握手包的具體格式什么的,可以參照詳細(xì)的協(xié)議。
可以看到在所以的通訊過程中,主機(jī)都是發(fā)起者,不管是主機(jī)發(fā)送數(shù)據(jù)到USB設(shè)備還是USB設(shè)備發(fā)送數(shù)據(jù)到主機(jī),都必須收主機(jī)控制。圖二為一次事務(wù)的過程
??
??????? 令牌階段?? ——》??????? 數(shù)據(jù)階段???? ——》???? 握手階段
??????????????????????????????? 圖二
這個(gè)過程可以這樣描述,甲和乙對話,甲是老板,乙是職員。第一節(jié)已經(jīng)講過了,乙面試就是枚舉,在這個(gè)過程中,甲多段的發(fā)送STEP令牌包給乙,乙收到后如果要反饋數(shù)據(jù),就發(fā)數(shù)據(jù)包給甲,甲正確接收后,跟甲握握手,表示這次對話成功。
乙被正式錄取后,甲會(huì)分派任務(wù)(OUT),這時(shí)甲對乙說有任務(wù)給你(令牌階段),然后乙就開始聽,甲說你的任務(wù)就是記錄數(shù)據(jù)并且上報(bào)(這段話就是數(shù)據(jù)包),乙說好的(握手包)。
乙開始正式工作,并且記錄數(shù)據(jù)。過了一段時(shí)間,甲開始要求提交數(shù)據(jù)(IN),乙把數(shù)據(jù)報(bào)告給甲(數(shù)據(jù)階段),甲說好(握手成功)。這里乙不能主動(dòng)的去向老板匯報(bào),只能被動(dòng)的干活。
上面已經(jīng)講USB主機(jī)和設(shè)備間數(shù)據(jù)傳輸?shù)倪^程,都是我個(gè)人理解,有不正確和不到位的大家提出,方便初學(xué)者理解,謝謝??
初涉USB,初學(xué)者USB入門總結(jié)(4)USB通訊設(shè)備快速開發(fā)
經(jīng)過上述三節(jié)的描述,對USB應(yīng)該已經(jīng)有了初步的認(rèn)識,其中具體的協(xié)議(比如各個(gè)描述符的定義什么的)這里不做描述了,網(wǎng)上一搜一大堆。下面我以一個(gè)實(shí)例來詳細(xì)說明快速開發(fā)USB設(shè)備的步驟,
一,設(shè)定規(guī)劃
凡事預(yù)則立,不預(yù)則費(fèi),所以開發(fā)一個(gè)小小的USB也要稍微規(guī)劃一下,比如想象要實(shí)現(xiàn)什么功能,傳輸?shù)臄?shù)據(jù)協(xié)議什么的。
二,固件編程,
固件編程說白了就是寫單片機(jī)程序,要實(shí)現(xiàn)USB一般可以使用帶USB功能的單片機(jī),再個(gè)就是加一個(gè)專用的USB芯片。這里以內(nèi)部集成USB功能單片機(jī)為例
固件的USB開發(fā)一般就是先使能USB,使能USB時(shí)鐘,使能各個(gè)USB控制中斷(掛起,復(fù)位,標(biāo)準(zhǔn)請求,寫入,寫出等)然后USB就能正常工作了,這時(shí)候不如不寫別的東西,電腦就可以檢測出有USB設(shè)備插入了,具體的反應(yīng)是在設(shè)備管理器里會(huì)發(fā)現(xiàn)閃了一下說明發(fā)現(xiàn)了新的USB設(shè)備,接下來電腦會(huì)發(fā)送各種標(biāo)準(zhǔn)請求,因?yàn)檫@個(gè)時(shí)候你的程序還沒寫完整,對這些請求不會(huì)有反應(yīng),所以電腦不可能識別出是什么東西。
接下來的工作就是在中斷中響應(yīng)電腦傳來的各種標(biāo)準(zhǔn)請求。當(dāng)必要的請求都被正確的響應(yīng)的話,這個(gè)時(shí)候如果電腦里有正確的驅(qū)動(dòng),電腦就會(huì)去加載這個(gè)驅(qū)動(dòng),如果是第一次插入這個(gè)設(shè)備,還要把驅(qū)動(dòng)安裝一下,然后設(shè)備就進(jìn)入正常工作了,電腦會(huì)顯示“這個(gè)USB已經(jīng)成功安裝并可以應(yīng)用了”。
這里捎帶著說一下端點(diǎn)(endpoint)的概念,一般一個(gè)USB設(shè)備都會(huì)有數(shù)個(gè)端點(diǎn),端點(diǎn)就是一個(gè)數(shù)據(jù)緩沖控制區(qū)(FIFO),每個(gè)緩沖區(qū)相當(dāng)于有一個(gè)出口一個(gè)進(jìn)口的池子,數(shù)據(jù)通過進(jìn)口進(jìn)入到池子,然后你再在固件里去用這些數(shù)據(jù)。固件往電腦寫數(shù)據(jù),也是把數(shù)據(jù)先放到池子里,然后打開出口,就可以干自己的事情,不用一個(gè)個(gè)的把數(shù)據(jù)發(fā)出了,池子的出口自動(dòng)把數(shù)據(jù)流出。
一般的端口0是用來做標(biāo)準(zhǔn)請求響應(yīng)用的,也就是在枚舉階段用到。我一般把端口1定義為出(OUT),端口2定義為入(IN)(注意,這個(gè)OUT和IN是相對與電腦的,也就是說OUT是數(shù)據(jù)從電腦出去到設(shè)備,IN是設(shè)備的數(shù)據(jù)進(jìn)入電腦)。這些定義也是在標(biāo)準(zhǔn)請求中去告訴電腦的。
接下來就可以實(shí)現(xiàn)與電腦的通訊了,你把數(shù)據(jù)放到相應(yīng)的池子里就行了。下面就可以自己定義通訊的數(shù)據(jù)格式了。比如控制開發(fā)板上的8個(gè)LED的第一個(gè)燈亮,那么上位機(jī)發(fā)送數(shù)據(jù)0x55,0x01,0x80,0xaa。我們就可以規(guī)定第一個(gè)數(shù)據(jù)是啟示位,遇到這個(gè)表明開始一次控制指令,0x01表示這個(gè)是控制燈亮暗的指令,0x80表示LED的控制數(shù)據(jù),最高位是1,表示第一個(gè)亮,其他位是0,表示都暗。最后一個(gè)數(shù)據(jù)是0xaa,表示這是結(jié)束。其實(shí)所謂的數(shù)據(jù)協(xié)議不過就是自己定義的一套讓通訊雙方都能正確理解對方的數(shù)據(jù)格式。電腦比較是電腦,什么都要規(guī)定好了,它才能正確的工作。
三,驅(qū)動(dòng)程序
??? 對于快速開發(fā)用Driverstudio就可以了,我先裝了VC6.0,然后裝了DDK2600,最后裝了Driverstudio,網(wǎng)上有說這個(gè)順序不容易出問題,我也沒時(shí)間去試別的順序會(huì)出怎么樣的特效,姑且不管他是否在忽悠,先這樣按了沒壞處。
??? 我一開始比較新潮的裝了DriverStudio3.2版本,然后按網(wǎng)上的方法破解了,生成了驅(qū)動(dòng)是能打開設(shè)備,但是就是傳輸不了數(shù)據(jù),搞了兩天還是不行,后來想到是不是3.2版本太新了?或者破解沒完整?然后卸載了3.2裝了3.1,果然可以了,真不知道是Compuware做了手腳故意玩我還是本人愚笨弄錯(cuò)了哪里。
驅(qū)動(dòng)生成的步驟可以在百度,Google里搜“10分鐘完成一個(gè)USB驅(qū)動(dòng)程序”能出來一
大堆,要是你嫌搜索麻煩就直接點(diǎn)這個(gè)算了http://www.4oa.com/Article/html/6/33/482/2005/17317.html按那個(gè)步驟操作就可以了,根據(jù)向?qū)Р僮魍炅艘院?,VC就會(huì)出來一個(gè)驅(qū)動(dòng)程序框架了,如果你在這個(gè)時(shí)候編譯一下就可你會(huì)碰到很多問題,我的操作是這樣的。首先把DDK的庫編譯一下,操作網(wǎng)上有, 網(wǎng)上有云:
1.啟動(dòng)Visual C++ 。
2.選擇菜單 File|Open Workspace。打開位于DriverStudio/DriverWorks/Source/vdwlibs.dsw的工作空間文件。
3.選擇菜單 Build|Batch Build,在彈出的對話框中選擇你想編譯的庫。
4.點(diǎn)擊Build編譯你選擇的庫。
然后在VC的Driverstudio的工具條點(diǎn)擊“change environment variables”,在第一個(gè)選型卡把DDK的路徑選上,我的是C:\WINDDK\2600。然后點(diǎn)OK,接下來點(diǎn)DriverStudio工具條的編譯,就可以了,如果你還是碰到問題,你可以把VC顯示的錯(cuò)誤復(fù)制到百度。
評論