DWORD dwIoControlCode, // operation,IOCTL操作碼
LPVOID lpInBuffer, // input data buffer,輸入數(shù)據(jù)緩沖//區(qū)
DWORD nInBufferSize, // size of input data buffer,輸入//數(shù)據(jù)緩沖區(qū)大小
LPVOID lpOutBuffer, // output data buffer,輸出數(shù)據(jù)緩沖//區(qū)
DWORD nOutBufferSize, // size of output data buffer,輸出
//數(shù)據(jù)緩沖區(qū)大小LPDWORD lpBytesReturned, // byte count,通訊字節(jié)計數(shù)
LPOVERLAPPED lpOverlapped // overlapped information,異步通訊//信息
); 參數(shù)中的dwIoControlCode對應著驅(qū)動中定義的IOCTL操作碼。該操作碼唯一定義了驅(qū)動的各項操作,比如讀寫端點1,讀寫端點2等。其他參數(shù)請參考msdn。
利用上述函數(shù),分別編寫VC中讀寫各端點的函數(shù)。在本人提供的應用程序?qū)嵗锒x了以下幾個函數(shù):
DWORD CTestDevice::Endpoint1ReadPipes(UINT Length, void *pBuffer)
DWORD CTestDevice::Endpoint1WritePipes(UINT Length, void *pBuffer)
DWORD CTestDevice::ReadBulkPipes(UINT Length,void* pBuffer,DWORD* dwBytesTransferred)
DWORD CTestDevice::WriteBulkPipes(UINT Length,void* pBuffer,DWORD* dwBytesTransferred)
在程序中,定義一個CTestDevice類,然后調(diào)用上面的函數(shù)即實現(xiàn)了對4個D12端點的同步讀寫操作。由于異步讀寫需要更深層次的驅(qū)動的知識,所以不做探討。
當PC應用軟件希望發(fā)送數(shù)據(jù)給單片機時,只需調(diào)用Endpoint1WritePipes或者WriteBulkPipes(針對不同端點,下同)函數(shù),剩下的USB底層數(shù)據(jù)傳送則交給了驅(qū)動與D12。當數(shù)據(jù)傳送過來后,D12便觸發(fā)中斷,單片機在查詢了中斷寄存器后便知道PC通過哪個端點發(fā)送數(shù)據(jù)過來,隨后讀出該端點緩沖區(qū)的數(shù)據(jù),進行操作。
當單片機需要發(fā)送數(shù)據(jù)給PC應用軟件時,只要調(diào)用D12_WriteEndpoint函數(shù)即可將數(shù)據(jù)通過D12傳送到PC端。那么PC應用軟件怎么知道數(shù)據(jù)已經(jīng)過來了呢?在同步數(shù)據(jù)讀寫方式下,PC應用軟件一般采用查詢的方式。大家可以看到DeviceIoControl函數(shù)中定義了輸出緩沖區(qū)和輸入緩沖區(qū)。PC應用軟件在得到單片機發(fā)送過來的數(shù)據(jù)前,一直查詢輸入緩沖區(qū)的數(shù)據(jù)有沒變化。一旦數(shù)據(jù)有變化,表明單片機已經(jīng)發(fā)送數(shù)據(jù)過來,然后讀出緩沖區(qū)的數(shù)據(jù)進行操作。當然這有個很大的缺點,就是PC應用軟件進行查詢時,就不能再做別的事情了,線程被阻塞。這個可以通過多線程的方式解決。
當采用異步讀寫的時候,就可以避免上面的問題,它類似與一種中斷機制,即當數(shù)據(jù)傳送過來時,驅(qū)動會發(fā)送一個IRP包通知應用程序。在這之前,應用程序完全可以處理別的事情,而不需要等待。當然這種方式是以增加驅(qū)動程序難度為代價的,對于初學者來說還是過于復雜了。





