前言:想要寫(xiě)出一篇令人眼前一亮的文章嗎?我們特意為您整理了5篇驅(qū)動(dòng)程序設(shè)計(jì)范文,相信會(huì)為您的寫(xiě)作帶來(lái)幫助,發(fā)現(xiàn)更多的寫(xiě)作思路和靈感。
關(guān)鍵詞:WDF PCI 中斷 驅(qū)動(dòng)程序 同步時(shí)鐘卡
中圖分類號(hào):TP336 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1007-9416(2015)05-0000-00
Abstract:This paper introduces the design of Device Drivers of PCI synchronous clock card based on WDF model. Briefly introduces the system architecture and works on our own PCI synchronous clock card, and Analysis the framework of the WDF model and the design process. Focused on the research and development of the WDF Device Drivers based on the PCI synchronous clock card, including hardware access, Interrupt notification. The driver has passed the test for stability and reliability.
Key words: WDF; PCI; interrupt; driver; synchronous clock card.
時(shí)間是科學(xué)實(shí)驗(yàn)、科學(xué)研究和工程技術(shù)等領(lǐng)域中的一個(gè)基本物理參量。為了保證系統(tǒng)各部分時(shí)間的一致性和正確性,系統(tǒng)內(nèi)各設(shè)備的同步時(shí)鐘從卡從時(shí)鐘源獲取高精度的標(biāo)準(zhǔn)時(shí)間,提供給相應(yīng)設(shè)備。這樣系統(tǒng)內(nèi)各設(shè)備的時(shí)間與時(shí)間源相同而保持一致。同步時(shí)鐘卡一般采用PCI總線方式。PCI總線能夠?qū)崿F(xiàn)設(shè)備間的快速訪問(wèn),它以突出的性能受到計(jì)算機(jī)和通信界工程師們的青睞。
因此如何開(kāi)發(fā)出穩(wěn)定、可靠、高效的PCI設(shè)備驅(qū)動(dòng)程序成為驅(qū)動(dòng)工程師們面臨的一個(gè)棘手的問(wèn)題[5]。過(guò)去對(duì)于PCI設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā)大多采用WDM(Windows Driver Model)框架,但是它編程比較復(fù)雜,快速掌握其開(kāi)發(fā)要領(lǐng)對(duì)于初學(xué)者來(lái)說(shuō)比較困難[5]。本文所述的PCI同步時(shí)鐘卡的驅(qū)動(dòng)程序的開(kāi)發(fā)采用微軟最新推出的WDF(Windows Driver Foundation)驅(qū)動(dòng)模型。WDF驅(qū)動(dòng)模型提供事件驅(qū)動(dòng)和面向?qū)ο蟮尿?qū)動(dòng)程序開(kāi)發(fā)框架,大大降低了設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā)難度[5]。
1 同步時(shí)鐘卡系統(tǒng)架構(gòu)
本文所述的驅(qū)動(dòng)程序是基于自行研發(fā)的PCI同步時(shí)鐘卡,其原理框圖如圖1所示。本同步時(shí)鐘卡選擇PCI9052芯片做為PCI總線的接口芯片。該電路除了用到PCI9052外,還用到了單片機(jī)、EEPROM、雙口RAM、CPLD。單片機(jī)是系統(tǒng)的控制單元;串行EEPROM存儲(chǔ)了PCI9052芯片所需要的配置信息;雙口RAM用于PC機(jī)與時(shí)鐘卡之間交換數(shù)據(jù);CPLD用于200us時(shí)標(biāo)的產(chǎn)生和中斷的控制。
同步時(shí)鐘卡的工作流程如下:同步時(shí)鐘從卡接收時(shí)鐘源輸出的時(shí)間信號(hào),單片機(jī)將其解析成高精度的同步時(shí)間信息,控制邏輯(CPLD)通過(guò)1PPS脈沖信號(hào)產(chǎn)生200us的高精度時(shí)間刻度,于是產(chǎn)生高精度的同步絕對(duì)時(shí)標(biāo),連續(xù)存儲(chǔ)于雙口RAM中,最后計(jì)算機(jī)通過(guò)PCI總線接口獲取高精度的絕對(duì)時(shí)間。本系統(tǒng)中計(jì)算機(jī)獲取雙口RAM中的時(shí)間數(shù)據(jù)的方式有兩種:(1)PC機(jī)主動(dòng)讀取雙口RAM中的數(shù)據(jù)。(2)外部事件通過(guò)中斷通知PC機(jī)事件發(fā)生,PC機(jī)收到通知后讀取雙口RAM中的時(shí)間信息,可獲得外部事件發(fā)生的精確時(shí)刻。兩種方式分別涉及驅(qū)動(dòng)程序的硬件訪問(wèn)和中斷通知。于是涉及到本文介紹的重點(diǎn):基于WDF模型的PCI總線驅(qū)動(dòng)程序的開(kāi)發(fā)。
2 WDF驅(qū)動(dòng)程序設(shè)計(jì)
微軟對(duì)過(guò)去的WDM(Windows Driver Model)驅(qū)動(dòng)程序的架構(gòu)做了改進(jìn),形成了全新的WDF(Windows Driver Foundation)框架結(jié)構(gòu)。它將原來(lái)普通軟件開(kāi)發(fā)中面向?qū)ο蟮募夹g(shù)應(yīng)用到了驅(qū)動(dòng)程序的開(kāi)發(fā)中。WDF改變了驅(qū)動(dòng)程序與操作系統(tǒng)內(nèi)核之間的關(guān)系,在傳統(tǒng)的WDM驅(qū)動(dòng)程序中,不僅要處理硬件,還要處理驅(qū)動(dòng)程序與操作系統(tǒng)內(nèi)核之間的交互[4]。現(xiàn)在WDF則使驅(qū)動(dòng)程序與操作系統(tǒng)內(nèi)核獨(dú)立開(kāi)來(lái),驅(qū)動(dòng)程序與操作系統(tǒng)交互工作將由框架內(nèi)封裝的方法(函數(shù))去完成,這樣驅(qū)動(dòng)開(kāi)發(fā)工程師只需專注處理目標(biāo)硬件的行為即可,避免了兩面不周顧此失彼的弊端。不僅大大降低了驅(qū)動(dòng)程序的代碼量,還使整個(gè)系統(tǒng)更加穩(wěn)定、可靠。
WDF驅(qū)動(dòng)程序包括兩個(gè)類型,一個(gè)是內(nèi)核級(jí)的,稱為KMDF(Kernel-Mode Driver Framework);另一個(gè)是用戶級(jí)的,稱為UMDF(User-Mode Driver Framework)。本文所述的驅(qū)動(dòng)程序采用KMDF模式。
2.1 WDF驅(qū)動(dòng)程序開(kāi)發(fā)流程
本文所用開(kāi)發(fā)環(huán)境為Microsoft Windows Driver Kit(WDK) 8.1和Microsoft Visual Studio 2013,操作系統(tǒng)為Windows7。先安裝VS2013,再安裝WDK8.1,便可在VS2013中直接創(chuàng)建KMDF工程。根據(jù)同步時(shí)鐘卡所需功能編寫(xiě)好驅(qū)動(dòng)程序即可進(jìn)行編譯。
WDF驅(qū)動(dòng)程序框圖如圖2所示。
2.2 基于WDF模型的PCI設(shè)備驅(qū)動(dòng)程序的實(shí)現(xiàn)
WDF模型的設(shè)備驅(qū)動(dòng)程序從功能上可分為三個(gè)部分:初始化設(shè)備、控制設(shè)置與交換數(shù)據(jù)[3]。初始化設(shè)備主要實(shí)現(xiàn)設(shè)備的識(shí)別、驅(qū)動(dòng)對(duì)象與設(shè)備對(duì)象的建立與硬件資源的分配;控制設(shè)置負(fù)責(zé)應(yīng)用程序與驅(qū)動(dòng)程序的連接和設(shè)備的打開(kāi);交換數(shù)據(jù)處理的是設(shè)備功能的具體應(yīng)用,即PCI總線與同步時(shí)鐘卡之間的數(shù)據(jù)傳輸。
從本質(zhì)上來(lái)說(shuō),WDF模型的設(shè)備驅(qū)動(dòng)程序是由入口函數(shù)DriverEntry和事件例程及其子函數(shù)組成的[3]。操作系統(tǒng)在第一次加載驅(qū)動(dòng)程序時(shí)會(huì)通過(guò)調(diào)用DriverEntry例程來(lái)完成設(shè)備驅(qū)動(dòng)程序和框架的初始化[3]。所有的驅(qū)動(dòng)程序都必須包含一個(gè)DriverEntry例程。對(duì)于不同類型的驅(qū)動(dòng)程序其入口函數(shù)DriverEntry也不同,可分為:設(shè)備驅(qū)動(dòng)、純軟件驅(qū)動(dòng)與過(guò)濾驅(qū)動(dòng)。本文所述的PCI總線驅(qū)動(dòng)程序?qū)儆谠O(shè)備驅(qū)動(dòng),在入口函數(shù)DriverEntry中,主要完成兩件事:注冊(cè)EvtDriverDeviceAdd回調(diào)例程、創(chuàng)建和初始化WDFDRIVER對(duì)象。
WDF_DRIVER_CONFIG_INIT(&config,PCIdriverEvtDeviceAdd);
//注冊(cè)EvtDriverDeviceAdd回調(diào)例程
status = WdfDriverCreate(DriverObject, RegistryPath,...);
//創(chuàng)建驅(qū)動(dòng)對(duì)象
2.2.1初始化設(shè)備
在驅(qū)動(dòng)程序被成功初始化完成之后,操作系統(tǒng)會(huì)順序調(diào)用EvtDriverDeviceAdd、EvtDevicePrepareHardware等回調(diào)例程以實(shí)現(xiàn)所控制的設(shè)備的初始化。
當(dāng)首次枚舉設(shè)備時(shí),EvtDriverDeviceAdd例程在系統(tǒng)初始化時(shí)被PnP管理器調(diào)用。在系統(tǒng)運(yùn)行過(guò)程中,任何時(shí)候一個(gè)新的相同設(shè)備被枚舉,系統(tǒng)都將調(diào)用此例程。EvtDriverDeviceAdd例程是設(shè)備初始化過(guò)程中最新被調(diào)用的回調(diào)例程,它需要完成:設(shè)備對(duì)象的創(chuàng)建,創(chuàng)建符號(hào)鏈接或設(shè)備對(duì)象GUID接口,創(chuàng)建一個(gè)或多個(gè)I/O隊(duì)列,各種事件的回調(diào)函數(shù)的注冊(cè),如即插即用、電源管理、I/O處理例程等[1]。
EvtDriverDeviceAdd例程的主要代碼如下所示:
注冊(cè)即插即用基本例程:
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
pnpPowerCallbacks.EvtDevicePrepareHardware = PCIDriverEvtDevicePrepareHardware;
pnpPowerCallbacks.EvtDeviceReleaseHardware = PCIDriverEvtDeviceReleaseHardware;
..........
WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
創(chuàng)建設(shè)備對(duì)象:
WDF_FILEOBJECT_CONFIG_INIT(&f_config,...);
WdfDeviceInitSetFileObjectConfig(DeviceInit, &f_config,WDF_NO_OBJECT_ATTRIBUTES);
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, ..);
status = WdfDeviceCreate(&DeviceInit, &attributes, &control_device);
創(chuàng)建隊(duì)列對(duì)象并注冊(cè)回調(diào)例程:
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,....);
ioQueueConfig.EvtIoDeviceControl = PCIdriverEvtIoDeviceControl;
ioQueueConfig.EvtIoStop = PCIdriverEvtIoStop;
status = WdfIoQueueCreate(control_device,&ioQueueConfig,...);
創(chuàng)建符號(hào)鏈接:
status = WdfDeviceCreateSymbolicLink(control_device, &ustring);
創(chuàng)建中斷對(duì)象:
deviceContext = GetDeviceContext(control_device);
WDF_INTERRUPT_CONFIG_INIT(&interruptConfig,PCIDriverEvtInterruptIsr,
PCIDriverEvtInterruptDpc);//設(shè)置中斷服務(wù)例程和延遲過(guò)程調(diào)用WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&interruptAttributes,..);
status = WdfInterruptCreate(control_device,&interruptConfig,
&interruptAttributes,&deviceContext->Interrupt);
EvtDriverDeviceAdd例程調(diào)用完成之后,系統(tǒng)將調(diào)用EvtDevicePrepareHardware例程初始化地址指針,將設(shè)備所占用的I/O地址和內(nèi)存地址映射為虛擬地址,驅(qū)動(dòng)程序?qū)⑼ㄟ^(guò)這些虛擬地址完成與設(shè)備的數(shù)據(jù)傳輸。由于串行EEPROM存儲(chǔ)了PCI9052芯片所需要的配置信息,系統(tǒng)將自動(dòng)為本文所述的PCI同步時(shí)鐘卡分配資源,它們包括雙口RAM的內(nèi)存地址、PCI9052的I/O地址空間,所以EvtDevicePrepareHardware例程必須將這些資源映射為虛擬地址。對(duì)于I/O端口,只需將首地址與地址數(shù)目值保存在設(shè)備上下文;對(duì)于存儲(chǔ)器芯片,調(diào)用MmMapIoSpace函數(shù)將物理地址映射為系統(tǒng)內(nèi)核虛擬地址,然后保存于設(shè)備上下文。相對(duì)應(yīng)的,當(dāng)設(shè)備被卸載時(shí),系統(tǒng)會(huì)自動(dòng)調(diào)用EvtDeviceReleaseHardware回調(diào)例程釋放之前申請(qǐng)的硬件資源。
for (i = 0; i < WdfCmResourceListGetCount(ResourceListTranslated); i++) {//WdfCmResourceListGetDescriptor函數(shù)獲取該資源的描述符
descri = WdfCmResourceListGetDescriptor(ResourceListTranslated, i);
switch (descri->Type)
{case CmResourceTypeMemory:
Mem_Count++;
if (Mem_Count == 2)//將雙口RAM地址映射為虛擬地址
{pDevice_context->MemBaseAddress = MmMapIoSpace(
descri->u.Memory.Start,
descri->u.Memory.Length,
MmNonCached);
pDevice_context->MemLength = descri->u.Memory.Length;}
break;
case CmResourceTypePort://將PCI9052的I/O地址映射為虛擬地址
pDevice_context->Io_baseAddress = descri->u.Port.Start.LowPart;
pDevice_context->Io_length = descri->u.Port.Length;
default:
break;}}
2.2.2控制設(shè)置與數(shù)據(jù)交換
應(yīng)用程序?qū)崿F(xiàn)和驅(qū)動(dòng)程序通信的過(guò)程是:應(yīng)用程序首先調(diào)用CreateFile函數(shù)打開(kāi)設(shè)備,然后可以使用DeviceIoControl和驅(qū)動(dòng)程序通信,包括寫(xiě)數(shù)據(jù)給驅(qū)動(dòng)程序和從驅(qū)動(dòng)程序讀數(shù)據(jù)兩種情況,也可以用WriteFile寫(xiě)數(shù)據(jù)給驅(qū)動(dòng)程序或用ReadFile從驅(qū)動(dòng)程序讀數(shù)據(jù),當(dāng)應(yīng)用程序退出時(shí),調(diào)用用CloseHandle關(guān)閉設(shè)備。本文所述的系統(tǒng)是用DeviceIoControl和驅(qū)動(dòng)程序通信。CreateFile打開(kāi)設(shè)備的方式有兩種:符號(hào)鏈接名與GUID接口,本文所述驅(qū)動(dòng)程序采用的是符號(hào)鏈接名的方式。
m_hDevice=CreateFile(sLinkName,...);//以符號(hào)鏈接名的方式打開(kāi)設(shè)備
上述代碼中sLinkName為符號(hào)鏈接名,它與驅(qū)動(dòng)程序中設(shè)置的符號(hào)鏈接名相同。m_hDevice為返回的設(shè)備的有效句柄,應(yīng)用程序就可以應(yīng)用它調(diào)用DeviceIoControl函數(shù)與驅(qū)動(dòng)程序交換數(shù)據(jù)。應(yīng)用程序的請(qǐng)求會(huì)被放入請(qǐng)求隊(duì)列中,并在EvtIoDeviceControl函數(shù)之中被處理。
本文中應(yīng)用程序獲取時(shí)鐘卡上的時(shí)間信息的方式有兩種:(1)直接讀取。(2)中斷方式。
對(duì)于第一種方式,應(yīng)用程序直接調(diào)用DeviceIoControl函數(shù)與驅(qū)動(dòng)程序交換數(shù)據(jù)。由于系統(tǒng)的雙口RAM被映射到虛擬內(nèi)存,驅(qū)動(dòng)程序可以使用下面兩條指令對(duì)雙口RAM進(jìn)行讀寫(xiě): READ_REGISTER_XXX;//讀雙口RAM,WRITE_REGISTER_XXX;//寫(xiě)雙口RAM。
對(duì)于中斷方式,當(dāng)被捕獲的外部事件發(fā)生時(shí),驅(qū)動(dòng)程序會(huì)進(jìn)入中斷服務(wù)例程EvtInterruptIsr,然后進(jìn)入延時(shí)過(guò)程調(diào)用EvtInterruptDpc,首先清中斷源,然后將雙口RAM中的時(shí)間數(shù)據(jù)讀取到設(shè)備上下文中緩存,該數(shù)據(jù)即為外部事件發(fā)生的時(shí)間,最后通知應(yīng)用程序讀取該數(shù)據(jù)。應(yīng)用程序?qū)⒄{(diào)用DeviceIoControl函數(shù)獲取設(shè)備上下文中的時(shí)間信息。驅(qū)動(dòng)程序與應(yīng)用程序通信的方法有兩種:DeviceIoControl異步完成和WIN32事件通知。本文所述系統(tǒng)采用WIN32事件通知的方法。對(duì)于此種方法,應(yīng)用程序初始化時(shí)首先生成一個(gè)通知事件,并通過(guò)DeviceIoControl函數(shù)的輸入緩沖區(qū)發(fā)送給驅(qū)動(dòng)程序,驅(qū)動(dòng)程序創(chuàng)建相應(yīng)的內(nèi)核事件,同時(shí)使能PCI9052的LINT1中斷,當(dāng)該事件發(fā)生時(shí),驅(qū)動(dòng)程序會(huì)通知應(yīng)用程序,應(yīng)用程序的一個(gè)子線程不停的循環(huán)等待驅(qū)動(dòng)程序發(fā)來(lái)的事件發(fā)生通知。當(dāng)設(shè)備被卸載時(shí)需要撤銷該內(nèi)核事件。具體主要代碼如下:
應(yīng)用程序生成通知事件:
mhEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
應(yīng)用程序子線程中等待事件發(fā)生:
while (WaitForSingleObject(mhEvent, 0) != WAIT_OBJECT_0)
{...}
驅(qū)動(dòng)程序創(chuàng)建相應(yīng)的內(nèi)核事件:
ObReferenceObjectByHandle(....);
允許PCI中斷,使能PCI9052的本地LINT1中斷,pREG為PCI9052映射的I/O空間的基 地址:
inter = READ_PORT_USHORT(pREG + 0x4c);
inter |=0x43;
WRITE_PORT_USHORT(pREG + 0x4c, inter);
清中斷源,設(shè)置PCI9052的CS3引腳有效,通知CPLD清掉LINT1信號(hào):
inter = READ_PORT_USHORT(pREG + 0x50);
inter |= 0x800;
WRITE_PORT_USHORT(pREG + 0x50, inter);
驅(qū)動(dòng)程序給應(yīng)用程序發(fā)送事件,通知應(yīng)用程序讀取數(shù)據(jù):
KeSetEvent(pDevice_context->Event, 0, FALSE);
驅(qū)動(dòng)程序內(nèi)撤銷內(nèi)核事件:
ObDereferenceObject(...);
3 結(jié)語(yǔ)
驅(qū)動(dòng)程序是硬件與應(yīng)用程序通信的橋梁,它對(duì)系統(tǒng)性能提升的作用舉足輕重。高效、穩(wěn)定、可靠的驅(qū)動(dòng)程序可以使系統(tǒng)性能得到很好的提升。
本文簡(jiǎn)要介紹了PCI同步時(shí)鐘從卡的工作原理,并重點(diǎn)討論了基于WDF模型的PCI設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)方法。本文所述的PCI同步時(shí)鐘卡驅(qū)動(dòng)程序,在WDK8.1中成功編譯,自動(dòng)生成SYS文件(驅(qū)動(dòng)程序代碼)和INF文件(設(shè)備安裝信息),成功安裝并且能夠穩(wěn)定可靠地運(yùn)行。經(jīng)測(cè)試,捕獲的時(shí)間精度達(dá)到誤差小于200us,滿足系統(tǒng)設(shè)計(jì)要求。涉及本驅(qū)動(dòng)程序的系統(tǒng)已應(yīng)用于三峽大壩左岸發(fā)電廠發(fā)變機(jī)組的故障錄波系統(tǒng)中,運(yùn)行穩(wěn)定可靠。總而言之,WDF驅(qū)動(dòng)模型優(yōu)化并簡(jiǎn)化了設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā),比傳統(tǒng)的WDM驅(qū)動(dòng)模型更加穩(wěn)定。
參考文獻(xiàn)
[1]武安河.Windows設(shè)備驅(qū)動(dòng)程序WDF開(kāi)發(fā)[M].北京:電子工業(yè)出版社,2009.
[2][美]Ronald D. Reeves 著,張猛等 譯.Windows設(shè)備驅(qū)動(dòng)程序開(kāi)發(fā)[M].北京:人民郵電出版社,2012.
[3]黎順杰,張艷榮.基于WDF的PCI-CAN設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)[J].電子測(cè)試,2013;5:20-21.
【關(guān)鍵詞】USB 設(shè)備驅(qū)動(dòng) Linux
1 USB總線原理
USB 協(xié)議是1994年底由康柏、IBM、英特爾等幾家公司聯(lián)合提出來(lái)的外部總線接口協(xié)議。USB就是英文中Universal Serial Bus(通用串行總線)的縮寫(xiě)。USB總線具有其他總線所不具備的如:熱插拔、數(shù)據(jù)傳輸可靠、擴(kuò)展方便、成本低等一系列特點(diǎn),因此在嵌入式系統(tǒng)中被廣泛使用。
一個(gè)USB系統(tǒng)一般是由一個(gè)USB主機(jī)控制器、一個(gè)或多個(gè)USB集線器和一個(gè)或多個(gè)USB設(shè)備節(jié)點(diǎn)組成。USB系統(tǒng)的物理連接具有層次性。USB總線連接USB設(shè)備和USB主機(jī),是一種星型拓?fù)浣Y(jié)構(gòu)。USB的拓?fù)浣Y(jié)構(gòu)如圖1所示。
在一個(gè)USB系統(tǒng)傳輸數(shù)據(jù)的過(guò)程中有兩個(gè)非常重要的概念,就是USB傳輸模式和USB描述符。USB傳輸模式是指USB設(shè)備傳輸數(shù)據(jù)的形式。USB設(shè)備支持四種傳輸模式:控制傳輸模式、同步傳輸模式、中斷傳輸模式和批量傳輸模式。控制傳輸模式是用來(lái)處理USB主端口到USB從端口的數(shù)據(jù)傳輸,主要是設(shè)備控制指令、設(shè)備查詢狀態(tài)指令和確認(rèn)指令。同步傳輸模式是指?jìng)鬏敽蜁r(shí)間關(guān)系密切的信息所使用的一種傳輸方式,是一種周期的、連續(xù)的單向傳輸方式。中斷傳輸模式這類傳輸模式主要用于傳輸非周期性的、自然發(fā)生的、數(shù)據(jù)量很小的信息,這類數(shù)據(jù)傳輸?shù)姆较蚴菑脑O(shè)備到主機(jī),適用于鍵盤(pán)、鼠標(biāo)、操縱桿等設(shè)備上。最后一種是批量傳輸模式,該模式適用于大量的、對(duì)時(shí)間沒(méi)有要求的數(shù)據(jù)傳輸,如U盤(pán)或者移動(dòng)硬盤(pán)等設(shè)備。
USB設(shè)備在邏輯上分為幾個(gè)層次,分別是設(shè)備層(Device)、配置層(Config)、接口層(Interface)、端點(diǎn)層(Endpoint)。各個(gè)層次都有與之相對(duì)的描述符,分別是設(shè)備描述符、配置描述符、接口描述符和端點(diǎn)描述符。
2 Linux下的USB驅(qū)動(dòng)框架
USB設(shè)備的設(shè)備描述符在Linux系統(tǒng)中用usb_device_descriptor結(jié)構(gòu)體表示,它描述了USB設(shè)備的一般信息。配置描述符用usb_config_descriptor結(jié)構(gòu)體表示,它給出了USB設(shè)備的配置信息。接口驅(qū)動(dòng)程序是在一個(gè)配置內(nèi)給出一個(gè)接口信息,它在Linux中由usb_interface_descriptor結(jié)構(gòu)體表示。端口描述符被主機(jī)用來(lái)決定每個(gè)端口的帶寬需求,它在Linux系統(tǒng)中由usb_endpoint_descriptor結(jié)構(gòu)體表示。
編寫(xiě)一個(gè)USB驅(qū)動(dòng)程序,是從usb_driver結(jié)構(gòu)體開(kāi)始的。Linux中模塊加載函數(shù)調(diào)用usb_register()和usb_unregister()從而對(duì)usb_driver結(jié)構(gòu)體進(jìn)行加載與卸載。如果某個(gè)設(shè)備信息與該驅(qū)動(dòng)中usb_device_id usb_mouse_id_table 結(jié)構(gòu)體的信息相一致,則會(huì)調(diào)用usb_driver中探測(cè)成員函數(shù)probe(),將初始化USB斷點(diǎn)信息,并對(duì)設(shè)備做一些初始化工作,分配urb結(jié)構(gòu)體,準(zhǔn)備數(shù)據(jù)傳輸。其urb處理大致框架結(jié)構(gòu)如圖2所示。
當(dāng)鼠標(biāo)設(shè)備在用戶空間打開(kāi)時(shí),將提交 probe 函數(shù)構(gòu)建的 urb 請(qǐng)求塊,urb 將開(kāi)始為傳送數(shù)據(jù)而忙碌了。urb 請(qǐng)求塊就像一個(gè)裝東西的“袋子”,USB 驅(qū)動(dòng)程序把“空袋子”提交給 USB core,然后再交給主控制器,主控制器把數(shù)據(jù)放入這個(gè)“袋子”后再將裝滿數(shù)據(jù)的“袋子”通過(guò) USB core 交還給 USB 驅(qū)動(dòng)程序,這樣一次數(shù)據(jù)傳輸就完成了。
3 結(jié)束語(yǔ)
由于USB簡(jiǎn)單方便快捷等優(yōu)點(diǎn),許多外接設(shè)備會(huì)越來(lái)越青睞USB接口,這是一種發(fā)展的趨勢(shì)。Linux系統(tǒng)具有開(kāi)源、安全等特性,用戶也在急劇增加。屆時(shí),會(huì)有越來(lái)越多的USB驅(qū)動(dòng)加入Linux內(nèi)核之中。
參考文獻(xiàn)
[1]Jonathan Corbet,Alessandro Rubini,Greg Kroah-Hartman等.LINUX設(shè)備驅(qū)動(dòng)程序[M].北京:中國(guó)電力出版社,2006.
[2]Universal Serial Bus Specification Compaq,Intel,Mi―crosoft,NEC Revision 1.1.September 23,1998.
[3]溫卡特斯瓦蘭.精通Linux驅(qū)動(dòng)程序開(kāi)發(fā)[M].北京:人民郵電出版,2009.
[4]胡曉軍,張愛(ài)成.USB接口卡發(fā)技術(shù)[M].西安:西安電子科技大學(xué)出社,2005:15-17.
作者簡(jiǎn)介
徐海林(1989-),男,江蘇省南通市人。現(xiàn)為安徽理工大學(xué)計(jì)算機(jī)科學(xué)與工程學(xué)院學(xué)生。
第一節(jié)windows nt網(wǎng)絡(luò)結(jié)構(gòu)
§1.1.1 windows nt網(wǎng)絡(luò)體系結(jié)構(gòu)
windows nt的網(wǎng)絡(luò)體系結(jié)構(gòu)是基于國(guó)際標(biāo)準(zhǔn)化(iso)制定的標(biāo)準(zhǔn)模型──開(kāi)放式系統(tǒng)互連(open system interconnection:osi)參考模型分層建立的,這種方式有利于隨時(shí)擴(kuò)展其它功能和服務(wù)。
windows nt網(wǎng)絡(luò)模型開(kāi)始于mac子層,網(wǎng)卡驅(qū)動(dòng)程序就駐留在其中。它通過(guò)相關(guān)的網(wǎng)卡把windows nt與網(wǎng)絡(luò)連接起來(lái),圖中的多個(gè)網(wǎng)卡表明在一臺(tái)運(yùn)行windows nt的計(jì)算機(jī)上能使用多種網(wǎng)卡。
這一網(wǎng)絡(luò)體系結(jié)構(gòu)包括兩個(gè)重要接口──ndis接口與傳輸驅(qū)動(dòng)
程序接口(tdi)。這兩個(gè)接口把兩個(gè)層隔離開(kāi)來(lái),辦法是相鄰的部件只允許按單一的標(biāo)準(zhǔn)來(lái)寫(xiě),不允許多重標(biāo)準(zhǔn)。例如一個(gè)網(wǎng)卡驅(qū)動(dòng)程序(在ndis接口的下面)就不需要特地按每個(gè)傳輸協(xié)議來(lái)寫(xiě)它的代碼塊,恰恰相反,該驅(qū)動(dòng)程序是寫(xiě)給ndis接口的,它通過(guò)符合ndis的相應(yīng)傳輸協(xié)議來(lái)請(qǐng)求服務(wù)。這些接口包含在windows nt的網(wǎng)絡(luò)體系結(jié)構(gòu)中,以容納可移植、可互換的模塊。
在兩個(gè)接口之間,是傳輸協(xié)議。它在網(wǎng)絡(luò)中起著組織者的作用。一個(gè)傳輸協(xié)議規(guī)定了數(shù)據(jù)以何種方式呈遞給下一個(gè)接收層,以及如何對(duì)數(shù)據(jù)相應(yīng)地進(jìn)行打包。它通過(guò)ndis把數(shù)據(jù)傳給網(wǎng)卡驅(qū)動(dòng)程序,并通過(guò)tdi把數(shù)據(jù)傳給轉(zhuǎn)發(fā)程序(redirector)
tdi之上是轉(zhuǎn)發(fā)程序,它把本地的網(wǎng)絡(luò)資源申請(qǐng)轉(zhuǎn)送給網(wǎng)絡(luò)。
為了能和其他廠商的網(wǎng)絡(luò)互連,windows nt允許有多個(gè)轉(zhuǎn)發(fā)程序。對(duì)于每一個(gè)轉(zhuǎn)發(fā)程序windows nt計(jì)算機(jī)必須也有一個(gè)相應(yīng)的供應(yīng)者(provider)(由網(wǎng)絡(luò)廠商提供)。多供應(yīng)者路由選擇程序決定適當(dāng)?shù)墓?yīng)者,然后借助于供應(yīng)者,對(duì)應(yīng)用請(qǐng)求到相應(yīng)的轉(zhuǎn)發(fā)程序做出選擇。windows nt支持兩種類型的網(wǎng)絡(luò)驅(qū)動(dòng)程序
傳輸驅(qū)動(dòng)程序
實(shí)現(xiàn)數(shù)據(jù)鏈路層中的邏輯鏈路控制子層協(xié)議和傳輸層協(xié)議。向 下與ndis接口,向上與tdi接口。
網(wǎng)卡驅(qū)動(dòng)程序
實(shí)現(xiàn)對(duì)物理層的管理和數(shù)據(jù)鏈路層中介質(zhì)訪問(wèn)控制子層協(xié)議,通過(guò)ndis向下管理物理網(wǎng)卡,向上與傳輸驅(qū)動(dòng)程序通信。
§1.1.3 windows nt網(wǎng)卡驅(qū)動(dòng)程序
windows nt環(huán)境下的網(wǎng)卡驅(qū)動(dòng)程序也分為兩種:
miniport網(wǎng)卡驅(qū)動(dòng)程序:miniport驅(qū)動(dòng)程序只須實(shí)現(xiàn)與網(wǎng)絡(luò)硬件相關(guān)的操作(包括發(fā)送和接收)。而所有底層網(wǎng)卡驅(qū)動(dòng)程序的通用操作(如同步),一般由ndis接口程序來(lái)實(shí)現(xiàn)。
full網(wǎng)卡驅(qū)動(dòng)程序:full網(wǎng)卡驅(qū)動(dòng)程序必須實(shí)現(xiàn)所有硬件相關(guān)和同步、排隊(duì)等操作。例如full網(wǎng)卡驅(qū)動(dòng)程序?yàn)榱隧憫?yīng)數(shù)據(jù)接收,需要保持本身的捆綁信息,而miniport就可以由ndis接口庫(kù)來(lái)實(shí)現(xiàn)。
在windows nt的早期版本中,full網(wǎng)卡驅(qū)動(dòng)程序要求開(kāi)發(fā)者實(shí)現(xiàn)許多底層操作,來(lái)處理多處理器的核心問(wèn)題以及處理器、線程的同步,這樣不同的開(kāi)發(fā)者在大量重復(fù)著許多相同的工作。
而miniport網(wǎng)卡驅(qū)動(dòng)程序允許開(kāi)發(fā)者僅僅寫(xiě)一些與網(wǎng)絡(luò)硬件相關(guān)的代碼即可,而那些通用的函數(shù)由ndis接口庫(kù)來(lái)實(shí)現(xiàn),這樣開(kāi)發(fā)出來(lái)的驅(qū)動(dòng)程序減少了不必要的工作。
第二節(jié)miniport驅(qū)動(dòng)程序的結(jié)構(gòu)
ndis接口規(guī)范了網(wǎng)卡驅(qū)動(dòng)程序的實(shí)現(xiàn),同時(shí)也對(duì)tdi驅(qū)動(dòng)程序的實(shí)現(xiàn)提出了一定的要求,在nt中,ndis約束下的網(wǎng)卡驅(qū)動(dòng)程序、tdi驅(qū)動(dòng)程序和系統(tǒng)的關(guān)系如下圖所示:
圖2.0 ndis約束下的網(wǎng)卡驅(qū)動(dòng)程序、tdi驅(qū)動(dòng)程序和系統(tǒng)的關(guān)系
miniport驅(qū)動(dòng)程序包括驅(qū)動(dòng)程序?qū)ο蟆Ⅱ?qū)動(dòng)程序源代碼和ndis接口庫(kù)代碼。windows nt ddk提供ndis.h作為miniport驅(qū)動(dòng)程序的主要頭文件,定義了miniport驅(qū)動(dòng)程序的入口點(diǎn)、ndis接口庫(kù)函數(shù)和通用數(shù)據(jù)結(jié)構(gòu)。
上邊緣函數(shù)的作用是網(wǎng)卡驅(qū)動(dòng)與ndis接口庫(kù)進(jìn)行通信,而下邊緣函數(shù)是tdi協(xié)議驅(qū)動(dòng)程序與ndis通信的手段。ndis用一個(gè)叫做邏輯網(wǎng)卡的軟件對(duì)象來(lái)描述系統(tǒng)中的每塊網(wǎng)卡,而邏輯網(wǎng)卡與windows nt設(shè)備對(duì)象的通信由i/o子系統(tǒng)來(lái)管理,描述網(wǎng)卡的設(shè)備對(duì)象包括相關(guān)的網(wǎng)絡(luò)信息如名字、網(wǎng)絡(luò)地址和網(wǎng)卡內(nèi)存基地址等,它還包含與硬件相關(guān)的驅(qū)動(dòng)程序狀態(tài)數(shù)據(jù)(捆綁數(shù)目,捆綁句柄,包過(guò)濾數(shù)據(jù)庫(kù)等)。ndis分配一個(gè)句柄到miniportinitialize這個(gè)上邊緣函數(shù)的一個(gè)結(jié)構(gòu)中,然后miniport網(wǎng)卡驅(qū)動(dòng)程序?qū)⒃谝院筇峁┻@個(gè)句柄來(lái)給ndis調(diào)用,這個(gè)結(jié)構(gòu)一直被ndis保持,并且對(duì)miniport驅(qū)動(dòng)程序不透明。 當(dāng)miniport網(wǎng)卡驅(qū)動(dòng)程序初始化一塊網(wǎng)卡時(shí),它創(chuàng)立自己的內(nèi)部數(shù)據(jù)結(jié)構(gòu)來(lái)描述網(wǎng)卡,記錄需要它管理的與設(shè)備相關(guān)的狀態(tài)信息。當(dāng)miniport網(wǎng)卡驅(qū)動(dòng)程序調(diào)用ndismsetatttibutes或ndismsetattributesex兩ndis庫(kù)函數(shù)時(shí),它傳遞一個(gè)句柄給這數(shù)據(jù)結(jié)構(gòu)。這樣,當(dāng)調(diào)用miniport驅(qū)動(dòng)程序入口點(diǎn)時(shí),它就傳遞這個(gè)句柄來(lái)驗(yàn)證驅(qū)動(dòng)程序所對(duì)應(yīng)的網(wǎng)卡的正確性。這個(gè)數(shù)據(jù)結(jié)構(gòu)為miniport網(wǎng)卡驅(qū)動(dòng)程序所擁有并維護(hù)。miniport nic驅(qū)動(dòng)程序還需要維護(hù)一組對(duì)象,這些對(duì)象是系統(tǒng)定義的對(duì)象標(biāo)識(shí)符(object idetifier:oid)來(lái)標(biāo)識(shí),以描述驅(qū)動(dòng)程序的性能和當(dāng)前狀態(tài)信息。為查詢這些信息,上層驅(qū)動(dòng)程序調(diào)用ndisrequest向ndis接口庫(kù)指示oid。oid表示了調(diào)用所需的信息類型,如miniport驅(qū)動(dòng)程序所支持的lookahead緩沖區(qū)大小等。ndis接到上層驅(qū)動(dòng)程序的查詢請(qǐng)求,將oid傳遞給上邊緣函數(shù)miniportqueryinformation實(shí)現(xiàn)對(duì)oid的查詢,如果上層驅(qū)動(dòng)程序請(qǐng)求改變狀態(tài)信息則調(diào)用miniportsetinformation實(shí)現(xiàn)對(duì)oid的設(shè)置。典型的miniport nic驅(qū)動(dòng)程序必須有一些函數(shù)來(lái)通過(guò)ndis接口實(shí)現(xiàn)上層驅(qū)動(dòng)程序與硬件的通信。這些函數(shù)稱為上邊緣服務(wù)函數(shù)。
這些上邊緣服務(wù)函數(shù)由驅(qū)動(dòng)程序的開(kāi)發(fā)者根據(jù)驅(qū)動(dòng)程序面向的特定低層網(wǎng)絡(luò)類型和硬件以及相應(yīng)環(huán)境,可以有選擇地實(shí)現(xiàn),但必須保證驅(qū)動(dòng)程序最基本的功能,這些基本功能包括初始化、發(fā)送、中斷處理、重置、參數(shù)查詢與設(shè)置和報(bào)文接收。
miniportinitialize:操作系統(tǒng)根據(jù)系統(tǒng)配置信息,檢測(cè)出網(wǎng)卡已安裝時(shí),由ndis接口在初始化時(shí)調(diào)用,主要完成低層網(wǎng)絡(luò)類型確定,對(duì)應(yīng)于物理網(wǎng)卡的邏輯網(wǎng)卡初始化,中斷信息注冊(cè),網(wǎng)卡與主機(jī)通訊方式的確認(rèn)。i/o端口的申請(qǐng)與注冊(cè),內(nèi)存映像,mib的初始化,物理網(wǎng)卡的驗(yàn)證與初始化等。
miniportreconfigure:支持網(wǎng)卡參數(shù)動(dòng)態(tài)變化,和miniportinitilize一樣由ndis接口以初始化級(jí)別調(diào)度執(zhí)行(不能屏蔽中斷,必須由驅(qū)動(dòng)程序承認(rèn)并清除在此期間產(chǎn)生的中斷),支持即插即用和軟配置的網(wǎng)卡在動(dòng)態(tài)改變參數(shù)時(shí),必須提供此函數(shù)。
miniportqueryinformation:查詢網(wǎng)卡的狀態(tài)以及網(wǎng)卡驅(qū)動(dòng)程序的操作或統(tǒng)計(jì)參數(shù),如是否支持組通訊、網(wǎng)卡的物理速率是否支持回環(huán)、是否支持直接拷貝等,這些參數(shù)以oid方式統(tǒng)一管理。
miniportsetinformation:ndis接口或協(xié)議驅(qū)動(dòng)程序通過(guò)調(diào)用此接口改變驅(qū)動(dòng)程序維護(hù)的oid庫(kù),一些操作參數(shù)的改變也將同時(shí)改變驅(qū)動(dòng)程序狀態(tài),例如組地址的設(shè)置。
miniportreset:包括網(wǎng)卡硬件重置和驅(qū)動(dòng)程序軟件重置,軟件重置包括驅(qū)動(dòng)程序狀態(tài)重置,以及一些相關(guān)的參數(shù)重置,還需考慮有些參數(shù)的恢復(fù),重置時(shí)不必完成所有正在活躍的外部請(qǐng)求,但必須釋放已占用的外部資源。
miniporthalt:掛起網(wǎng)卡并釋放該網(wǎng)卡驅(qū)動(dòng)程序占用的所有資源,在此期間不屏蔽中斷。
miniportisr:高優(yōu)先級(jí)的中斷處理程序,進(jìn)行的工作包括初始中斷處理類型,決定是否進(jìn)行中斷轉(zhuǎn)交,對(duì)卡上中斷進(jìn)行處理 等,該服務(wù)類型只在以下情況被調(diào)用:
ndis接口調(diào)用miniportinitialize和miniporthalt兩函數(shù)時(shí)。
.中斷處理類型設(shè)為每此中斷處理過(guò)程都調(diào)用時(shí)。
為使系統(tǒng)能及時(shí)響應(yīng)所有硬件中斷,高優(yōu)先級(jí)的硬件中斷處理程序應(yīng)盡可能的減少運(yùn)行時(shí)間,防止長(zhǎng)時(shí)間的屏蔽低優(yōu)先級(jí)中斷,避免造程中斷丟失。
miniporthandleinterrupt:由中斷延時(shí)處理程序在中斷延時(shí)處理時(shí)進(jìn)行調(diào)用。ndis排隊(duì)所有的延時(shí)處理,該服務(wù)主要處理發(fā)送完成、報(bào)文接收、描述符用盡、溢出、網(wǎng)卡異常等中斷。
miniportsend:ndis收到上層發(fā)送請(qǐng)求時(shí)經(jīng)過(guò)若干協(xié)議處理再向下調(diào)用此服務(wù)過(guò)程,發(fā)送的packet已含有l(wèi)lc和mac頭,該服務(wù)過(guò)程進(jìn)行邊界對(duì)齊、packet約束重整、描述符映射和報(bào)文發(fā)送、以及發(fā)送資源和packet緩沖隊(duì)列管理。
miniporttransferdata:多個(gè)已和網(wǎng)卡捆綁的協(xié)議驅(qū)動(dòng)程序在接收到報(bào)文到達(dá)指示后,向網(wǎng)卡驅(qū)動(dòng)程序發(fā)出傳送請(qǐng)求以拷貝各自所需的報(bào)文數(shù)據(jù)部分,網(wǎng)卡驅(qū)動(dòng)程序根據(jù)各協(xié)議驅(qū)動(dòng)程序?qū)蝹€(gè)packet是否進(jìn)行多次拷貝,以決定是否暫存只允許單次拷貝的packet等。
miniportcheckhandle:ndis每秒調(diào)用此服務(wù)函數(shù)一次,驅(qū)動(dòng)程序發(fā)現(xiàn)網(wǎng)卡異常時(shí)報(bào)告給ndis由ndis調(diào)用miniportreset進(jìn)行硬件重恢復(fù)。
miniportenableintrrupt:中斷使能。
miniportdisableinterrupt:中斷屏蔽。
另外,每個(gè)網(wǎng)卡驅(qū)動(dòng)程序必須有一個(gè)初始化入口點(diǎn),由driver entry函數(shù)實(shí)現(xiàn),它和系統(tǒng)相關(guān),由操作系統(tǒng)在裝入驅(qū)動(dòng)程序時(shí)調(diào)用,主要完成初始化ndis wrapper,再由wrapper初始生成驅(qū)動(dòng)程序管理塊并完成相應(yīng)各種初始化工作,登錄網(wǎng)卡驅(qū)動(dòng)程序所有上邊緣服務(wù)入口點(diǎn),同時(shí)寫(xiě)入ndis版本信息。ndis接口庫(kù)包括在ndis.sys中,它是一個(gè)核態(tài)函數(shù)庫(kù),有一套抽象的函數(shù),無(wú)論協(xié)議驅(qū)動(dòng)程序還是nic驅(qū)動(dòng)程序都連接到這個(gè)庫(kù)中,以實(shí)現(xiàn)上下層之間的操作。
第二章fddi網(wǎng)卡驅(qū)動(dòng)程序的加載和運(yùn)行
第一節(jié) 網(wǎng)卡驅(qū)動(dòng)程序的安裝
windows nt網(wǎng)卡驅(qū)動(dòng)程序安裝的目的是實(shí)現(xiàn)網(wǎng)卡相應(yīng)硬件信息和驅(qū)動(dòng)程序在windows nt注冊(cè)庫(kù)中的注冊(cè),使windows nt能夠正確識(shí)別網(wǎng)卡,了解所必需的軟硬件信息并能在windows nt啟動(dòng)時(shí)加載相應(yīng)驅(qū)動(dòng)程序。
網(wǎng)卡驅(qū)動(dòng)程序安裝時(shí),首先在主群組的控制面板中選擇“網(wǎng)絡(luò)”,然后添加網(wǎng)卡,指定相應(yīng)信息文件──oemsetup.inf的路徑,以完成以下兩個(gè)必要的操作:
復(fù)制驅(qū)動(dòng)程序到相應(yīng)的系統(tǒng)目錄(windows nt根目錄system32drivers)中;
在windows nt注冊(cè)庫(kù)中存入相應(yīng)軟硬件信息。
下面主要以fddi網(wǎng)卡為例介紹安裝驅(qū)動(dòng)程序所必需的工作:
§2.1.1網(wǎng)卡一般硬件參數(shù)
對(duì)于fddi網(wǎng)卡,必須在編寫(xiě)其oemsetup.inf文件時(shí)確定以下硬件參數(shù):
總線類型:pci(5)……括號(hào)中的數(shù)字5表示pci總線在ndis中的總線類型代碼;
廠商代號(hào):0x5588……系統(tǒng)加載時(shí)確定網(wǎng)卡的標(biāo)記,也是編程時(shí)確定pci槽號(hào)的標(biāo)識(shí);
cfid: 0x01;
介質(zhì)類型:光纖(3) ……括號(hào)中的數(shù)字表示光纖在ndis中的介質(zhì)類型代碼;
是否支持全雙工:支持。
對(duì)于其它的硬件信息在此inf配置信息文件中可有可無(wú),如若配置,則可在驅(qū)動(dòng)程序的編寫(xiě)時(shí)利用這些信息,方便編程,同時(shí)有利于其它應(yīng)用對(duì)其參數(shù)的確定和使用。網(wǎng)卡驅(qū)動(dòng)程序的安裝通常將創(chuàng)建登錄表中的四個(gè)不同子鍵:
software registrion鍵,對(duì)應(yīng)于驅(qū)動(dòng)程序,存在于hkey_local_machinesoftwarecompany productnameversion中。我們的fddi網(wǎng)卡驅(qū)動(dòng)程序所對(duì)應(yīng)的是hkey_local_machinesoftwarenet612yhfddiyhfddi1.0;
網(wǎng)卡的軟件登錄鍵,存在于hkey_local_machinesoftwaremicrosoft windows ntnt3.51networkcardsyhfddi1;
驅(qū)動(dòng)程序的服務(wù)登錄鍵,存在于hkey_local_machinesystemcurrentcontrolsetservices
網(wǎng)卡的服務(wù)登錄鍵,存在于hkey_local_machinesystemcurrentcontrolsetservices
對(duì)于每一個(gè)網(wǎng)絡(luò)部件,一個(gè)名為netrules的特殊子鍵在鄰近的驅(qū)動(dòng)程序或網(wǎng)卡登錄子鍵里創(chuàng)建,netrules標(biāo)識(shí)網(wǎng)絡(luò)部件為網(wǎng)絡(luò)整體的一部分。
fddi網(wǎng)卡驅(qū)動(dòng)程序?qū)?yīng)的標(biāo)準(zhǔn)軟件登錄表項(xiàng)將出現(xiàn)在以下路徑:
hkey_local_machinesoftwarenet612yhfddiyhfddi1.0;
驅(qū)動(dòng)程序?qū)?yīng)的標(biāo)準(zhǔn)項(xiàng)的值為:
description =yhfddi/pci adapter controller
install date =……
……
refcount =0x01
servicename =yhfddi
softwaretype =driver
title =yhfddi/pci adapter controller
而且在yhfddi驅(qū)動(dòng)程序相關(guān)的netrules子鍵下,這些值項(xiàng)為:
bindable =yhfddi driver yhfddi adapter non exclusiver
bindform =“yhfddisys”yes no container
class = reg_multi_sz “yhfddi driver basic”
infname =oemnad1.inf
type =yhfddisys ndisdriver yhfddidriver
use =driver
yhfddi網(wǎng)卡在如下路徑的networkcards子鍵里介紹:
hkey_local_machinesoftwaremicrosoft
windows ntnt3.51networkcardsyhfddi1;
網(wǎng)卡的標(biāo)準(zhǔn)項(xiàng)包括以下這些值:
description =yhfddi/pci adapter controller
install date =……
manufacturer =net612
productname =yhfddi
servicename =yhfddi01
title =[01]yhfddi/pci adapter controller
§2.1.3編寫(xiě)inf信息配置文件
gui inf描述語(yǔ)言被windows nt用以書(shū)寫(xiě)系統(tǒng)所有部件的配置文件,當(dāng)然也可以用以書(shū)寫(xiě)網(wǎng)絡(luò)系統(tǒng)各部件的配置文件,該配置文件描述了網(wǎng)絡(luò)部件安裝、配置、刪除的執(zhí)行過(guò)程。當(dāng)網(wǎng)絡(luò)部件進(jìn)行初始安裝或二次安裝(通常通過(guò)ncpa進(jìn)行)時(shí),安裝程序讀取部件對(duì)應(yīng)的配置文件,進(jìn)行解釋執(zhí)行。gui inf描述語(yǔ)言由節(jié)、命令、邏輯操作、變量規(guī)范、流程控制以及一套調(diào)用dll或外部程序的機(jī)制組成,其中,節(jié)是配置文件的主體,節(jié)可分為install節(jié)(類似于函數(shù)),shell節(jié)(也類似于函數(shù),但可調(diào)用insall和shell節(jié)),detect節(jié)(不包含命令),一個(gè)配置文件一般由若干不同類型的節(jié)組成。驅(qū)動(dòng)程序的開(kāi)發(fā)者根據(jù)需要可以在配置文件中編寫(xiě)相應(yīng)代碼,使得用戶和系統(tǒng)之間能進(jìn)行交互,并且由用戶決定一些配置參數(shù)。
nt網(wǎng)卡配置文件有其一套規(guī)范,驅(qū)動(dòng)程序開(kāi)發(fā)者必須按規(guī)范編寫(xiě)配置文件,一般來(lái)說(shuō),一個(gè)配置文件至少應(yīng)該提供下面三個(gè)節(jié):
安裝入口點(diǎn):[identify]shell節(jié)。該節(jié)主要功能是給出安裝部件的類型名,系統(tǒng)通過(guò)它識(shí)別該部件屬于哪一大類(display,mouse,scsi,network等)中的哪一類(網(wǎng)絡(luò)adapter,driver,transport,service,network和netprovidor),同時(shí),還需要給出映像文件和配置文件所在的源介質(zhì)及標(biāo)識(shí)。
[returnoption]shell節(jié)。系統(tǒng)執(zhí)行安裝identify節(jié)后,執(zhí)行該節(jié)。它主要功能是檢查所需安裝的部件是否支持的硬件平臺(tái)和語(yǔ)言,并給出網(wǎng)卡名(有些配置文件支持多類網(wǎng)卡,此時(shí)必須讓用戶進(jìn)行選擇,并獲得選擇結(jié)果)。
[installoption]shell節(jié)。該節(jié)是配置文件得主體,也是上次安裝完后再次進(jìn)行配置、刪除、更新的入口點(diǎn)。主要功能是拷貝映像文件和配置文件,生成配置的各種選項(xiàng),創(chuàng)建該部件在注冊(cè)庫(kù)中對(duì)應(yīng)的各種登錄子樹(shù)并更新重寫(xiě)。
第二節(jié) 驅(qū)動(dòng)程序的加載過(guò)程
§2.2.1 windows nt的啟動(dòng)過(guò)程
關(guān)鍵詞:ACM競(jìng)賽;程序設(shè)計(jì);課程;教學(xué)改革
中圖分類號(hào):TP3-4 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1007-9599 (2012) 19-0000-02
1 引言
計(jì)算機(jī)軟件技術(shù)的發(fā)展日新月異,給高等院校相關(guān)專業(yè)的教學(xué)帶來(lái)了很大的挑戰(zhàn),為了更好地適應(yīng)不斷變化的社會(huì)就業(yè)需求,就必須在傳統(tǒng)的計(jì)算機(jī)專業(yè)教學(xué)模式的基礎(chǔ)上開(kāi)辟出一條新路。
在這樣的背景下,樂(lè)山師范學(xué)院計(jì)算機(jī)科學(xué)學(xué)院早在2005年就開(kāi)始開(kāi)展校企合作辦學(xué),與企業(yè)聯(lián)合培養(yǎng)校企合作方向的學(xué)生,至今已是第八屆。相比普通班,校企合作教改班所開(kāi)設(shè)的專業(yè)課程更符合于當(dāng)前計(jì)算機(jī)人才市場(chǎng)的需求,典型的特點(diǎn)就是注重對(duì)學(xué)生的專業(yè)技能尤其是程序設(shè)計(jì)和軟件開(kāi)發(fā)能力的系統(tǒng)性培養(yǎng),嚴(yán)格按照軟件工程師的培養(yǎng)模式來(lái)開(kāi)展相關(guān)的理論和實(shí)踐教學(xué)環(huán)節(jié),這在很大程度上改變了以往只注重專業(yè)理論教學(xué)的局限性。
在對(duì)近幾年教改學(xué)生的就業(yè)情況進(jìn)行分析以后,明確肯定了校企合作教學(xué)模式為我院本科人才培養(yǎng)體系的改革起到了決定性的促進(jìn)作用,學(xué)生的專業(yè)技能有了明顯的增強(qiáng),也大大提高了畢業(yè)生的就業(yè)率。
但與此同時(shí)也認(rèn)識(shí)到存在的一些問(wèn)題:首先,傳統(tǒng)的以程序設(shè)計(jì)語(yǔ)言語(yǔ)法描述為主線的教學(xué)方式,以及模式化的實(shí)驗(yàn)內(nèi)容,使教師在教學(xué)過(guò)程中容易將重點(diǎn)偏向理論,降低了對(duì)學(xué)生實(shí)踐能力的鍛煉和考核;其次,我們的軟件工程師主要是在教室和機(jī)房這樣的環(huán)境下培養(yǎng)出來(lái)的,缺乏真刀真槍的實(shí)踐鍛煉機(jī)會(huì);最后,雖然校企合作人才培養(yǎng)方案的整體實(shí)施效果不錯(cuò),但也很難培養(yǎng)出高層次的計(jì)算機(jī)專業(yè)人才。
如果以上幾點(diǎn)不能有效地解決,那么校企合作辦學(xué)的成效和前景將受到限制,因此迫切地需要一種途徑去驅(qū)動(dòng)程序設(shè)計(jì)類專業(yè)課程的教學(xué)模式改革,經(jīng)過(guò)長(zhǎng)期、反復(fù)的思考和摸索,我們認(rèn)為通過(guò)開(kāi)展學(xué)科專業(yè)競(jìng)賽活動(dòng)來(lái)推動(dòng)課程教學(xué)改革是比較可行的。而在種類繁多的計(jì)算機(jī)學(xué)科專業(yè)競(jìng)賽中,最權(quán)威、級(jí)別最高的就是《ACM/ICPC國(guó)際大學(xué)生程序設(shè)計(jì)競(jìng)賽》。
本教改項(xiàng)目結(jié)合ACM競(jìng)賽來(lái)促進(jìn)計(jì)算機(jī)專業(yè)教學(xué)體系特別是程序設(shè)計(jì)類課程的教學(xué)改革,教改實(shí)施對(duì)象主要為計(jì)算機(jī)科學(xué)學(xué)院軟件工程專業(yè)方向的學(xué)生。首先針對(duì)程序設(shè)計(jì)類課程教學(xué)存在的問(wèn)題以及問(wèn)題產(chǎn)生的原因進(jìn)行分析,然后在ACM競(jìng)賽模式和特點(diǎn)的基礎(chǔ)上,嘗試通過(guò)結(jié)合ACM競(jìng)賽來(lái)改革課程開(kāi)設(shè)體系和課程教學(xué)模式,最后提出了解決問(wèn)題的具體措施,并在實(shí)際教學(xué)應(yīng)用中取得了一定的成效。
2 當(dāng)前程序設(shè)計(jì)類課程教學(xué)存在的問(wèn)題
2.1 人才培養(yǎng)模式陳舊,實(shí)踐教學(xué)比例不足
在傳統(tǒng)的被動(dòng)教學(xué)模式中,學(xué)生缺乏學(xué)習(xí)主動(dòng)性、創(chuàng)新性和行業(yè)競(jìng)爭(zhēng)力。而計(jì)算機(jī)專業(yè)課程大多屬于實(shí)踐型課程,強(qiáng)調(diào)動(dòng)手能力。為了加深對(duì)理論知識(shí)的理解,必須提高實(shí)踐教學(xué)質(zhì)量,理論和實(shí)踐教學(xué)的學(xué)時(shí)分配要作適當(dāng)調(diào)整。
2.2 實(shí)踐內(nèi)容模板化,缺乏創(chuàng)新能力的培養(yǎng)
首先,設(shè)計(jì)性、綜合性實(shí)驗(yàn)偏少,很難培養(yǎng)學(xué)生的創(chuàng)造性思維;其次,實(shí)驗(yàn)內(nèi)容嚴(yán)重脫離了現(xiàn)代軟件工程過(guò)程,更談不上對(duì)綜合型應(yīng)用問(wèn)題的解決;最后,在實(shí)踐教學(xué)過(guò)程中,教師干預(yù)太多,學(xué)生處于被動(dòng)完成實(shí)驗(yàn)任務(wù)的角色。
2.3 缺乏互助學(xué)習(xí)能力,團(tuán)隊(duì)協(xié)作意識(shí)較差
當(dāng)前軟件項(xiàng)目的開(kāi)發(fā)都是以團(tuán)隊(duì)形式實(shí)施的,團(tuán)隊(duì)成員之間需要合理分工和無(wú)障礙溝通。但在傳統(tǒng)教學(xué)模式中,以項(xiàng)目組為單位來(lái)開(kāi)展教學(xué)活動(dòng)的機(jī)會(huì)非常少,更談不上互助學(xué)習(xí)和團(tuán)隊(duì)協(xié)作了。
2.4 課程考核模式單一,缺乏激勵(lì)機(jī)制
課程考核主要采用傳統(tǒng)考核模式,考核內(nèi)容受限于教材知識(shí)點(diǎn),缺乏對(duì)學(xué)生知識(shí)結(jié)構(gòu)與實(shí)踐技能的綜合考察,不利于學(xué)生綜合實(shí)踐能力和創(chuàng)新能力的培養(yǎng),最終形成“高分低能”的現(xiàn)象。
3 改革措施
本教改項(xiàng)目主要通過(guò)以下幾個(gè)方面來(lái)實(shí)施以ACM競(jìng)賽促進(jìn)程序設(shè)計(jì)類課程教學(xué)改革的方案。
3.1 改革課程開(kāi)設(shè)計(jì)劃
全面分析了目前程序設(shè)計(jì)類專業(yè)課程教學(xué)中存在的一些問(wèn)題(比如教法和學(xué)法等方面),結(jié)合ACM的競(jìng)賽大綱和競(jìng)賽模式來(lái)調(diào)整開(kāi)課計(jì)劃,把原計(jì)劃一學(xué)期的《程序設(shè)計(jì)基礎(chǔ)》課程的教學(xué)時(shí)間調(diào)整為一學(xué)年,第一學(xué)期是程序設(shè)計(jì)的入門教學(xué),主要介紹高級(jí)程序設(shè)計(jì)語(yǔ)言編程基礎(chǔ);第二學(xué)期是程序設(shè)計(jì)的進(jìn)階教學(xué),主要介紹算法設(shè)計(jì)與分析。
3.2 改革課程實(shí)踐教學(xué)模式[1]
(1)實(shí)驗(yàn)內(nèi)容分級(jí)化:
將實(shí)驗(yàn)內(nèi)容分成知識(shí)型(單一算法)、應(yīng)用型(算法和實(shí)際問(wèn)題結(jié)合)和綜合型(若干小算法的綜合,用于解決一個(gè)較大規(guī)模的問(wèn)題)。不同級(jí)別題型的權(quán)值不同,每一級(jí)別中又包含若干個(gè)相同權(quán)值的題目,學(xué)生可以根據(jù)自身情況選擇不同級(jí)別的題型和題目數(shù)量,這樣既考慮到了不同層次學(xué)生的學(xué)習(xí)需求,又達(dá)到了統(tǒng)一的實(shí)驗(yàn)?zāi)康摹?/p>
(2)實(shí)驗(yàn)題目趣味化:
傳統(tǒng)的程序設(shè)計(jì)類實(shí)驗(yàn)題目普遍比較枯燥,難以調(diào)動(dòng)學(xué)生的學(xué)習(xí)興趣和設(shè)計(jì)思路。參考ACM的海量題集,由任課教師將實(shí)驗(yàn)題目生活化和趣味化,使學(xué)生自主選擇合理的數(shù)據(jù)結(jié)構(gòu)和算法來(lái)解題,這樣可以充分激發(fā)學(xué)生的學(xué)習(xí)主動(dòng)性和積極性,將被動(dòng)學(xué)習(xí)轉(zhuǎn)化為主動(dòng)學(xué)習(xí),更好地達(dá)到了實(shí)踐教學(xué)的目的。
(3)實(shí)驗(yàn)時(shí)間分散化:
考慮到實(shí)驗(yàn)課時(shí)非常有限,可參照ACM競(jìng)賽平臺(tái)來(lái)構(gòu)建“程序設(shè)計(jì)在線評(píng)測(cè)系統(tǒng)”,功能包括用戶管理、題庫(kù)管理、在線提交、在線排名、在線討論等。學(xué)生注冊(cè)后可在任何時(shí)間登陸該系統(tǒng)進(jìn)行選題、提交、評(píng)測(cè)和討論等自主學(xué)習(xí)環(huán)節(jié),將有限的課內(nèi)練習(xí)時(shí)間延續(xù)到課外。
3.3 開(kāi)發(fā)資源網(wǎng)站
在全面搜集ACM競(jìng)賽相關(guān)資源的前提下,以程序員協(xié)會(huì)的學(xué)生會(huì)員為主力設(shè)計(jì)并開(kāi)發(fā)了“ACM資源網(wǎng)站”,并掛靠在學(xué)院的Web服務(wù)器上,以該資源網(wǎng)為平臺(tái)來(lái)開(kāi)展競(jìng)賽的宣傳、組織、培訓(xùn)等活動(dòng),同時(shí)也為相關(guān)課程的理論實(shí)踐教學(xué)和學(xué)生自主學(xué)習(xí)提供了一個(gè)優(yōu)質(zhì)的信息化平臺(tái)。
3.4 建設(shè)學(xué)生梯隊(duì)
依托于樂(lè)山師范學(xué)院第二課堂課程《ACM程序設(shè)計(jì)》的開(kāi)設(shè),以樂(lè)山師范學(xué)院三星級(jí)社團(tuán)“程序員協(xié)會(huì)”為活動(dòng)主體,在全校范圍內(nèi)吸納對(duì)計(jì)算機(jī)編程和競(jìng)賽感興趣的學(xué)生,成立“ACM競(jìng)賽興趣小組”,通過(guò)舉辦專業(yè)講座、學(xué)生科研、協(xié)會(huì)內(nèi)部競(jìng)賽、協(xié)會(huì)沙龍等活動(dòng),為本專業(yè)學(xué)生提供一個(gè)進(jìn)一步增強(qiáng)職業(yè)技能的交流和學(xué)習(xí)平臺(tái),同時(shí)也要在興趣小組中發(fā)現(xiàn)適合參加ACM競(jìng)賽的后備人才,面向各年級(jí)構(gòu)建ACM競(jìng)賽梯隊(duì)。
3.5 建立激勵(lì)機(jī)制
增設(shè)創(chuàng)新學(xué)分,設(shè)置創(chuàng)新環(huán)節(jié),搭建創(chuàng)新實(shí)踐的平臺(tái),讓學(xué)生有更多的機(jī)會(huì)展示自己的專業(yè)特長(zhǎng)。將參加ACM等學(xué)科競(jìng)賽納入學(xué)生的綜合測(cè)評(píng),通過(guò)設(shè)立競(jìng)賽獎(jiǎng)學(xué)金制度來(lái)引導(dǎo)學(xué)生積極參加課外科技活動(dòng)、不斷提高自身的創(chuàng)新素質(zhì)。
3.6 組織參賽
在本教改項(xiàng)目的實(shí)施過(guò)程中,還要積極組織學(xué)生參加各個(gè)級(jí)別的ACM賽事。對(duì)于每一次競(jìng)賽,首先成立競(jìng)賽領(lǐng)導(dǎo)小組,分析官方公布的競(jìng)賽大綱,及時(shí)、準(zhǔn)確地改革專業(yè)教學(xué)體系目標(biāo)和課程開(kāi)設(shè)計(jì)劃;其次根據(jù)往屆參賽經(jīng)驗(yàn),結(jié)合本次競(jìng)賽的具體情況制定出競(jìng)賽活動(dòng)方案,將競(jìng)賽的宣傳、組織、選拔、培訓(xùn)、參賽、獎(jiǎng)勵(lì)等環(huán)節(jié)制度化;然后選拔ACM參賽隊(duì)伍,指派經(jīng)驗(yàn)豐富且取得過(guò)優(yōu)異成績(jī)的教練對(duì)參賽隊(duì)員進(jìn)行長(zhǎng)期、深入、全方位的強(qiáng)化培訓(xùn)和指導(dǎo);最后通過(guò)對(duì)競(jìng)賽成績(jī)的分析再次調(diào)整專業(yè)課程開(kāi)設(shè)計(jì)劃和教學(xué)模式。[2]
3.7 改革考核手段
ACM模式的重要特色之一是完善而嚴(yán)謹(jǐn)?shù)目己藱C(jī)制,所以我們大膽嘗試將ACM的考核方式借鑒到程序設(shè)計(jì)類課程的考核環(huán)節(jié)中,采用ACM模式的黑箱測(cè)試,將學(xué)生在“程序設(shè)計(jì)在線評(píng)測(cè)系統(tǒng)”中獲得的成績(jī)以50%的權(quán)重加入到課程考核指標(biāo)當(dāng)中。這一方面減少了教師的工作量,降低了考核錯(cuò)誤率,另一方面做到了客觀、公正,更好地發(fā)掘了學(xué)生的創(chuàng)新能力,提高其對(duì)知識(shí)點(diǎn)的掌握程度。
4 要解決的關(guān)鍵問(wèn)題
4.1 課程教學(xué)形式的改革,特別是如何處理實(shí)踐教學(xué)和理論教學(xué)的比重關(guān)系,以及如何讓學(xué)生能夠真正地解決問(wèn)題,而不是按照設(shè)定好的思路去模仿著解決問(wèn)題。
4.2 課程評(píng)價(jià)體系的改革,尤其是目前的實(shí)踐環(huán)節(jié)評(píng)價(jià)機(jī)制弊端明顯,嚴(yán)重束縛了學(xué)生的創(chuàng)新能力,錯(cuò)誤地引導(dǎo)學(xué)生把自己改造為一個(gè)受制于理論教材的傀儡。
4.3 差異化教學(xué),考慮到ACM競(jìng)賽的難度較大,所以必須考慮到在將ACM融入到專業(yè)課程教學(xué)過(guò)程之后,如何確保整體教學(xué)質(zhì)量并解決好部分學(xué)生學(xué)習(xí)能力較差的問(wèn)題。
4.4 在ACM競(jìng)賽中取得更好的成績(jī),必須建立有效的組織、選拔、培訓(xùn)、參賽、總結(jié)等相關(guān)機(jī)制。
5 結(jié)語(yǔ)
ACM競(jìng)賽對(duì)程序設(shè)計(jì)類專業(yè)課程的教學(xué)改革起到了積極的推動(dòng)作用,從教學(xué)隊(duì)伍建設(shè)的角度來(lái)看,它在提高教師的教學(xué)水平、科研能力、促進(jìn)專業(yè)的對(duì)外交流等方面都起到了重要的作用;從學(xué)生培養(yǎng)的角度來(lái)看,它在提高學(xué)生的學(xué)習(xí)興趣、自學(xué)能力、創(chuàng)新能力、求真務(wù)實(shí)的科學(xué)態(tài)度上有很大的幫助。
總之,通過(guò)合理的應(yīng)用ACM競(jìng)賽這個(gè)平臺(tái),可以使我們的計(jì)算機(jī)專業(yè)教學(xué)更趨科學(xué)化、規(guī)范化,可以讓我們的學(xué)生開(kāi)拓視野,促進(jìn)實(shí)踐型、創(chuàng)新型人才的培養(yǎng),提高學(xué)生的就業(yè)競(jìng)爭(zhēng)力。
參考文獻(xiàn):
[1]常子楠.基于ACM模式的程序設(shè)計(jì)類課程實(shí)踐教學(xué)探索[J].計(jì)算機(jī)教育,2010(16):144-146.
[2]項(xiàng)煒.以學(xué)科競(jìng)賽促進(jìn)計(jì)算機(jī)專業(yè)教學(xué)改革的探索[J].改革與開(kāi)放,2009(12):207.
[作者簡(jiǎn)介]
為了保證操作系統(tǒng)的平安性和穩(wěn)定性以及應(yīng)用程序的可移植性,Windows操作系統(tǒng)不答應(yīng)應(yīng)用程序直接訪問(wèn)系統(tǒng)的硬件資源,而是必須借助于相應(yīng)的設(shè)備驅(qū)動(dòng)程序。設(shè)備驅(qū)動(dòng)程序可以直接操作硬件,假如應(yīng)用程序和設(shè)備驅(qū)動(dòng)程序之間實(shí)現(xiàn)了雙向通信,也就達(dá)到了應(yīng)用程序控制底層硬件設(shè)備的目的。它們之間的通信包括兩個(gè)方面摘要:一方面是應(yīng)用程序傳送給設(shè)備驅(qū)動(dòng)程序的數(shù)據(jù);另一方面是設(shè)備驅(qū)動(dòng)程序發(fā)送給應(yīng)用程序的消息。前者的實(shí)現(xiàn)較輕易,通過(guò)CreateFile()函數(shù)獲取設(shè)備驅(qū)動(dòng)程序的句柄后,就可以使用Win32函數(shù),如DeviceIoControl()、ReadFile()或WriteFile()等實(shí)現(xiàn)應(yīng)用程序和設(shè)備驅(qū)動(dòng)程序之間的通信。后者的實(shí)現(xiàn)遠(yuǎn)比前者復(fù)雜,同時(shí)介紹這方面情況的文章較少。這不等于說(shuō)它不重要,相反,它在有些應(yīng)用場(chǎng)合發(fā)揮著重要的功能。設(shè)備驅(qū)動(dòng)程序完成數(shù)據(jù)的采集工作后,需要馬上通知應(yīng)用程序,以便應(yīng)用程序能夠及時(shí)將數(shù)據(jù)取走并進(jìn)行處理。諸如此類情況,不一而足。
鑒于設(shè)備驅(qū)動(dòng)程序通知應(yīng)用程序的重要性,本人結(jié)合一些經(jīng)驗(yàn),對(duì)它進(jìn)行了總結(jié),歸納出5種方法摘要:異步過(guò)程調(diào)用(APC)、事件方式(VxD)、消息方式、異步I/O方式和事件方式(WDM)。下面分別說(shuō)明這幾種方式的原理,并給出實(shí)現(xiàn)的部分源代碼。
1 異步過(guò)程調(diào)用(APC)
Win32應(yīng)用程序使用CreateFile()函數(shù)動(dòng)態(tài)加載設(shè)備驅(qū)動(dòng)程序,然后定義一個(gè)回調(diào)函數(shù)backFunc(),并且將回調(diào)函數(shù)的地址%26amp;backFunc()作為參數(shù),通過(guò)DeviceIoControl()傳送給設(shè)備驅(qū)動(dòng)程序。設(shè)備驅(qū)動(dòng)程序獲得回調(diào)函數(shù)的地址后,將它保存在一個(gè)全局變量(如callback)中,同時(shí)調(diào)用Get_Cur_Thread_Handle()函數(shù)獲取它的應(yīng)用程序線程的句柄,并且將該句柄保存在一個(gè)全局變量(如appthread)中。當(dāng)條件成熟時(shí),設(shè)備驅(qū)動(dòng)程序調(diào)用_VWIN32_QueueUserApc()函數(shù),向Win32應(yīng)用程序發(fā)送消息。這個(gè)函數(shù)帶有三個(gè)參數(shù)摘要:第一個(gè)參數(shù)為回調(diào)函數(shù)的地址(已經(jīng)注冊(cè));第二個(gè)參數(shù)為傳遞給回調(diào)函數(shù)的消息;第三個(gè)參數(shù)為調(diào)用者的線程句柄(已經(jīng)注冊(cè))。Win32應(yīng)用程序收到消息后,自動(dòng)調(diào)用回調(diào)函數(shù)(實(shí)際是由設(shè)備驅(qū)動(dòng)程序調(diào)用)。回調(diào)函數(shù)的輸入?yún)?shù)是由設(shè)備驅(qū)動(dòng)程序填入的,回調(diào)函數(shù)在這里主要是對(duì)消息進(jìn)行處理。
2 事件方式(VxD)
首先,Win32應(yīng)用程序創(chuàng)建一個(gè)事件的句柄,稱其為Ring3句柄。由于虛擬設(shè)備驅(qū)動(dòng)程序使用事件的Ring0句柄,因此,需要?jiǎng)?chuàng)建Ring0句柄。用LoadLibrary()函數(shù)加載未公開(kāi)的動(dòng)態(tài)鏈接庫(kù)Kernel32.dll,獲得動(dòng)態(tài)鏈接庫(kù)的句柄。然后,調(diào)用GetProcAddress(), 找到函數(shù)OpenVxDHandle()在動(dòng)態(tài)鏈接庫(kù)中的位置。接著,用OpenVxDHandle()函數(shù)將Ring3事件句柄轉(zhuǎn)化為Ring0事件句柄。Win32應(yīng)用程序用CreateFile()函數(shù)加載設(shè)備驅(qū)動(dòng)程序。假如加載成功,則調(diào)用DeviceIoControl()函數(shù)將Ring0事件句柄傳給VxD;同時(shí),創(chuàng)建一個(gè)輔助線程等待信號(hào)變成有信號(hào)狀態(tài),本身則可去干其它的事情。當(dāng)條件成熟時(shí),VxD置Ring0事件為有信號(hào)狀態(tài)(調(diào)用_VWIN32_SetWin32Event()函數(shù)),這馬上觸發(fā)對(duì)應(yīng)的Ring3事件為有信號(hào)狀態(tài)。一旦Ring3事件句柄為有信號(hào)狀態(tài),Win32應(yīng)用程序的輔助線程就對(duì)這個(gè)消息進(jìn)行相應(yīng)的處理。
3 消息方式
Win32應(yīng)用程序調(diào)用CreateFile()函數(shù)動(dòng)態(tài)加載虛擬設(shè)備驅(qū)動(dòng)程序。加載成功后,通過(guò)調(diào)用DeviceIoControl()函數(shù)將窗體句柄傳送給VxD,VxD利用這個(gè)句柄向窗體發(fā)消息。當(dāng)條件滿足時(shí),VxD調(diào)用SHELL_PostMessage()函數(shù)向Win32應(yīng)用程序發(fā)送消息。要讓該函數(shù)使用成功,必須用#define來(lái)自定義一個(gè)消息,并且也要照樣在應(yīng)用程序中定義它;還要在消息循環(huán)中使用ON_MESSAGE()來(lái)定義消息對(duì)應(yīng)的消息處理函數(shù),以便消息產(chǎn)生時(shí),能夠調(diào)用消息處理函數(shù)。SHELL_PostMessage()函數(shù)的第一個(gè)參數(shù)為Win32窗體句柄,第二個(gè)參數(shù)為消息ID號(hào),第三、四個(gè)參數(shù)為發(fā)送給消息處理函數(shù)的參數(shù),第五、六個(gè)參數(shù)為回調(diào)函數(shù)和傳給它的參數(shù)。Win32應(yīng)用程序收到消息后,對(duì)消息進(jìn)行處理。
4 異步I/O方式
Win32應(yīng)用程序首先調(diào)用CreateFile()函數(shù)加載設(shè)備驅(qū)動(dòng)程序。在調(diào)用該函數(shù)時(shí),將倒數(shù)第2個(gè)參數(shù)設(shè)置為FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,表示以后可以對(duì)文件進(jìn)行重疊I/O操作。當(dāng)設(shè)備驅(qū)動(dòng)程序文件創(chuàng)建成功后,創(chuàng)建一個(gè)初始態(tài)為無(wú)信號(hào)、需要手動(dòng)復(fù)位的事件,并且將這個(gè)事件傳給類型為OVERLAPPED的數(shù)據(jù)結(jié)構(gòu)(如Overlapped)。然后,將Overlapped作為一個(gè)參數(shù),傳給DeviceIoControl()函數(shù)。設(shè)備驅(qū)動(dòng)程序把這個(gè)I/O請(qǐng)求包(IRP)設(shè)置為掛起狀態(tài),并且設(shè)置一個(gè)取消例程。假如當(dāng)前IRP隊(duì)列為空,則將這個(gè)IRP傳送給StartIo()例程;否則,將它放到IRP隊(duì)列中。設(shè)備驅(qū)動(dòng)程序做完這些工作后,結(jié)束這個(gè)DeviceIoControl()的處理,于是Win32應(yīng)用程序可能不等待IRP處理完,就從DeviceIoControl()的調(diào)用中返回。通過(guò)判定返回值,得到IRP的處理情況。假如當(dāng)前IRP處于掛起狀態(tài),則主程序先做一些其它的工作,然后調(diào)用WaitForSingleObject()或WaitForMultipleObject()函數(shù)等待Overlapped中的事件成為有信號(hào)狀態(tài)。設(shè)備驅(qū)動(dòng)程序在適當(dāng)?shù)臅r(shí)候處理排隊(duì)的IRP,處理完成后,調(diào)用IoCompleteRequest()函數(shù)。該函數(shù)將Overlapped中的事件設(shè)置為有信號(hào)狀態(tài)。Win32應(yīng)用程序?qū)@個(gè)事件馬上進(jìn)行響應(yīng),退出等待狀態(tài),并且將事件復(fù)位為無(wú)信號(hào)狀態(tài),然后調(diào)用GetOverlappedResult()
函數(shù)獲取IRP的處理結(jié)果。
5 事件方式(WDM)
Win32應(yīng)用程序首先創(chuàng)建一個(gè)事件,然后將該事件句柄傳給設(shè)備驅(qū)動(dòng)程序,接著創(chuàng)建一個(gè)輔助線程,等待事件的有信號(hào)狀態(tài),自己則接著干其它事情。設(shè)備驅(qū)動(dòng)程序獲得該事件的句柄后,將它轉(zhuǎn)換成能夠使用的事件指針,并且把它寄存起來(lái),以便后面使用。當(dāng)條件具備后,設(shè)備驅(qū)動(dòng)程序?qū)⑹录O(shè)置為有信號(hào)狀態(tài),這樣應(yīng)用程序的輔助線程馬上知道這個(gè)消息,于是進(jìn)行相應(yīng)的處理。當(dāng)設(shè)備驅(qū)動(dòng)程序不再使用這個(gè)事件時(shí),應(yīng)該解除該事件的指針。
6 結(jié)語(yǔ)
在目前流行的Windows操作系統(tǒng)中,設(shè)備驅(qū)動(dòng)程序是操縱硬件的最底層軟件接口。它向上提供和硬件無(wú)關(guān)的用戶接口,向下直接進(jìn)行I/O、硬件中斷、DMA和內(nèi)存訪問(wèn)等操作。它將應(yīng)用程序和硬件細(xì)節(jié)屏蔽開(kāi)來(lái),使軟件不依靠于硬件并且可在多個(gè)不同的平臺(tái)之間移植。本文介紹了5種設(shè)備驅(qū)動(dòng)程序通知應(yīng)用程序的方法,其中前3種方法主要用于VxD中,后2種方法主要用于WDM。這5種方法都經(jīng)過(guò)實(shí)際測(cè)試。測(cè)試結(jié)果表明,它們都能夠達(dá)到設(shè)備驅(qū)動(dòng)程序通知應(yīng)用程序的目的。
參考文獻(xiàn)摘要:
[1歐青立,徐建波,李方敏,等. 虛擬設(shè)備驅(qū)動(dòng)程序VxD的探究和開(kāi)發(fā). 計(jì)算機(jī)工程,2003
驅(qū)動(dòng)教學(xué)論文 驅(qū)動(dòng)電源設(shè)計(jì) 驅(qū)動(dòng)程序設(shè)計(jì) 紀(jì)律教育問(wèn)題 新時(shí)代教育價(jià)值觀