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