文獻標識碼: A
DOI:10.16157/j.issn.0258-7998.2017.02.029
中文引用格式: 王嘉駿,楊錄,韓志毅,等. 車架號碼區域隱藏焊縫檢測系統的定位裝置[J].電子技術應用,2017,43(2):120-123.
英文引用格式: Wang Jiajun,Yang Lu,Han Zhiyi,et al. The positioning device for the detection system of the frame number area hidden weld[J].Application of Electronic Technique,2017,43(2):120-123.
0 引言
車架號碼是由阿拉伯數字和字母組成的17位編碼,對車輛具有唯一識別性,因此被稱為“汽車身份證”[1]。被盜車輛的車架號碼區域通常會被整體摳掉,并重新焊接刻有偽造車架號碼的鋼板,再通過打膩子和噴漆的方法隱藏焊縫,從而逃避交警的追查[2]。針對這種情況,現常使用超聲無損檢測技術,通過分析超聲回波來判定車架的完整性。但是,這種方法僅可作為一種甄別手段,對于刑事訴訟仍缺少有力的證據。所以,本文將通用鼠標改造成一位置傳感器,在檢測過程中對隱藏焊縫進行定位,再結合超聲回波信號,生成對檢測區域內部結構的俯視灰度圖,進一步判斷車架的完整性并提供有力證據。
在對車架區域檢測掃描的過程中,為了獲得檢測區域內部結構的俯視圖,須實時獲得超聲探頭的二維坐標。本文通過將編寫的下層過濾驅動程序安裝到USB(通用串行總線)鼠標,使其成為一個虛擬的位置傳感器來實現定位。最終,檢測系統將采集到的超聲回波信號和相應的探頭位置信息匹配,實現實時計算檢測過程中超聲探頭的運動軌跡和生成檢測區域內部結構的俯視圖,并使得檢測設備具有便攜和靈活的特點。
1 USB鼠標驅動模型
1.1 Windows驅動模型概述
Windows驅動程序在Windows主機應用程序和物理設備之間采用了靈活的分層驅動方式。分層式的結構具有很好的可移植性和兼容性,開發者可利用已有的系統驅動程序來開發滿足客戶需要的驅動程序。
在標準的Windows系統驅動程序分層結構的模型中,功能驅動程序和總線驅動程序是兩個最為重要的驅動程序。其中,總線驅動程序負責主機和硬件設備的連接,由操作系統提供,用戶無須干預。功能驅動程序是用戶根據需要自己開發,一個完整的功能驅動程序包含多個例程,當Windows系統接收到一個IRP(I/O請求包)時,系統就會調用相應的驅動程序例程來執行操作。
有些設備還需要安裝過濾驅動程序,過濾驅動程序根據功能的不同分成上層過濾驅動程序和下層過濾驅動程序兩種。其中上層過濾驅動程序作用于功能驅動程序之上,為指定設備提供附加的功能支持。下層過濾驅動程序作用于功能驅動程序之下,且數據須經過下層過濾驅動程序處理后再向下傳輸[3]。
這樣下層過濾驅動程序可以對數據進行捕捉、修改或者攔截的操作,進而重新定義硬件行為。本文就是使用這類過濾驅動程序來開發位置傳感器。
1.2 HID USB鼠標的驅動程序設備棧模型
圖1是USB鼠標在Windows系統環境中的訪問流程。在圖中,一個HID類應用程序可以調用含有系統HID類驅動程序hidclass.sys的HID類設備棧。HID類驅動程序又調用HID小驅動程序和硬件設備進行USB通信,在訪問過程中需要經過下層過濾驅動程序hidparse.sys進行語法分析。
當USB鼠標插入到計算機后會先經過USB棧被識別為USB設備,因為它也是HID類設備,所以系統會同時裝入HID類的驅動棧;當HID類驅動程序通過HID小驅動程序hidparse.sys讀取到USB鼠標的報告描述符時,系統依據對報告描述符中usage項的判斷,識別當前設備為鼠標。因此鼠標驅動程序也會在HID類驅動棧之上的位置裝入系統,這樣完整的驅動程序棧裝入完畢。此時,USB鼠標就可以正常的工作了。隨后Windows系統利用Win32函數以光標的形式將USB鼠標的位移信息表現出來,這就完成了對USB鼠標的操作。
2 USB光電鼠標映射為虛擬的位置傳感器的開發思路
2.1 USB 鼠標過濾驅動程序的開發思路
本文的目的是利用USB光電鼠標獲得精確的位置信息,但光電鼠標作為操作系統的獨占設備,只允許Windows系統對其訪問,所以需要攔截并改變它的報告描述符使它成為自定義的新設備。HID類驅動程序與USB棧對話會調用小驅動程序,小驅動程序又通過產生內部IOCTL(I/O控制碼)來使能USB類驅動程序,進而可獲得設備的報告描述符。當設備是鼠標時,報告描述符中的usage項的值是2,如果將它改為0,操作系統就不會再將它識別為鼠標,也就不會再有裝入鼠標驅動棧的操作。所此, 本文的工作就是編譯一個下層過濾驅動程序usbfilt.sys來攔截USB鼠標的報告描述符并修改其中usage項的返回值,使系統不會將它識別為鼠標, 這樣用戶態程序就有權利對新定義的設備進行控制和訪問。
2.2 I/O請求包和IRP處理
I/O請求包是Windows系統所使用的與內核模式驅動程序通信的一種數據結構,其中帶有一組I/O管理器例程且可對I/O請求包進行操作。I/O管理器依據請求內容的不同來選擇相應的設備對象和驅動程序對象,同時生成相應的IRP發送到對應的驅動程序中來執行特定的操作,驅動與驅動之間通過IRP進行通信。
IRP是從非分頁內存中定義分配的大小可變的結構,它由IRP首部和可變數目的輔助請求棧單元組成。IRP首部由當前擁有IRP的驅動指針、指向IRP輸入輸出緩沖區的指針等組成。之后是一個IO_STACK_LOCATION結構的棧單元,棧單元中保存著一個I/O請求的參數以及代碼、完成函數指針請求、當前對應的設備指針等。當多個驅動程序處理一個IRP時,就會生成多個IRP棧單元。不同驅動程序需從其所指向的IRP棧單元中讀取到相應的IRP參數。如果需要把IRP沿當前被訪問設備的驅動程序棧繼續傳遞下去,下一個棧單元的參數必須被正確設置。向下傳遞的IRP所對應的參數必須不同于正在處理的IRP。
當一個I/O請求包生成一個對應的IRP時,IRP首部和第一個IRP棧單元將首先被I/O管理器設置。IRP中含有很多問題需要驅動程序進行處理,所以當一個IRP生成時,就會被傳遞到當前訪問設備的驅動程序棧的棧頂,隨即會被從上而下進行相應的處理,如圖2所示。
IRP的處理是從最頂層驅動程序1開始,通過調用函數IoGetCurrentIrpStackLocation來使I/O管理器棧單元指針指向當前棧單元。如果IRP需要繼續向下傳遞到驅動程序2,這時驅動程序2的棧單元需驅動程序1設置它的參數,并通過函數IoCallDriver來被調用,同時新生成的棧單元地址會映射到I/O管理器棧單元的指針, 然后過濾到的符合條件的IRP 將會被驅動程序2 處理,之后以同樣的方式向下傳遞直到所用的驅動程序處理完畢。當IRP包含的問題處理完畢,最后的驅動程序4 通過調用函數IoCompleteRequest 來標識當前IRP為已經完成處理, 隨后沿著設備棧將IRP向上傳遞, 最終到達棧頂彈出,回到用戶。
3 過濾驅動程序的開發
3.1 過濾驅動程序主框架
DriverStudio是NuMega公司提供的驅動程序開發工具。在DriverWorks中提供一個過濾驅動程序的模板例程usbfilt[4]。在這個過濾驅動程序中,直接把IRP傳送下去。本設計重點在于下面這個例程:
NTSTATUS UsbFilterDevice::InternalDeviceControl
(KIrp I)
{
T << "UsbFilterDevice::InternalDeviceControl\n";
if (I.IoctlCode() !=
IOCTL_INTERNAL_USB_SUBMIT_URB)
return DefaultPnp(I);
PURB p = I.Urb(CURRENT);
if(p->UrbHeader.Function!=URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE)
return DefaultPnp(I);
return PassThrough(I,
LinkTo(DeviceControlComplete), this);
}
需要重新定義的IRP會被上面的例程過濾到,并經過下面的完成例程處理,從而構成過濾驅動程序的主框架。
NTSTATUS UsbFilterDevice::DeviceControlComplete(KIrp I)
{
T <<"UsbFilterDevice::DeviceControlComplete\n";
PURB p=I.Urb(CURRENT);
if(p)
{
char* DeseriptorBuffer=
(char*)p->
UrbControlDescriptorRequest.TransferBuffer;
DeseriptorBuffer+=3;
if((*DeseriptorBuffer&0xff)==2)
{
*DeseriptorBuffer=0;
}
}
return I.Status();
}
在這個完成例程中定義了一個指向URB(USB請求塊)緩沖區的指針DeseriptorBuffer,其中保存著設計所需要的報告描述符。在這個數組的第3個字節中保存著usage的值,然后需要對此值進行判斷,如果是“2”就可以判定當前讀取到的設備報告描述符是鼠標的,之后需要將此值改為“0”,這樣就把讀到的報告描述符改成了自定義設備的報告。重啟設備后,當系統再次讀到這個報告時就不會把USB鼠標當成標準設備而被系統獨占了。相反,USB鼠標會作為自定義設備來使用。驅動程序經過DriverStudio在VC++6.0的編譯運行后,生成了設計所需要的過濾驅動程序usbfilt.sys。
3.2 過濾驅動程序的安裝
為了通過VC++6.0將過濾驅動程序準確地安裝到某個設備上,應該通過GUID(全域唯一標識碼)查找指定設備類下的硬件ID來決定是否需要安裝過濾驅動。另外,由于該過濾驅動修改了報告描述符,導致最終的設備由原來的鼠標變成了HID兼容設備。所以需要先將原來的驅動卸載掉,然后才能安裝過濾驅動;否則系統將還使用以前的驅動,也就不會出現新的硬件。安裝過濾驅動的關鍵是以下幾方面:(1)復制過濾驅動文件usbfilt.sys到當前系統的Windows\System32\Drivers目錄下;(2)卸載舊的驅動程序,通過查找所有鼠標設備,查看是否有指定硬件ID的設備,如果有,則卸載它;(3)添加服務,調用OpenSCManager()函數打開SCManager數據庫,然后調用CreatService()函數增加usbfilt服務;(4)更新設備過濾驅動程序名稱列表;(5)重新啟動設備,使主機識別新硬件。
3.3 獲取信息的用戶態應用程序開發
通過安裝過濾驅動把一個標準的Windows系統USB鼠標改造成虛擬位置傳感設備后,Windows系統就失去了對它獨占訪問的權利。利用VC++編寫用戶態應用程序對其進行訪問, 讀出它的位置信息為系統所用。
光電鼠標芯片是一種內部集成有圖像采集系統(IAS)和數字處理器(DSP)的數字圖像處理系統,通過圖像處理實現二維平面的定位。圖像采集系統通過芯片底部的感光眼不斷對物體拍照,然后將圖像信息發送到數字處理器,數字處理器首先提取每張圖像信息中的特征像素,然后對相鄰的兩幅圖像信息中同一特征像素的位置變化進行識別,進而間接計算得到兩幅圖像在拍攝時間間隔內USB鼠標的移動方向和位移大小,并把這些數值量化封裝后,發送到鼠標芯片的固件中,進一步封裝得到固定格式的報告描述符,最終通過USB接口送入計算機。
本文采用的鼠標芯片的輸入報告描述符有5個字節。其中在第1、第2和第3個字節中儲存著X、Y方向的坐標值以及左右鍵的狀態,這3 個字節的具體結構如圖3所示。需要注意的是:一方面在輸入報告描述符中第2和第3字節是移動的相對坐標值,需在后續的程序中通過累加算法把它轉換為鼠標移動的絕對坐標;另一方面,此設備被激勵后使用的是右手坐標系。
要實時獲得位置傳感器的位置信息,需要循環讀取位移信息。為了避免讀操作時發生訪問沖突失去響應,單獨創建一個線程來高速讀取輸入報告。通過調用Windows提供的API函數庫來識別并讀取USB設備的數據,并定義一個緩沖數組存取輸入報告描述符中的坐標值, 最后根據對鼠標設定的分辨率將得到的絕對坐標值轉換為實際的位移大小。
4 實驗結果及分析
將過濾驅動程序usbfilt.sys準確地安裝到目標鼠標上。此時,重新啟動設備,使主機識別新硬件。圖4所示為在VC環境下編譯的簡易上位機,上位機可識別改造好的新設備,并顯示必要的設備信息。
在車架的完整性檢測工程中,超聲探頭和位置傳感器在車架區域同步掃描。通過定義灰度值將超聲回波信號可視化顯示,即可生成一檢測區域內部結構的俯視圖。經實驗檢測,傳感器定位精度可達到0.03 mm,完全滿足本檢測系統對于位置信息的精度要求。
5 結論
本文通過編寫HID類下層過濾驅動程序將USB光電鼠標映射為一個位置傳感器,實現了車架完整性檢測過程中快速、準確定位隱藏焊縫,并進一步結合超聲回波信號,生成對檢測區域內部結構的俯視灰度圖。為公安機關處理走私、盜竊車輛案件的刑事訴訟工作提供了有力證據,同時這種方法充分體現便攜式檢測設備輕便靈活的特點,具有很好實用價值。
參考文獻
[1] 于吉剛,楊錄,張艷花.便攜式隱藏焊縫超聲檢測系統設計[J].儀表技術與傳感器,2015(12):85-87,96.
[2] 武佳慧,楊錄,張艷花.車架VIN碼區域超聲檢測方法研究[J].電子技術應用,2014(8):80-82,86.
[3] 宮閩軍.碳纖維復合材料孔隙率超聲檢測系統定位裝置及可視化研究[D].杭州:浙江大學,2005.
[4] 李凌.碳纖維復合材料數字化超聲檢測系統關鍵技術研究[D].杭州:浙江大學,2007.
作者信息:
王嘉駿1,楊 錄1,韓志毅2,趙 辛2
(1.中北大學 信息與通信工程學院 電子測試技術國家重點實驗室,山西 太原030051;
2.太原市公安局,山西 太原030051)