在線客服

          驅動程序設計實用13篇

          引論:我們為您整理了13篇驅動程序設計范文,供您借鑒以豐富您的創作。它們是您寫作時的寶貴資源,期望它們能夠激發您的創作靈感,讓您的文章更具深度。

          篇1

          一、引言

          嵌入式系統的硬件組成除了包括中心控制部件嵌入式系統處理器外,還有輸入輸出裝置以及一些擴充裝置開關、按鍵、傳感器、模數轉換器、LCD顯示器、觸摸屏及LED(發光二極管)等嵌入式硬件設備。嵌入式硬件環境是整個嵌入式操作系統和應用程序運行的硬件平臺,不同的應用通常有不同的硬件環境[1]。硬件平臺的多樣性是嵌入式系統的一個主要特點。如何讓這些設備工作起來,是嵌入式驅動程序的任務。由于I/O設備種類繁多,工作模式各不相同,驅動程序是整個嵌入式軟件設計中最復雜、代碼量最大、最繁瑣的部分。

          二、嵌入式驅動程序概述

          外設驅動程序可以對系統提供訪問設備的接口,把操作系統(軟件)和設備(硬件)分離開來。當設備改變的時候,只需要更換相應的驅動程序,不必修改操作系統的內核以及運行在操作系統中的軟件。系統的驅動程序要受控于相應的操作系統的多任務之間的同步機制。在操作系統中使用信號量、郵箱等機制進行協調。操作系統只和特定的驅動抽象層通訊,無論在抽象層下面對應的是什么類型的設備,對操作系統和用戶的應用程序來說都是統一的接口[2]。驅動抽象層位置圖如圖1所示。

          圖1:驅動抽象層位置圖

          該部分包括基于ARM架構的串行口通訊、鍵盤驅動原理、I/O接口電路、A/D接口電路、LCD的驅動控制、觸摸屏程序設計的內容。

          三、嵌入式驅動程序設計研究

          1.串行口通訊

          通過監視串行口,把我們在程序中插入的想要反饋程序運行情況的串行口語句輸出到顯示器中的超級終端中。這樣便可以實時監控程序的運行情況,方便調試程序。串行口組件設計是將接收到的字符再發送給串口(計算機與開發板是通過超級終端通訊的),即按PC鍵盤通過超級終端發送數據,開發板將接收到的數據再返送給PC,在超級終端上顯示[3]。

          要想設計好串行口驅動程序,需要做如下幾步:

          (1)熟悉串口通訊原理;

          (2)查閱ARM串口寄存器文檔,包括S3C2410控制、狀態和數據寄存器;

          (3)查閱電平轉換芯片資料(max3232);

          (4)設計硬件電路圖;

          (5)設計串口驅動(包括串口寄存器初始化,發送接收函數等)。

          異步通信必須遵循的3項規定為:

          (1)字符的格式

          (2)波特率

          (3)校驗位

          初始化時需要設置波特率、停止位、奇偶校驗、數據位等參數。異步串行方式是將傳輸數據的每個字符一位接一位(例如先低位、后高位)地傳送。數據的各不同位可以分時使用同一傳輸通道,因此串行I/O可以減少信號連線。如圖2給出了異步串行通信中一個字符的傳送格式。

          圖2:串行通信字符格式

          開始前,線路處于空閑狀態,送出連續“1”。傳送開始時首先發一個“0”作為起始位,然后出現在通信線上的是字符的二進制編碼數據。每個字符的數據位長可以約定為5位、6位、7位或8位,一般采用ASCII編碼。后面是奇偶校驗位,根據約定,用奇偶校驗位將所傳字符中為“1”的位數湊成奇數個或偶數個。也可以約定不要奇偶校驗,這樣就取消奇偶校驗位。最后是表示停止位的“1”信號,這個停止位可以約定持續1位、1.5位或2位的時間寬度。至此一個字符傳送完畢,線路又進入空閑,持續為“1”。經過一段隨機的時間后,下一個字符開始傳送才又發出起始位。

          2.鍵盤驅動原理

          鍵盤的設計是將一個瞬時接觸開關放置在每一行與每一列的交叉點。矩陣所需的鍵的數目顯然根據應用程序而不同。每一行由一個輸出端口的一位驅動,而每一列由一個電阻器上拉且供給輸入端口一位。鍵盤掃描過程就是讓微處理器按有規律的時間間隔查看鍵盤矩陣,以確定是否有鍵被按下。一旦處理器判定有一個鍵按下,鍵盤掃描軟件將過濾掉抖動并且判定哪個鍵被按下。每個鍵被分配一個稱為掃描碼的唯一標識符。應用程序利用該掃描碼,根據按下的鍵來判定應該采取什么行動。如圖3所示為逐行掃描法工作原理:逐根行線輸出0電平,而其他行線保持高電平;同時檢測列,列全1就沒有鍵按下,0有鍵按下。行線和列線狀態組合在一起就確定了是哪個鍵按下,如110 1110是0鍵按下,1010111是7鍵按下。

          圖3:逐行掃描法原理圖

          3.I/O接口電路

          I/O系統的目標是對RTOS和應用程序員隱藏設備特定的信息,并且對系統的I/O設備提供一個統一的訪問方法。下面是從不同角度看I/O系統:

          (1)從系統軟件開發者角度看,I/O操作意味著與設備的通信、對設備編程初始化和請示執行設備與系統之間的實際數據傳輸以及操作完成后通知請求者。系統軟件工程師必須理解設備的物理特性,如寄存器的定義和設備的訪問方法。

          (2)從RTOS的角度看,I/O操作意味著對I/O請求定位正確的設備,對設備定位正確的設備驅動程序,并解決對設備驅動程序的請求。有時要求RTOS保證對設備的同步訪問。RTOS必須進行抽象,對應用程序員隱含設備的特性。

          (3)從應用程序員角度看,目標是找到一個簡單、統一和精練的方法與系統中出現的所有類型的設備。

          I/O接口的編址方式分為兩種:

          (1)I/O接口獨立編址――端口映射方式

          這種編址方式是將存儲器地址空間和I/O接口地址空間分開設置,互不影響。設有專門的輸入指令(IN)和輸出指令(OUT)來完成I/O操作。

          (2)I/O接口與存儲器統一編址方式――內存映射這種編址方式不區分存儲器地址空間和I/O接口地址空間,把所有的I/O接口的端口都當作是存儲器的一個單元對待,每個接口芯片都安排一個或幾個與存儲器統一編號的地址號。也不設專門的輸入/輸出指令,所有傳送和訪問存儲器的指令都可用來對I/O接口操作。

          4.A/D接口電路

          A/D轉換器能將模擬量轉換為數字量的電路;D/A轉換器能將數字量轉換為模擬量的電路。A/D轉換器和D/A轉換器是溝通模擬電路和數字電路的橋梁,也可稱之為兩者之間的接口。A/D 轉換器是模擬信號源和CPU 之間聯系的接口,它的任務是將連續變化的模擬信號轉換為數字信號,以便計算機和數字系統進行處理、存儲、控制和顯示。一般A/D轉換過程要經過采樣、保持、量化和編碼四個步驟。前兩步在取樣―保持電路中完成,后兩步則在A/D轉換器中完成。D/A轉換器的基本原理是將輸入的每一位二進制代碼按其權的大小轉換成相應的模擬量,然后將代表各位的模擬量相加,所得的總模擬量就與數字量成正比,這樣便實現了從數字量到模擬量的轉換。

          A/D轉換器較常用的是逐次逼近型,如圖4所示。轉換前,先將SAR寄存器各位清零。轉換開始時,控制邏輯電路先設定SAR寄存器的最高位為“1”,其余位為“0”,此試探值經D/A轉換成電壓Vc,然后將Vc與模擬輸入電壓Vx比較。如果Vx≥Vc,說明SAR最高位的“1”應予保留;如果Vx

          圖4:逐次逼近式A/D轉換原理圖

          5.LCD的驅動控制

          LCD顯示器的基本原理就是通過給不同的液晶單元供電,控制其光線的通過與否,從而達到顯示的目的。因此,LCD的驅動控制歸于對每個液晶單元的通斷電的控制,每個液晶單元都對應著一個電極,對其通電,便可使光線通過。

          液晶模塊有兩種工作模式:圖形方式和文本方式。在圖形方式下,模塊上的緩沖區映射的是液晶屏上顯示的圖形點陣;在文本方式下,模塊上的緩沖區對應的是液晶屏上顯示的文本字符,包括英文字符和英文標點符號。因為漢字字庫沒有包含在液晶模塊之中,所以液晶屏在文本方式下只能顯示英文,不能顯示漢字。液晶屏的操作主要包括:初始化、設置液晶屏的工作模式(文本或者圖形)、更新顯示、開啟(或者關閉)背光等。

          6.觸摸屏程序設計

          觸摸屏是專門處理是否有筆或手指等物體按下觸摸屏,平常相互絕緣的兩層導電層就在觸摸點位置有了一個接觸,并在按下時分別給兩組電極通電。因其中一面導電層(頂層)接通X軸方向的5V均勻電壓場,使得檢測層(底層)的電壓由零變為非零,控制器偵測到這個接通后,其對應位置的模擬電壓信號經過A/D轉換送回處理器。經過坐標轉換后,得到觸摸點的x/y坐標。

          觸摸屏接口專用芯片ADS7843是Burr-Brown公司生產的,能夠完成電極電壓的切換及采集接觸點處的電壓值,并進行A/D轉換。在完成一次x/y坐標采樣的過程中需要一次模式轉換即在點擊觸摸屏之前是等待中斷模式,當有觸摸動作產生觸摸屏中斷以后,在x/y的坐標采集驅動中設置成自動的x/y位置轉換模式,在完成采集以后再轉換回等待中斷模式,準備下一次的觸摸采樣。

          四、總結

          嵌入式驅動程序設計滲透在掌上電腦、筆記本電腦和手機等各個領域,這些設備要想正確工作,必須借助相應硬件及其驅動程序。隨著嵌入式系統在工業控制領域、智能機器人、移動通訊以及智能家電、網絡家電的應用,驅動程序設計方面的開發人員需求量也會越來越多。

          基金項目:北京信息科技大學《嵌入式系統安全》課程建設項目

          [參考文獻]

          [1]王小妮、魏桂英、楊根興. 嵌入式組件設計[M].北京航空航天大學出版社,2012

          篇2

          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.

          時間是科學實驗、科學研究和工程技術等領域中的一個基本物理參量。為了保證系統各部分時間的一致性和正確性,系統內各設備的同步時鐘從卡從時鐘源獲取高精度的標準時間,提供給相應設備。這樣系統內各設備的時間與時間源相同而保持一致。同步時鐘卡一般采用PCI總線方式。PCI總線能夠實現設備間的快速訪問,它以突出的性能受到計算機和通信界工程師們的青睞。

          因此如何開發出穩定、可靠、高效的PCI設備驅動程序成為驅動工程師們面臨的一個棘手的問題[5]。過去對于PCI設備驅動程序的開發大多采用WDM(Windows Driver Model)框架,但是它編程比較復雜,快速掌握其開發要領對于初學者來說比較困難[5]。本文所述的PCI同步時鐘卡的驅動程序的開發采用微軟最新推出的WDF(Windows Driver Foundation)驅動模型。WDF驅動模型提供事件驅動和面向對象的驅動程序開發框架,大大降低了設備驅動程序的開發難度[5]。

          1 同步時鐘卡系統架構

          本文所述的驅動程序是基于自行研發的PCI同步時鐘卡,其原理框圖如圖1所示。本同步時鐘卡選擇PCI9052芯片做為PCI總線的接口芯片。該電路除了用到PCI9052外,還用到了單片機、EEPROM、雙口RAM、CPLD。單片機是系統的控制單元;串行EEPROM存儲了PCI9052芯片所需要的配置信息;雙口RAM用于PC機與時鐘卡之間交換數據;CPLD用于200us時標的產生和中斷的控制。

          同步時鐘卡的工作流程如下:同步時鐘從卡接收時鐘源輸出的時間信號,單片機將其解析成高精度的同步時間信息,控制邏輯(CPLD)通過1PPS脈沖信號產生200us的高精度時間刻度,于是產生高精度的同步絕對時標,連續存儲于雙口RAM中,最后計算機通過PCI總線接口獲取高精度的絕對時間。本系統中計算機獲取雙口RAM中的時間數據的方式有兩種:(1)PC機主動讀取雙口RAM中的數據。(2)外部事件通過中斷通知PC機事件發生,PC機收到通知后讀取雙口RAM中的時間信息,可獲得外部事件發生的精確時刻。兩種方式分別涉及驅動程序的硬件訪問和中斷通知。于是涉及到本文介紹的重點:基于WDF模型的PCI總線驅動程序的開發。

          2 WDF驅動程序設計

          微軟對過去的WDM(Windows Driver Model)驅動程序的架構做了改進,形成了全新的WDF(Windows Driver Foundation)框架結構。它將原來普通軟件開發中面向對象的技術應用到了驅動程序的開發中。WDF改變了驅動程序與操作系統內核之間的關系,在傳統的WDM驅動程序中,不僅要處理硬件,還要處理驅動程序與操作系統內核之間的交互[4]?,F在WDF則使驅動程序與操作系統內核獨立開來,驅動程序與操作系統交互工作將由框架內封裝的方法(函數)去完成,這樣驅動開發工程師只需專注處理目標硬件的行為即可,避免了兩面不周顧此失彼的弊端。不僅大大降低了驅動程序的代碼量,還使整個系統更加穩定、可靠。

          WDF驅動程序包括兩個類型,一個是內核級的,稱為KMDF(Kernel-Mode Driver Framework);另一個是用戶級的,稱為UMDF(User-Mode Driver Framework)。本文所述的驅動程序采用KMDF模式。

          2.1 WDF驅動程序開發流程

          本文所用開發環境為Microsoft Windows Driver Kit(WDK) 8.1和Microsoft Visual Studio 2013,操作系統為Windows7。先安裝VS2013,再安裝WDK8.1,便可在VS2013中直接創建KMDF工程。根據同步時鐘卡所需功能編寫好驅動程序即可進行編譯。

          WDF驅動程序框圖如圖2所示。

          2.2 基于WDF模型的PCI設備驅動程序的實現

          WDF模型的設備驅動程序從功能上可分為三個部分:初始化設備、控制設置與交換數據[3]。初始化設備主要實現設備的識別、驅動對象與設備對象的建立與硬件資源的分配;控制設置負責應用程序與驅動程序的連接和設備的打開;交換數據處理的是設備功能的具體應用,即PCI總線與同步時鐘卡之間的數據傳輸。

          從本質上來說,WDF模型的設備驅動程序是由入口函數DriverEntry和事件例程及其子函數組成的[3]。操作系統在第一次加載驅動程序時會通過調用DriverEntry例程來完成設備驅動程序和框架的初始化[3]。所有的驅動程序都必須包含一個DriverEntry例程。對于不同類型的驅動程序其入口函數DriverEntry也不同,可分為:設備驅動、純軟件驅動與過濾驅動。本文所述的PCI總線驅動程序屬于設備驅動,在入口函數DriverEntry中,主要完成兩件事:注冊EvtDriverDeviceAdd回調例程、創建和初始化WDFDRIVER對象。

          WDF_DRIVER_CONFIG_INIT(&config,PCIdriverEvtDeviceAdd);

          //注冊EvtDriverDeviceAdd回調例程

          status = WdfDriverCreate(DriverObject, RegistryPath,...);

          //創建驅動對象

          2.2.1初始化設備

          在驅動程序被成功初始化完成之后,操作系統會順序調用EvtDriverDeviceAdd、EvtDevicePrepareHardware等回調例程以實現所控制的設備的初始化。

          當首次枚舉設備時,EvtDriverDeviceAdd例程在系統初始化時被PnP管理器調用。在系統運行過程中,任何時候一個新的相同設備被枚舉,系統都將調用此例程。EvtDriverDeviceAdd例程是設備初始化過程中最新被調用的回調例程,它需要完成:設備對象的創建,創建符號鏈接或設備對象GUID接口,創建一個或多個I/O隊列,各種事件的回調函數的注冊,如即插即用、電源管理、I/O處理例程等[1]。

          EvtDriverDeviceAdd例程的主要代碼如下所示:

          注冊即插即用基本例程:

          WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);

          pnpPowerCallbacks.EvtDevicePrepareHardware = PCIDriverEvtDevicePrepareHardware;

          pnpPowerCallbacks.EvtDeviceReleaseHardware = PCIDriverEvtDeviceReleaseHardware;

          ..........

          WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);

          創建設備對象:

          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);

          創建隊列對象并注冊回調例程:

          WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,....);

          ioQueueConfig.EvtIoDeviceControl = PCIdriverEvtIoDeviceControl;

          ioQueueConfig.EvtIoStop = PCIdriverEvtIoStop;

          status = WdfIoQueueCreate(control_device,&ioQueueConfig,...);

          創建符號鏈接:

          status = WdfDeviceCreateSymbolicLink(control_device, &ustring);

          創建中斷對象:

          deviceContext = GetDeviceContext(control_device);

          WDF_INTERRUPT_CONFIG_INIT(&interruptConfig,PCIDriverEvtInterruptIsr,

          PCIDriverEvtInterruptDpc);//設置中斷服務例程和延遲過程調用WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&interruptAttributes,..);

          status = WdfInterruptCreate(control_device,&interruptConfig,

          &interruptAttributes,&deviceContext->Interrupt);

          EvtDriverDeviceAdd例程調用完成之后,系統將調用EvtDevicePrepareHardware例程初始化地址指針,將設備所占用的I/O地址和內存地址映射為虛擬地址,驅動程序將通過這些虛擬地址完成與設備的數據傳輸。由于串行EEPROM存儲了PCI9052芯片所需要的配置信息,系統將自動為本文所述的PCI同步時鐘卡分配資源,它們包括雙口RAM的內存地址、PCI9052的I/O地址空間,所以EvtDevicePrepareHardware例程必須將這些資源映射為虛擬地址。對于I/O端口,只需將首地址與地址數目值保存在設備上下文;對于存儲器芯片,調用MmMapIoSpace函數將物理地址映射為系統內核虛擬地址,然后保存于設備上下文。相對應的,當設備被卸載時,系統會自動調用EvtDeviceReleaseHardware回調例程釋放之前申請的硬件資源。

          for (i = 0; i < WdfCmResourceListGetCount(ResourceListTranslated); i++) {//WdfCmResourceListGetDescriptor函數獲取該資源的描述符

          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控制設置與數據交換

          應用程序實現和驅動程序通信的過程是:應用程序首先調用CreateFile函數打開設備,然后可以使用DeviceIoControl和驅動程序通信,包括寫數據給驅動程序和從驅動程序讀數據兩種情況,也可以用WriteFile寫數據給驅動程序或用ReadFile從驅動程序讀數據,當應用程序退出時,調用用CloseHandle關閉設備。本文所述的系統是用DeviceIoControl和驅動程序通信。CreateFile打開設備的方式有兩種:符號鏈接名與GUID接口,本文所述驅動程序采用的是符號鏈接名的方式。

          m_hDevice=CreateFile(sLinkName,...);//以符號鏈接名的方式打開設備

          上述代碼中sLinkName為符號鏈接名,它與驅動程序中設置的符號鏈接名相同。m_hDevice為返回的設備的有效句柄,應用程序就可以應用它調用DeviceIoControl函數與驅動程序交換數據。應用程序的請求會被放入請求隊列中,并在EvtIoDeviceControl函數之中被處理。

          本文中應用程序獲取時鐘卡上的時間信息的方式有兩種:(1)直接讀取。(2)中斷方式。

          對于第一種方式,應用程序直接調用DeviceIoControl函數與驅動程序交換數據。由于系統的雙口RAM被映射到虛擬內存,驅動程序可以使用下面兩條指令對雙口RAM進行讀寫: READ_REGISTER_XXX;//讀雙口RAM,WRITE_REGISTER_XXX;//寫雙口RAM。

          對于中斷方式,當被捕獲的外部事件發生時,驅動程序會進入中斷服務例程EvtInterruptIsr,然后進入延時過程調用EvtInterruptDpc,首先清中斷源,然后將雙口RAM中的時間數據讀取到設備上下文中緩存,該數據即為外部事件發生的時間,最后通知應用程序讀取該數據。應用程序將調用DeviceIoControl函數獲取設備上下文中的時間信息。驅動程序與應用程序通信的方法有兩種:DeviceIoControl異步完成和WIN32事件通知。本文所述系統采用WIN32事件通知的方法。對于此種方法,應用程序初始化時首先生成一個通知事件,并通過DeviceIoControl函數的輸入緩沖區發送給驅動程序,驅動程序創建相應的內核事件,同時使能PCI9052的LINT1中斷,當該事件發生時,驅動程序會通知應用程序,應用程序的一個子線程不停的循環等待驅動程序發來的事件發生通知。當設備被卸載時需要撤銷該內核事件。具體主要代碼如下:

          應用程序生成通知事件:

          mhEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

          應用程序子線程中等待事件發生:

          while (WaitForSingleObject(mhEvent, 0) != WAIT_OBJECT_0)

          {...}

          驅動程序創建相應的內核事件:

          ObReferenceObjectByHandle(....);

          允許PCI中斷,使能PCI9052的本地LINT1中斷,pREG為PCI9052映射的I/O空間的基 地址:

          inter = READ_PORT_USHORT(pREG + 0x4c);

          inter |=0x43;

          WRITE_PORT_USHORT(pREG + 0x4c, inter);

          清中斷源,設置PCI9052的CS3引腳有效,通知CPLD清掉LINT1信號:

          inter = READ_PORT_USHORT(pREG + 0x50);

          inter |= 0x800;

          WRITE_PORT_USHORT(pREG + 0x50, inter);

          驅動程序給應用程序發送事件,通知應用程序讀取數據:

          KeSetEvent(pDevice_context->Event, 0, FALSE);

          驅動程序內撤銷內核事件:

          ObDereferenceObject(...);

          3 結語

          驅動程序是硬件與應用程序通信的橋梁,它對系統性能提升的作用舉足輕重。高效、穩定、可靠的驅動程序可以使系統性能得到很好的提升。

          本文簡要介紹了PCI同步時鐘從卡的工作原理,并重點討論了基于WDF模型的PCI設備驅動程序設計方法。本文所述的PCI同步時鐘卡驅動程序,在WDK8.1中成功編譯,自動生成SYS文件(驅動程序代碼)和INF文件(設備安裝信息),成功安裝并且能夠穩定可靠地運行。經測試,捕獲的時間精度達到誤差小于200us,滿足系統設計要求。涉及本驅動程序的系統已應用于三峽大壩左岸發電廠發變機組的故障錄波系統中,運行穩定可靠。總而言之,WDF驅動模型優化并簡化了設備驅動程序的開發,比傳統的WDM驅動模型更加穩定。

          參考文獻

          [1]武安河.Windows設備驅動程序WDF開發[M].北京:電子工業出版社,2009.

          [2][美]Ronald D. Reeves 著,張猛等 譯.Windows設備驅動程序開發[M].北京:人民郵電出版社,2012.

          篇3

          0 引 言

          設備互聯(PCI)總線是一種先進的高性能局部總線,可同時支持多組設備[1]。CPCI總線應用于工業和嵌入式領域,其規范改進自PCI規范,CPCI規范在電氣方面兼容PCI規范,只是在封裝結構上進行了加強,CPCI板的封裝結構基于IEC 60297?3,IEC 60297?4以及IEEE 1101.10定義的歐式板卡外形[2]。既然電氣特性上兼容PCI規范,因此CPCI驅動程序的設計本質就是PCI驅動程序設計。

          當前Windows環境下用于PCI設備驅動開發的工具主要是DDK,DriverStudio以及WinDriver。前兩者功能強大,但是開發者需要熟知操作系統的體系結構、匯編語言和設備驅動程序結構體系方法,還需要具備豐富的驅動程序開發經驗,否則可能造成軟件不穩定甚至系統崩潰,另外前兩者開發周期長。而Jungo公司開發的WinDriver改變了傳統的驅動程序開發方法,其整個驅動程序中的所有函數都是工作在用戶態下,使開發者不需要掌握前兩者所需的預備知識就可以開發出與之相媲美的程序[3]。

          為了實現在主控計算機和信號處理板之間快速通信,采用了CPCI并行總線技術,信號處理板采用內嵌PCI模塊的DSP6416芯片。軟件開發基于Windows平臺和VC++6.0編程環境,為了便于應用程序調用驅動程序,按照模塊化的軟件設計思想,驅動程序以DLL動態鏈接庫的形式封裝。為提高工作效率、縮短開發周期,開發工具選用WinDriver。

          1 WinDriver簡介

          WinDriver是一套設備驅動程序開發組件,它的目的就是方便程序員快速開發出PCI,ISA,CPCI,PCIE等設備的Windows驅動程序[4]。

          1.1 WinDriver原理

          WinDriver的體系架構分為兩種模式:用戶模式和內核模式。對硬件進行操作時,開發者應用程序調用WinDriver用戶模式的庫函數,用戶模式的庫函數再調用WinDriver內核,WinDriver內核再調用操作系統底層函數實現對硬件的最終訪問。其與硬件模板、用戶驅動程序、用戶應用程序之間的關系即體系架構見圖1[5?6]。對于某些在用戶模式下不能實現的高性能硬件驅動程序,可通過WinDriver的內核插件功能實現:在用戶模式下完成編程和調試,不做任何修改,直接將該高性能要求的程序模塊植入內核插件,WinDriver即從內核模式下調用該程序模塊。

          1.2 WinDriver特點

          作為一款實用的驅動程序開發工具包,WinDriver的主要優點和特征如下:

          (1)通過內核插件功能(Kernel PlugIn)能夠實現用戶模式的易用和內核模式的高性能;

          (2)友好的驅動向導允許不寫一行代碼即可實現硬件診斷;

          (3)支持所有PCI/PCMCIA/CardBus/ISA/EISA/CompactPCI/PCIExpress設備,與制造商無關;

          (4)可以利用常見的軟件開發平臺包括MSDEV/VisualC/C++,Borland Delphi,Visual Basic6.0等;

          (5)開發者不需要知道DDK,ETK,DDI及任何其他系統層面的編程知識;

          (6)支持I/O、DMA中斷處理和直接訪問板卡映射的存儲器;

          (7)支持多CPU及多PCI總線平臺。

          1.3 用WinDriver開發驅動程序

          利用WinDriver開發驅動程序有2種方式:通過驅動程序向導生成驅動程序框架,再對框架程序進行修改和調試;直接編寫驅動程序。

          通過驅動程序向導開發步驟:板卡檢測、診斷;生成驅動程序框架;調試、編譯驅動程序。

          直接編寫代碼方式步驟:

          (1)包含WinDriver相關的頭文件;

          (2)WinDriver庫函數調用,WinDriver庫函數典型調用流程見圖2[7]。

          2 CPCI信號處理板卡驅動程序設計

          2.1 硬件環境

          實現PCI總線協議一般有2種方法:一是用FPGA設計實現,由于PCI協議比較復雜,實現較困難;二是采用專業PCI總線控制芯片,如AMCC公司的S5933、PLX公司的PCI 9080等通用PCI接口芯片[8]。本信號處理板采用第二種方法,選用自帶PCI接口模塊的DSP6416,主控計算機上的應用程序通過驅動程序將控制命令字主動寫入DSP內存,實現主控計算機對信號處理板的控制;信號處理板結果數據處理完畢后,向主控計算機發中斷,驅動程序響應該中斷,并主動讀取指定DSP內存獲取結果數據。

          結果數據和模塊狀態信息存入L2緩存單元,主控計算機下發的命令字也寫入L2緩存單元。結果數據緩存劃分為大小各為28 KB的Block1和Block2兩塊區域;模塊狀態信息緩存大小為24字節;控制命令緩存大小為1 B。DSP中與PCI操作有關的緩存定義見表1。

          表1 DSP中與PCI操作有關的緩存定義

          當Block1緩存填滿后,新的結果數據存入Block2緩存,同時DSP給主控計算機發PCI中斷,主控計算機通過PCI接口讀取Block1;同理當Block2填滿后,新的結果數據存入Block1緩存,主控計算機通過PCI讀取Block2。Block1和Block2緩存交替接收結果數據。

          2.2 CPCI驅動程序DLL接口設計

          為了便于應用程序訪問驅動程序,按照模塊化的軟件設計思想,驅動程序以DLL動態鏈接庫的形式進行封裝,應用程序通過與驅動程序DLL之間的接口來訪問信號處理模塊的板上資源,下發控制命令、獲取結果數據。主要接口及其功能描述如下:

          (1)DSP6416DLL_Init(CWnd* pMainWnd):打開并注冊WDC庫、打開設備,初始化中斷;

          (2)DSP6416DLL_SendCmd(BYTE BCommand):主控計算機中的控制命令數據寫入DSP中命令存儲區;

          (3)DSP6416DLL_ReadState(BYTE *StateData):從DSP的狀態存儲區讀取信號處理板的狀態數據;

          (4)DSP6416DLL_ReadResult(BYTE *ResultData):從DSP的Block1或Block2數據緩存區讀取結果數據;

          (5)DSP6416DLL_Exit():關閉中斷,關閉設備,關閉WDC庫。

          2.3 CPCI驅動程序實現

          在硬件環境和接口、驅動程序封裝形式及其軟件接口確定后,剩下的工作就是CPCI驅動程序的實現。該工作主要內容為驅動程序DLL各接口函數的編碼實現和WinDriver庫函數調用。

          2.3.1 文件包含

          包含與WinDriver相關的頭文件:windrvr.h,windrvr_int_thread.h,wdc_lib.h。

          2.3.2 驅動程序初始化

          驅動程序初始化主要工作和步驟包括:打開WinDriver,WinDriver授權、版本號檢查、板卡檢測、板卡信息獲取、模塊配置、板卡注冊和PCI中斷使能,驅動程序初始化流程見圖3。

          2.3.3 驅動程序向DSP內存寫數據

          DSP6416的PCI接口支持四種類型的數據交換[9?10]:從模式寫,外部PCI主設備通過PCI接口寫數據到DSP;從模式讀,外部PCI主設備通過PCI接口讀取DSP中的數據;主模式寫,DSP主設備通過PCI接口向外部設備寫數據;主模式讀,DSP主設備通過PCI接口向外部設備讀數據。

          4 結 語

          通過實際應用,發現用WinDriver開發的本驅動程序運行穩定可靠,達到了主控計算機對信號處理板實時控制,特別是信號處理板中大容量數據實時上傳的目的。由于系統方案確定了CPCI并行總線作為通信手段,硬件設計時采用了自帶主從式PCI接口模塊的DSP6416芯片,驅動開發工具選擇了快速高效的WinDriver工具包,以及對驅動程序形態進行DLL封裝,本驅動程序從需求設計到完成編碼和調試不到一個月的時間,在保證軟件質量的同時,縮短了研制周期,提高了開發效率。

          參考文獻

          [1] 李貴山,戚德虎.PCI局部總線開發者指南[M].西安:西安電子科技大學出版社,1997.

          [2] PICMG. Compact PCI core specification PICMG 2.0 R3.0 [R]. [S.l.]: PICMG, 1999.

          [3] 王磊,魯新平,李吉成.WinDriver在開發基于PLX9056芯片的PCI設備驅動程序中的應用[J].現代電子技術,2006,29(18):77?79.

          [4] 李靜,趙保軍.基于TMS320C6416內嵌PCI設備驅動程序開發[J].微機發展,2005,15(10):135?137.

          [5] Jungo Ltd. WinDriver PCI/ISA/CardBus v8.02 user’s guide [R]. US: Jungo Ltd, 2005.

          [6] 簡育華.基于WinDriver的 PCI驅動程序開發[J].火控雷達技術,2011,40(1):68?70.

          [7] Jungo Ltd. WinDriver PCI/PCMCIA/ISA v8.02 Low?Level API Reference[R]. US: Jungo Ltd, 2005.

          篇4

          Designed of PCI Device Driver Based on DDK

          ZHAO bin1, TIAN Ze1, CHEN Jia2

          (1.Xi'an Shiyou University, Xi'an 710065, China; 2. Xidian University, Xi'an 710072, China)

          Abstract: This paper takes a PCI device as an example, describes WDM drivers and PCI bus protocols. And introducing a method of WDM driver design base on DDK(Driver Development Kit), realizing identification and testing function.

          Key words: WDM; PCI; DDK; device driver

          因為某項目的需求,需要在PC機上調試一PCI設備,在Windows系統下實現主機通過PLX9056橋芯片對PCI設備的訪問,但前提條件是當操作系統裝載驅動程序正確的情況下。如果驅動程序裝載不正常,主機首先就不能夠識別PCI設備;如果驅動程序運行不正常,用戶就不能正確的訪問PCI設備。因此,PCI驅動程序是實現主機識別板卡以及正確訪問設備的關鍵。

          目前常用的驅動開發工具有:微軟提供的DDK(Device Driver Kits),以及第三方廠商提供的DriverStudio和WinDriver,現在大多數驅動開發人員都是使用DriverStudio和WinDriver,其中DriverStudio將DDK函數按照邏輯功能組織,把很多常用功能封裝成類,建立了一個基于C++語言的面向對象的編程環境,大大降低了開發難度和開發周期;WinDriver將一些基本的操作如存儲讀寫、I/O端口讀寫、中斷服務、DMA操作等進行了封裝,開發者只需編寫一個外殼來調用這個驅動程序,就可以完成對硬件設備的訪問。前兩種開發工具使用簡單,開發速度快,但開發的驅動程序執行效率受到限制。DDK雖然編程難度較大,對編程人員的要求也較高,但是功能強大,編程靈活,使用范圍廣,可應用于各類硬件驅動程序的編寫,而且有助開發人員深刻理解驅動程序和WDM(Windows Driver Mode),所以DDK是更理想的開發工具。

          1 WDM式設備驅動的概述

          1.1 WDM概念

          設備驅動程序需與操作系統最底層進行交互,不同的操作系統底層結構對應于不同的設備驅動程序模型,也影響設備驅動程序的兼容性。在Windows 2000以后,微軟公司加入了新的驅動程序模型,這就是WDM。

          1.2 WDM式驅動的基本結構

          WDM模型中,兩個驅動設備對象分別是物理設備對象(Physical Device Object,簡稱PDO)和功能設備對象(Function Device Object,簡稱FDO)。其關系是“附加”與“被附加”的關系。

          當某個設備插入PC機時,PDO會自動創建。確切的說,PDO是由總線驅動創建的。PDO需要配合FDO一起使用,系統會提示檢測到新設備,要求安裝驅動程序。需要安裝的驅動程序就是WDM程序,此驅動程序就是創建FDO并附加到PDO之上。當一個FDO附加在PDO上的時候,PDO設備對象的子域AttachedDevice會記錄FDO的位置。PDO靠近物理設備,被稱作底層驅動,而FDO接近發出I/O請求,被稱作高層驅動。并且從WDM驅動的設計思路可以看出,WDM驅動是支持即插即用的。

          在FDO和PDO之間還會存在過濾驅動,在FDO上面的過濾驅動被稱作上層過濾驅動,在FDO下層的驅動,被稱作下層過濾驅動。在WDM模型中,過濾驅動不是必須存在的,PDO和FDO是必須的。

          2 PCI總線協議

          PCI總線協議是PC上最基本的總線,一般顯卡、網卡都設計成PCI總線設備。其他總線都是掛在PCI總線上的。例如,ISA總線是通過PCI-ISA橋設備掛在PCI總線上,而USB總線是通過USB HOST設備掛在PCI總線上的。

          2.1 PCI總線簡介

          PCI(Pheripheral Component Interconnect)總線是當前最流行的總線之一,是由Intel公司首先推出的一種局部總線。它定義了32位數據地址總線,并且可以擴展為64位,其支持突發讀寫操作,也同時可以支持多組設備。

          在當前的PC體系結構內,幾乎所有外部設備采用的各種各樣的接口總線,均是通過橋接電路掛接在PCI系統內的。在這種PCI系統中,Host/PCI橋稱為北橋,連接主處理器總線到基礎PCI局部總線。PCI-ISA橋稱為南橋,連接基礎PCI總線到ISA總線。其中南橋通常還含有中斷控制器、IDE控制器、USB控制器和DMA控制器等設備。

          2.2 PCI配置空間簡介

          PCI有三個相互獨立的物理地址空間:設備存儲器地址空間、I/O地址空間和配置空間。配置空間是PCI所特有的一個物理空間。由于PCI支持設備即插即用,所以PCI設備不占用固定的內存地址空間或I/O地址空間,而是可以由操作系統決定其映射的基址。

          系統加電時,BIOS檢測PCI總線,確定所有連接在PCI總線上的設備以及它們的配置要求,并進行系統配置,實現真正的即插即用。

          3 開發實例

          Windows從總體上分為內核模式(Kernel Mode)和用戶模式(User Mode)。驅動程序運行在內核模式下,擁有操作系統的最高權限。編寫驅動程序主要是為了操作硬件設備,這些硬件設備的操作主要包括訪問物理映射內存、設備端口等。而應用程序是運行在用戶模式下,應用程序無法直接與硬件設備通信,必須借助于驅動程序。

          所開發的PCI設備應用軟件和驅動軟件駐留在PC機中,其中應用軟件與特定的子系統有關,應用軟件通過調用PCI驅動軟件實現子系統功能要求。應用軟件和驅動軟件在Windows下的關系如圖2所示。

          3.1 PCI設備驅動程序

          PCI模塊驅動軟件是實現PCI板卡與宿主機(PC機)應用軟件間的接口控制與數據傳遞的專用軟件,它可提供PCI板卡與PC機各類消息數據的讀、寫支持,以及對PCI板卡內部程序的調度。

          PCI驅動程序開發軟件是DDK,用戶模式下所有對驅動程序的I/O請求,全部由操作系統轉化為IRP(I/O Request Package,即輸入輸出請求包)數據結構,不同IRP數據會被“派遣”到不同的派遣函數(Dispatch Function)。

          驅動軟件的入口程序是DriverEntry,在DriverEntry中包含了AddDevice函數的設置。PCI設備是屬于被動加載的設備,操作系統必須加載PDO后調用AddDevice例程,而AddDevice例程就是負責創建FDO并附加到PDO之上。

          其次,DriverEntry必須加入IRP_MJ_PNP的派遣回調函數。IRP_MJ_PNP就是即插即用IRP,是由即插即用管理器發送給PCI驅動程序的。

          當啟動PCI設備的時候,設備管理器將IRP_MN_START_DEVICE發送給PCI驅動。在處理完此IRP后,驅動程序會將處理結果存儲在IRP的設備堆棧中。程序可從當前堆棧就可以獲取PDO從PCI配置空間中的有用信息,如中斷號、設備物理內存及IO端口信息等。因為實際應用中,不能提前知道這些描述符在數組中出現的位置,因此在實現中必須用循環先把資源值提取到一組局部變量中,然后在處理這些資源信息。

          對于枚舉PCI設備資源,主要分為四類,分別是設備端口、設備物理內存、DMA、中斷等。在實現中,程序里枚舉了I/O端口資源,物理內存資源和中斷資源。其中,I/O端口資源包括I/O端口地址、I/O端口地址長度,物理內存資源包括基地址0和基地址2,中斷資源包括中斷請求級、中斷向量、CPU親緣關系、中斷模式以及共享中斷等。

          在設備即將停止的時候,即插即用管理器將發送IRP_MN_REMOVE_DEVICE給PCI驅動,這個IRP標志著設備即將關閉,PCI驅動在此時會做一些資源回收工作。

          因此開發PCI設備驅動最重要的一步就是將IRP_MN_START_DEVICE中獲取的設備資源記錄下來,以便以后使用。

          3.2 PCI設備應用程序與驅動程序的通訊

          PCI設備應用程序的開發軟件是VC6.0,在應用程序中尋找設備是通過設備接口和設備號決定的,其實現過程主要是通過SetupDiXX系列函數得到設備接口。

          在實際應用中,PLX9056的本地配置寄存器映射在PLX9056配置寄存器中基地址寄存器0,待測試設備的內存空間由硬件設計人員映射在PLX9056的基地址寄存器2。因此,在應用程序中需定義供用戶使用的通過基地址0和基地址2的讀寫接口函數。例如:

          基本的讀函數有:

          ULONG ReadFromBase0(HANDLE handle,ULONG Offset,

          UCHAR *buff,ULONG length);

          ULONG ReadFromBase2(HANDLE handle,ULONG Offset,

          UCHAR *buff,ULONG length);

          基本的寫函數有:

          ULONG WriteToBase0(HANDLE handle,ULONG Offset,

          UCHAR *buff,ULONG length);

          ULONG WriteToBase2(HANDLE handle,ULONG Offset,

          UCHAR *buff,ULONG length);

          應用程序可以通過Win32 API DeviceIoControl操作設備與驅動程序互相通信。DeviceIoControl內部會使操作系統創建一個IRP_MJ_DEVICE_CONTROL類型的IRP,然后操作系統會將這個IRP轉發到派遣函數中。

          而以上的讀寫接口函數的本質就是調用DeviceIoControl來實現的。例如從基地址0讀函數ReadFromBase0函數原型,如圖3。

          其中,DDK定義的DeviceIoControl的函數原型為:

          BOOL DeviceIoControl{

          HANDLE hDevice,//設備句柄

          DWORD dwIoControlCode, //控制碼

          LPVOID lpInBuffer,//輸入數據緩沖區指針

          DWORD nInBufferSize, //輸入數據緩沖區長度

          LPVOID lpOutBuffer, //輸出數據緩沖區指針

          DWORD nOutBufferSize,//輸出數據緩沖區長度

          LPDWORD lpByteReturned,//輸出數據實際長度單元長度

          LPOVERLAPPED lpOverlapped //重疊操作結構指針

          };

          DeviceIoControl的第二個參數是I/O控制碼,控制碼也稱IOCTL值,是一個32位的無符號整型。DDK提供一個宏CTL_CODE,定義為:

          CTL_CODE(DeviceType,Function,Method,Access)

          其中,DeviceType為設備對象的類型;Function為驅動程序定義的IOCTL值,0x000到0x7ff為微軟保留,0x800到0xfff由程序員自己定義;Method是操作模式,其中包括METHOD_BUFFERED為使用緩沖區方式操作,METHOD_IN_DIRECT為使用直接寫方式操作,METHOD_OUT_DIRECT為使用直接讀方式操作,METHOD_NEITHER為使用其他方式操作;Access為訪問權限。

          如上述例子ReadFromBase0函數,在驅動程序中用CLT_CODE宏定義定義的IOCTL碼:

          #define IOCTL_READ_BASE_BAR0 CTL_CODE(

          FILE_DEVICE_UNKONWN,

          0x800,

          METHOD_BUFFERED,

          FILE_ANY_ACCESS)

          驅動程序中IOCTL派遣函數的實現是首先得到當前I/O堆棧,從I/O堆棧中再一次得到輸入緩沖區大小,輸出緩沖區大小,以及IOCTL。在實現過程中,運用C語言中的switch語句分別處理不同的IOCTL。在每個IOCTL情況下,就必須使用DDK提供的內核函數WRITE_REGISTER_XX系列函數和READ_REGISTER_XX系列函數操作物理設備內存。具體流程如圖4所示。

          當應用程序需要操作讀寫接口函數時,設備管理器就會發送相對應的IRP給設備驅動,驅動程序就會調用DispatchControl函數找到相應的IOCTL碼,應用程序再調用DeviceIoControl操作設備。

          4 結束語

          本文以實際應用的一個PCI設備驅動開發為例著重介紹了驅動程序和應用程序的相互關系,并且還簡單介紹了WDM式設備驅動和PCI總線協議。設備驅動程序是Windows操作系統重要的內核組建,在系統中起至關重要。如果驅動程序出錯,很容易使Windows操作系統崩潰。開發利用DDK開發驅動程序能夠使開發者加深對Windows內核和WDM規范的理解。

          參考文獻:

          [1] 張帆,史彩成.Windows驅動開發技術詳解[M].北京:電子工業出版社,2009.

          [2] Walter Oney.Programming The Microsoft Windows Driver Model[M].1999.

          篇5

          USB 協議是1994年底由康柏、IBM、英特爾等幾家公司聯合提出來的外部總線接口協議。USB就是英文中Universal Serial Bus(通用串行總線)的縮寫。USB總線具有其他總線所不具備的如:熱插拔、數據傳輸可靠、擴展方便、成本低等一系列特點,因此在嵌入式系統中被廣泛使用。

          一個USB系統一般是由一個USB主機控制器、一個或多個USB集線器和一個或多個USB設備節點組成。USB系統的物理連接具有層次性。USB總線連接USB設備和USB主機,是一種星型拓撲結構。USB的拓撲結構如圖1所示。

          在一個USB系統傳輸數據的過程中有兩個非常重要的概念,就是USB傳輸模式和USB描述符。USB傳輸模式是指USB設備傳輸數據的形式。USB設備支持四種傳輸模式:控制傳輸模式、同步傳輸模式、中斷傳輸模式和批量傳輸模式??刂苽鬏斈J绞怯脕硖幚鞺SB主端口到USB從端口的數據傳輸,主要是設備控制指令、設備查詢狀態指令和確認指令。同步傳輸模式是指傳輸和時間關系密切的信息所使用的一種傳輸方式,是一種周期的、連續的單向傳輸方式。中斷傳輸模式這類傳輸模式主要用于傳輸非周期性的、自然發生的、數據量很小的信息,這類數據傳輸的方向是從設備到主機,適用于鍵盤、鼠標、操縱桿等設備上。最后一種是批量傳輸模式,該模式適用于大量的、對時間沒有要求的數據傳輸,如U盤或者移動硬盤等設備。

          USB設備在邏輯上分為幾個層次,分別是設備層(Device)、配置層(Config)、接口層(Interface)、端點層(Endpoint)。各個層次都有與之相對的描述符,分別是設備描述符、配置描述符、接口描述符和端點描述符。

          2 Linux下的USB驅動框架

          USB設備的設備描述符在Linux系統中用usb_device_descriptor結構體表示,它描述了USB設備的一般信息。配置描述符用usb_config_descriptor結構體表示,它給出了USB設備的配置信息。接口驅動程序是在一個配置內給出一個接口信息,它在Linux中由usb_interface_descriptor結構體表示。端口描述符被主機用來決定每個端口的帶寬需求,它在Linux系統中由usb_endpoint_descriptor結構體表示。

          編寫一個USB驅動程序,是從usb_driver結構體開始的。Linux中模塊加載函數調用usb_register()和usb_unregister()從而對usb_driver結構體進行加載與卸載。如果某個設備信息與該驅動中usb_device_id usb_mouse_id_table 結構體的信息相一致,則會調用usb_driver中探測成員函數probe(),將初始化USB斷點信息,并對設備做一些初始化工作,分配urb結構體,準備數據傳輸。其urb處理大致框架結構如圖2所示。

          當鼠標設備在用戶空間打開時,將提交 probe 函數構建的 urb 請求塊,urb 將開始為傳送數據而忙碌了。urb 請求塊就像一個裝東西的“袋子”,USB 驅動程序把“空袋子”提交給 USB core,然后再交給主控制器,主控制器把數據放入這個“袋子”后再將裝滿數據的“袋子”通過 USB core 交還給 USB 驅動程序,這樣一次數據傳輸就完成了。

          3 結束語

          由于USB簡單方便快捷等優點,許多外接設備會越來越青睞USB接口,這是一種發展的趨勢。Linux系統具有開源、安全等特性,用戶也在急劇增加。屆時,會有越來越多的USB驅動加入Linux內核之中。

          參考文獻

          [1]Jonathan Corbet,Alessandro Rubini,Greg Kroah-Hartman等.LINUX設備驅動程序[M].北京:中國電力出版社,2006.

          [2]Universal Serial Bus Specification Compaq,Intel,Mi―crosoft,NEC Revision 1.1.September 23,1998.

          [3]溫卡特斯瓦蘭.精通Linux驅動程序開發[M].北京:人民郵電出版,2009.

          [4]胡曉軍,張愛成.USB接口卡發技術[M].西安:西安電子科技大學出社,2005:15-17.

          作者簡介

          篇6

          1.1 WDM模式(Windows Driver Model)

          Windows2000對驅動程序的編寫不再基于以往的Win3.x和Win9x下的VxD(虛擬設備驅動程序)結構,而是基于一種新的驅動模型——WDM(Windows Driver Model)。

          WDM為Windows98/2000/XP操作系統的設備驅動程序的設計提供了統一的框架。WDM來源于Windows NT的分層32位設備驅動程序模型(layered 32-bit device driver model)。它支持更多的特性,如即插即用(PnP)、電源管理、WMI和NT事件。

          1.2 設備驅動程序

          設備驅動程序是操作系統的一個組成部分,它由I/O管理器(I/O Manager)管理和調動。Windows2000操作系統下的I/O管理器功能描述如圖1所示。

          I/O管理器每收到一個來自用戶應用程序的請求就創建一個I/O請求包(IRP)的數據結構,并將其作為參數傳遞給驅動程序。驅動程序通過識別IRP中的物理設備對象(PDO)來區別是發送給哪一個設備。IRP結構中存放請求的類型、用戶緩沖區的首地址、用戶請求數據的長度等信息。驅動程序處理完這個請求后,在該結構中填入處理結果的有關信息,調用IoCompleteRequest將其返回給 I/O管理器,用戶應用程序的請求隨即返回。訪問硬件時,驅動程序通過調用硬件抽象層的函數實現。

              1.3 DriverStudio工具簡介

          NuMega Lab公司開發的DriverStudio是一整套開發、調試和檢測Windows平臺下設備驅動程序的工具軟件包。它把DDK(Device Development Kit)封裝成完整的C++函數庫,根據具體硬件通過向導生成框架代碼,并且提供了一套完整的調試和性能測試工具SoftICE、DriverMonitor等。

          2 應用實例

          本文利用PCI專用接口芯片PCI9052設計了一個數據傳輸控制卡??ㄉ现饕男酒蠵CI9052、FIFO(CY7C4221)、CPLD(MAX7064S)和A/D轉換器(MAX1197)。傳輸卡硬件框圖如圖2所示。面陣CCD得到的視頻信號經過調理電路,生成的視頻調理信號通過A/D轉換器進行數字化處理,送入FIFO中。在CPLD的控制下,數據經過PCI9052送入PCI總線,再傳送到計算機內存中,并顯示在監視器上。驅動程序必須實現如下幾個基本功能:(1)硬件中斷;(2)能支持應用程序獲取數據;(3)能根據外部FIFO(CY7C4221)的狀態啟動或停止突發傳輸。

          在數據輸入過程中,最重要的是對數據進行實時控制,因此需要硬件中斷。在中斷程序中,根據外部FIFO狀態完成數據的讀入。

          2.1 用DriverWizard生成驅動程序框架

          DriverStudio中的DriverWorks軟件為開發WDM程序提供了一個完整的框架。它包含一個可快速生成WDM驅動程序框架的代碼生成向導工具DriverWizard,而且還帶有許多類庫。在用DriverWizard生成的程序框架中寫入相對于設備的特定代碼,編譯后即可得到所需的驅動程序。

          在利用DriverWorks V2.7的向導Driver Wizard完成驅動程序的框架時共有11個步驟,其中關鍵步驟有:

          (1)在第四步中選中PCI,并在VendorID和DeviceID中分別輸入廠商號和設備號,還需填入PCI Subsystem ID和PCI Revision ID。這四項可以用網上的免費軟件PCITree或PCIView瀏覽PCI設備,用這兩個軟件也可以得到BAR0~BAR5的資源分配情況和中斷號。

              (2)第七步IRP隊列排隊方法,它決定了驅動程序檢查設備的方式。本設計選SystemManaged,則所有的IRP排隊都由系統(即I/O管理器)完成。

          (3)第九步是最關鍵的一步。首先在Resources中添加資源,在name中輸入變量名,在PCI Base Address中輸入0~5的序列號。0~5和BAR0~BAR5一一對應。在設置中斷對話框中,在name欄寫入中斷服務程序的名稱,選中創建中斷服務程序ISR?穴Create ISR?雪,不選創建延遲程序調用DPC(Create DPC),選中Make ISR/DPC class functions,使ISR/DPC成為設備類的成員函數。

          其次選中Buffer以選取讀寫方式,用于描述與I/O操作相關的數據緩沖區。本設計需要快速傳送大量數據,因此采用Direct I/O方式。

          (4)在第十步中,需要加入與應用程序或者其他驅動程序通信的I/O控制代碼參量。

          2.2 驅動程序模塊框圖和代碼分布

          PCI設備驅動程序模塊包括配置空間的訪問模塊、IO端口模塊、內存讀寫模塊和終端模塊等。各模塊之間是對等的。驅動程序模塊框圖如圖3所示。

          驅動程序初始化模塊代碼段放在#pragma code_seg(″INT″)和#pragma code_seg()之間。在系統初始化完成后,這部分代碼從內存中釋放,防止占用系統寶貴的內存資源。#pragma code_seg()之后是驅動程序和系統的許多模塊的實現部分。這部分在驅動程序運行后不會從內存中釋放。

          2.3 驅動程序主要模塊的實現

          (1)配置空間的訪問模塊

          DriverWorks的KPciConfiguration類封裝了訪問PCI設備配置空間的所有操作。首先初始化這個類的實例:

          KpciConfiguration PciConfig()m_Lower.TopOfStack());

          /?觹m_Lower是 KpnpLowerDevice類的對象。m_LowerTopOfStack()返回當前設備堆棧頂部的設備對象。*/

          初始化完后可以直接利用成員函數 ReadHeader/ WriteHeader函數訪問所有的配置寄存器。

          為了確定映射空間的類型和大小,先向目標基地址寄存器寫入0Xffffffffh,然后回讀該寄存器的值。如果最低位為1,表示映射于I/O空間,反之為存儲空間;如果映射于存儲空間,從第四位開始計算0的個數可以確定內存空間的大??;如果是I/O方式,從第二位開始計算0的個數可確定I/O空間的大小,最大為256字節。如果設備的存儲空間超過256字節,要實現設備的整個存儲部分的訪問,就必須采用內存映射。

          (2)I/O操作模塊

          Driverworks的KIoRange類封裝了I/O端口訪問的操作。部分代碼如下:

          {……

          KIORange DevIoPort () ;//創建實例

          NTSTATUS status= DevIoPort ().Initialize ( pResListTranslated,pResListRaW,PciConfig.BaseAddressIndexToOrdinal(0));

          /* 第一個參數為轉換后的資源列表指針;第二個參數為原始資源列表指針;第三個參數中的0為 I/O口對應的基地址,用來轉換成特定端口資源的序數?*/

          If(NT _SUCCESS(status))

          {……

          DevIoPort.inb(0,LineBuf1,10);

          /*成功初始化后可分別用KIoRange類的成員函數inb(/outb)從端口中讀/寫字節 */

          }

          else{Invalidate();return status;

          /*未能初始化成功,錯誤信息在status中*/

          {

          ……}

          (3)內存讀寫模塊

          DriverWorks的 KMemoryRange類封裝了端口訪問的操作。

          status=m_MemoryRange().Initialize(pResListTranslated,pResListRaw, PciConfig.BaseAddressIndexToOrdinal(0));

          此函數的參數、意義及具體用法與I/O端口的操作基本相同。

          內存對象也用來發送控制字,以控制CPLD的開始和停止等。實際上控制字是通過PCI9052發送的。該控制字地址已被映射成PCI的內存空間。所以定義一個指向內存空間的內存對象,通過該對象即可發送控制字。

          (4)中斷模塊

          在中斷模塊,首先要激活PCI9052中斷使能位,然后判斷硬件中斷響應是否產生,如果有,則進行突發傳輸,讀入FIFO中的數據。

          BOOLEAN TranCard::Isr_MyIrq(void)

          { if (// 中斷未產生)

          {……

          return FALSE;}

          else

          {/* 如果產生硬件中斷,設置命令寄存器,進行突發數據傳輸 */

          return TRUE;}

          }

          為了將硬件中斷與編寫的中斷服務程序連接在一起,采用InitializeAndConnect方法,部分代碼如下:

          NTSTATUS TranCardDevice?押?押OnStartDevice(KIrp I )

          {……

          status=m_MyIrq. InitializeAndConnect(

          pResListTranlated,

          LinkTo(Isr_MyIrq),

          This;)

          ……}

          2.4 驅動程序的調用

          編寫驅動程序本身不是最終目的,最終目的是調用驅動程序管理資源,并為用戶應用程序使用。驅動程序加載以后,它的許多進程處于Idle狀態,實際上需要用戶應用程序去調用激活。應用程序利用Win32 API直接調用驅動程序,實現驅動程序和應用程序的信息交互。

              首先用CreateFile()打開設備,獲得一個指向設備對象的句柄。使用CreateFile函數時應注意:由于驅動程序是*.sys,所以第一個參數應該是這個設備對象的標志連接(symbolic link)。該標志連接名有一個設置數據文件搜索路徑的數字號,而這個數字號通常是零。如果這個連接名是″TranCard″,則傳遞給CreateFile的宇符串就是:″\\\\.\\ TranCard0″。例如:

          HANDLE hDevice=CreateFile(″\\\\.\\TranCard0″)GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ, NULL?, OPEN_EXISTING,0,NULL);

          然后用 DeviceIoControl()進行數據的傳送。最后用CloseHandle( )關閉設備句柄。

          下面是應用DeviceIoControl()程序片段。

          {……

          m_b=DeviceIoControl(hDevice,TRANCARD_IOCTL_

          RECEIVE(buffer, sizeof,buffer, NULL,0,&buffersize,NULL);

          ……}

          2.5 驅動程序的調試

          篇7

          Design of USB Device Driver Based on Real Time Operation System VxWorks

          WANG Hao

          (College of Computer, Xidian University, Xi'an 710071, China)

          Abstract:The architecture of USB dirver based on VxWorks is given, general method and key technology in developing USB device dirver are analyzed.Then the device driver of LM9833 is implemented, expectant performace of target system is achieved. The general process of developing USB device dirver used in this paper can be refered by others USB device driver developing based on VxWorks.

          Key words: VxWorks; USB device driver; pipe; callback

          1 VxWorks下USB驅動概述

          VxWorks是WindRiver公司開發的具有工業領導地位的高性能實時操作系統(Real Time Operation System, RTOS)內核。VxWorks5.5實現了USB1.1協議棧。圖1提供一個VxWorks下USB主驅動棧的簡單結構。

          在棧的最低層是USB主控制器(USB Host Controller, HC),這是主系統中控制每一個USB設備的硬件。在主控制器上層是一個與硬件獨立的主控制器驅動(USB Host Controller Driver,HCD)。USBD是在HCD之上的與硬件獨立的模塊,USBD管理每一個與主機相連的設備,向高層提供可與USB設備通信的路徑,USBD實現了USB總線枚舉、總線帶寬分配、傳輸控制等操作。在棧的頂層是USB Client 模塊,一般是特定的USB Class Driver,負責管理與USB主機連接的不同類型的設備。用戶自己的USB設備驅動程序通常是在USBD這一層上完成。

          2 VxWorks下USB設備驅動詳解

          2.1 驅動程序提供的函數

          2.1.1 向應用程序提供的接口函數

          設備驅動程序的主要作用是向上層應用程序屏蔽硬件,向上層應用程序提供統一的接口函數,驅動程序一般需要實現的函數如表1所示。

          圖1 USB主驅動棧結構

          表1 驅動程序提供的接口

          usbMSCDevInit();這是一個通用的初始化例程,可以在BSP中調用,也可以由應用程序來調用,但只能被調用一次,該例程初始化必須的數據結構,并向USBD注冊驅動程序。USB設備與USB主控制器之間的所有操作都通過USBD來完成,因此在調用usbMSCDevInit()之前必須確定USBD已經初始化,在使用USB設備之前也要確保USB主控制器已經掛接到USBD。

          usbMSCDevCreate();這是一個創建設備例程,當有設備接入時,回調函數usbMSCDevAttachCallback()調用該例程創建一個邏輯設備,當這個例程被調用時必須在系統中存在一個實際的USB物理設備。

          usbMSCDevDestroy();從系統中刪除設備。首先釋放設備占有的資源,從設備鏈表中移除該設備,同時調用usbdPipeDestroy()銷毀該設備與主機之間的通信管道,最后釋放設備結構體。

          usbMSCDevShutDown();該例程卸載已注冊的設備驅動程序,并回收所有已分配資源,包括刪除設備、回收信號量等。

          2.1.2 兩個重要的回調函數

          在編寫USB設備驅動程序時,除了上述接口函數外,還需要編寫另外兩個重要的回調函數:usbMSCDevAttachCallback()和usbMSCIrpCallback()。usbMSCDevAttachCallback()用于跟蹤設備的請求實現動態接入或刪除;usbMSCIrpCallback()是一個IRP callback,當每一個IRP執行完成之后調用該回調函數,實現IRP之間同步。

          2.2 設備標識

          在VxWorks中USB設備用USBD_NODE_ID來唯一區別,它是USBD用來跟蹤一個特定設備的句柄,它與USB設備的真正USB地址無關。這表明Client并不關心設備是物理上與哪一個USB主控制器連接,應用為每個設備抽象一個Node ID,使Client可以不用考慮物理設備的連接細節以及USB地址分配。當一個Client通知有一個設備連接或斷開時,USBD經常通過Node Id來定位設備。同樣,當USB設備與USBD通信時,它必須向USBD傳遞該設備的Node Id。Node ID通常作為設備結構體的一個重要成員。

          2.3 回調(Callback)

          USB操作是嚴格遵守時序的,WindRiver USBD采用回調機制來解決時序問題。例如在USBD識別一個動態連接事件之后會激活一個動態attach callback操作,這是一個注冊到USBD的回調例程,回調函數會判斷當前的操作,如果是接入(USBD_DYNA_ATTACH),就會調用usbMSCDevCreate()來在當前的USB句柄上創建一個邏輯設備結構體;如果是移出(USBD_DYNA_REMOVE)就會調用usbMSCDevDestroy()來刪除設備。同樣,當USBD處理完成一個USB IRP之后,Client的一個IRP callback被激活,該回調例程是由Irp.userCallback域來指定。在IRP callback中釋放IRP同步信號量。

          2.4 數據傳輸

          USB設備與主機之間是通過USB管道進行通信的。一旦Client配置完一個設備,就可以利用USBD提供的管道(pipe)傳輸功能與設備進行數據交換。管道是建立在USBD Client與設備特定的endpoint之間的單向通道。調用usbdPipeCreate()函數創建一個管道后返回一個管道句柄USBD_PIPE_HANDLE,以后所有的讀寫操作都分別在各自的管道句柄上進行。管道在剛創建完后是處于終止的狀態,為了能有效使用它們,還必須用usbdFeatureClear()來清除該終止狀態。每一個管道有以下性質:USBD_NODE_ID、端點地址,管道類型、數據流方向、包的最大有效載荷量、帶寬需求等。對于塊傳輸沒有帶寬限制。VxWorks的USB驅動程序的各層驅動程序間通過IRP機制進行通信,當有數據傳輸請求發生時,上層向下傳遞IRP。USBD得到請求后,調用HCD接口,將IRP轉化為usb的傳輸。這就需要提供一個特殊的回調函數usbMSCIrpCallback(),當塊傳輸結束時調用該回調函數。以下是讀設備的具體過程。

          1) 創建設備時創建out和in管道:

          usbdPipeCreate(usbdHandle, NodeId, outEpAddress, configuration, interface, USB_XFRTYPE_BULK, USB_DIR_OUT,maxPacketSize,0,0, outPipeHandle);

          usbdPipeCreate(usbdHandle, NodeId, inEpAddress, configuration, interface, USB_XFRTYPE_BULK, USB_DIR_IN,maxPacketSize,0,0, inoutPipeHandle);

          2) 定義IRP callback:usbMSCIrpCallback(pVOID p)。

          3) 構造USB_IRP outIrp請求包。

          4) 提交outIrp:usbdTransfer (usbdHandle, outPipeHandle, &outIrp)。讀命令在outIrp.bfrList[0].pBfr域中。

          5) 等待outIrp處理結束,結束調用usbMSCIrpCallback()釋放IRP同步信號量。

          6) 構造USB_IRP inIrp請求包。

          7) 提交inIrp:usbdTransfer (usbdHandle, inPipeHandle, &inIrp)。

          8) 等待inIrp處理結束,讀取的數據在inIrp.bfrList[0].pBfr域中。

          2.5 多個設備管理

          驅動程序用LIST_HEAD 來存儲多個設備,每個接入的USB設備利用其LINK節點加入到LIST_HEAD鏈表當中;一個LINK節點包含三部分:linkFwd指針、linkBack指針和pStruct指針;其中pStruct指向一個待連接的設備結構體。當有一個設備創建完成時調用usbListLink()將該設備加入鏈表,刪除設備之前調用usbListUnlink()從鏈表中移出該設備。由于USB設備是用Node ID來唯一標識的,在查找設備的時需要利用usbListNext()來遍歷設備鏈表,直到某個設備的Node ID與特定設備的Node ID相匹配為止。在多個設備管理時,采用USBD_NODE_ID usbd_scan_id[DEVICE_NUM]數組來存放多個設備的Node ID,在對設備進行讀寫時只需提供設備的索引序號就可以直接得到設備Node ID,提高了對設備的訪問速度。

          3 VxWorks下LM9833驅動程序實現

          3.1 LM9833 USB接口簡介

          LM9833掃描儀控制器在一個單獨的IC上可以提供一個完整的USB圖像掃描控制系統。它的USB接口提供4個USB端點(Control Endpoint,Interrupt Endpoint,Bulk In Endpoint和Bulk Out Endpoint),內部有00~7F個寄存器,其中00寄存器是存放一個8bits的圖象數據,其它分別為控制或狀態寄存器。通過向bulk out端點發送四字節的讀命令可以從bulk in端點讀取這些寄存器的值,也可以向bulk out端點發送四字節的寫命令加待寫數據完成寫寄存器。四字節命令依次表示:讀寫模式(1字節)、起始地址(1字節)、讀寫長度(2字節)。其中讀寫模式bit0為0表示寫,1表示讀;bit1為0表示非增模式,為1表示增模式,即讀寫寄存器完成之后寄存器地址加1。LM9833的工作過程就是通過讀寫這些寄存器來完成的。

          3.2 設備描述符結構

          typedef struct _usbScanDev

          {

          USBD_NODE_ID scanDevId; /* USBD node ID of the device */

          UINT16 configuration; /* Configuration value */

          UINT16 interface; /* Interface number */

          UINT16 altSetting; /* Alternate setting of interface */

          UINT16 outEpAddress; /* Bulk out EP address */

          UINT16 inEpAddress; /* Bulk in EP address */

          USBD_PIPE_HANDLE outPipe; /* Pipe handle for Bulk out EP */

          USBD_PIPE_HANDLE inPipe; /* Pipe handle for Bulk in EP */

          USB_IRP inIrp; /* IRP used for bulk-in data */

          USB_IRP outIrp; /* IRP used for bulk-out data */

          USB_IRP statusIrp; /* IRP used for reading status */

          UINT8 * scanInData; /* Pointer for bulk-in data */

          UINT8 * scanOutData; /* Pointer for bulk-out data */

          BOOL connected; /* TRUE if USB_SCAN device connected*/

          LINK scanDevLink; /* Link to other SCAN devices */

          UINT8 CommandByte[4]; /* Which read/write command the device */

          UINT16 actBytes; /* actual bytes will be transfered */

          UINT8 direction; /* data transfer direction */

          } USB_SCAN_DEV, *pUSB_SCAN_DEV;

          設備描述符結構中包含了設備的一些重要信息和訪問該設備時的必須資源,如Node ID、IN/OUT管道、IN/OUT IRP等等。

          3.3 注冊設備(LM9833)驅動程序

          注冊驅動程序一般包含兩大步:與USBD建立連接和注冊attach callback。以下是注冊LM9833驅動程序的源代碼。

          #define USB_SCAN_CLASS 0xff

          #define USB_SCAN_SUB_CLASS0x00

          #define USB_SCAN_DRIVE_PROTOCOL0xff

          STATUS usbScanDevInit()

          {……

          if(usbdClientRegister ("SCAN_CLASS", &usbdHandle)!=OK||

          usbdDynamicAttachRegister (usbdHandle, USB_SCAN_CLASS, USB_SCAN_SUB_CLASS,

          USB_SCAN_DRIVE_PROTOCOL, usbScanDevAttachCallback) != OK)

          ……

          }

          usbScanDevInit()調用usbdClientRegister()向USBD注冊一個名為SCAN_CLASS的Client,同時調用usbdDynamicAttachRegister()向USBD注冊一個回調例程usbScanDevAttachCallback (),跟蹤該Client請求,當設備動態地接入或移出系統時會自動地調用該回調函數。一個Client在利用usbdDynamicAttachRegister()進行注冊時只對特定的class、subclass、protocol感興趣。在成功注冊Client后,USBD返回一個Client句柄(USBD_CLIENT_HANDLE),以后對USBD的調用都會用到這個句柄。Attach callback 如下。

          LOCAL VOID usbScanDevAttachCallback

          (

          USBD_NODE_ID nodeId,

          UINT16 attachAction,

          UINT16 configuration,

          UINT16 interface,

          UINT16 deviceClass,

          UINT16 deviceSubClass,

          UINT16 deviceProtocol

          )

          該回調函數主要響應外部設備的動作,實現USB設備的動態接入和移除。

          3.4 創建設備

          創建設備函數如下:

          LOCAL STATUS usbScanPhysDevCreate(USBD_NODE_ID nodeId, UINT16 configuration, UINT16 interface)

          當接入設備時激活usbScanDevAttachCallback()操作,回調函數會根據接入(USBD_DYNA_ATTACH)動作調用usbScanPhysDevCreate()創建一個邏輯設備,在創建設備的同時,創建設備與USB主機之間通信的管道(pipe)。管道是建立在USB設備端點(endpoint)之上,是主機與設備之間數據傳輸的單向通道。設備與主機之間數據傳輸管道是建立在批量端點(bulk endpoint)之上,有BULK_IN和BULK_OUT兩個端點,從而建立雙向的數據通路。最后將該設備加入設備鏈表,進行多個設備的管理。創建設備流程如圖2所示。

          圖2 創建設備流程

          3.5 讀寫設備

          對設備進行讀寫時,首先需要將讀寫函數轉換成設備能夠識別的命令,對于LM9833來說,需將讀寫函數轉換成LM9833所能識別的四字節讀寫命令,讀寫時將這四字節的命令置于IRP包數據域的最前端,這樣到數據到達設備時首先接收到的是四個字節的命令,LM9833會根據這四個字節的命令完成相應的功能。讀寫函數原型為:

          STATUS usbScanRead/usbScanWrite

          (

          UINT dev, /* sequence number of the device */

          UINT Addr, /* start address in register */

          UINT8 *pBuffer, /* pBuffer to receive/send data from/to device*/

          UINT Len, /* lenth of pBuffer */

          BOOL bIncrement /* incremece of address in register or not */

          )

          LM9833的一個讀寫控制流程如圖3所示,查找設備流程如圖4所示。

          圖3 LM9833讀寫控制流程

          圖4 查找設備流程

          設備命令組幀:

          const unsigned int MODE_INC_READ = 0x03;

          const unsigned int MODE_NOINC_READ = 0x01;

          const unsigned int MODE_INC_WRITE = 0x02;

          const unsigned int MODE_NOINC_WRITE = 0x00;

          switch (Cmd)

          {

          case USB_SCAN_WRITE:/* bulk out */

          pScanDev->CommandByte[0] = (bIncrement>0)? MODE_INC_WRITE : MODE_NOINC_WRITE;

          pScanDev->CommandByte[1] = Addr+((bIncrement>0)? i : 0);

          pScanDev->CommandByte[2] = (Len >> 8); /* length of the data to be written */

          pScanDev->CommandByte[3] = (Len & 0xff);

          memcpy(pScanDev->scanOutData, pScanDev->CommandByte, 4); /* 4 bytes Lm9833 command followed by write data */

          memcpy(pScanDev->scanOutData + 4, pBuffer + i, Len);

          pScanDev->actBytes = Len+4; /* actual length to be transfered*/

          pScanDev->direction = USB_SCAN_DIR_OUT;

          break;

          篇8

          windows nt的網絡體系結構是基于國際標準化(iso)制定的標準模型──開放式系統互連(open system interconnection:osi)參考模型分層建立的,這種方式有利于隨時擴展其它功能和服務。

          windows nt網絡模型開始于mac子層,網卡驅動程序就駐留在其中。它通過相關的網卡把windows nt與網絡連接起來,圖中的多個網卡表明在一臺運行windows nt的計算機上能使用多種網卡。

          這一網絡體系結構包括兩個重要接口──ndis接口與傳輸驅動

          程序接口(tdi)。這兩個接口把兩個層隔離開來,辦法是相鄰的部件只允許按單一的標準來寫,不允許多重標準。例如一個網卡驅動程序(在ndis接口的下面)就不需要特地按每個傳輸協議來寫它的代碼塊,恰恰相反,該驅動程序是寫給ndis接口的,它通過符合ndis的相應傳輸協議來請求服務。這些接口包含在windows nt的網絡體系結構中,以容納可移植、可互換的模塊。

          在兩個接口之間,是傳輸協議。它在網絡中起著組織者的作用。一個傳輸協議規定了數據以何種方式呈遞給下一個接收層,以及如何對數據相應地進行打包。它通過ndis把數據傳給網卡驅動程序,并通過tdi把數據傳給轉發程序(redirector)

          tdi之上是轉發程序,它把本地的網絡資源申請轉送給網絡。

          為了能和其他廠商的網絡互連,windows nt允許有多個轉發程序。對于每一個轉發程序windows nt計算機必須也有一個相應的供應者(provider)(由網絡廠商提供)。多供應者路由選擇程序決定適當的供應者,然后借助于供應者,對應用請求到相應的轉發程序做出選擇。windows nt支持兩種類型的網絡驅動程序

          傳輸驅動程序

          實現數據鏈路層中的邏輯鏈路控制子層協議和傳輸層協議。向 下與ndis接口,向上與tdi接口。

          網卡驅動程序

          實現對物理層的管理和數據鏈路層中介質訪問控制子層協議,通過ndis向下管理物理網卡,向上與傳輸驅動程序通信。

          §1.1.3 windows nt網卡驅動程序

          windows nt環境下的網卡驅動程序也分為兩種:

          miniport網卡驅動程序:miniport驅動程序只須實現與網絡硬件相關的操作(包括發送和接收)。而所有底層網卡驅動程序的通用操作(如同步),一般由ndis接口程序來實現。

          full網卡驅動程序:full網卡驅動程序必須實現所有硬件相關和同步、排隊等操作。例如full網卡驅動程序為了響應數據接收,需要保持本身的捆綁信息,而miniport就可以由ndis接口庫來實現。

          在windows nt的早期版本中,full網卡驅動程序要求開發者實現許多底層操作,來處理多處理器的核心問題以及處理器、線程的同步,這樣不同的開發者在大量重復著許多相同的工作。

          而miniport網卡驅動程序允許開發者僅僅寫一些與網絡硬件相關的代碼即可,而那些通用的函數由ndis接口庫來實現,這樣開發出來的驅動程序減少了不必要的工作。

          第二節miniport驅動程序的結構

          ndis接口規范了網卡驅動程序的實現,同時也對tdi驅動程序的實現提出了一定的要求,在nt中,ndis約束下的網卡驅動程序、tdi驅動程序和系統的關系如下圖所示:

          圖2.0 ndis約束下的網卡驅動程序、tdi驅動程序和系統的關系

          miniport驅動程序包括驅動程序對象、驅動程序源代碼和ndis接口庫代碼。windows nt ddk提供ndis.h作為miniport驅動程序的主要頭文件,定義了miniport驅動程序的入口點、ndis接口庫函數和通用數據結構。

          上邊緣函數的作用是網卡驅動與ndis接口庫進行通信,而下邊緣函數是tdi協議驅動程序與ndis通信的手段。ndis用一個叫做邏輯網卡的軟件對象來描述系統中的每塊網卡,而邏輯網卡與windows nt設備對象的通信由i/o子系統來管理,描述網卡的設備對象包括相關的網絡信息如名字、網絡地址和網卡內存基地址等,它還包含與硬件相關的驅動程序狀態數據(捆綁數目,捆綁句柄,包過濾數據庫等)。ndis分配一個句柄到miniportinitialize這個上邊緣函數的一個結構中,然后miniport網卡驅動程序將在以后提供這個句柄來給ndis調用,這個結構一直被ndis保持,并且對miniport驅動程序不透明。 當miniport網卡驅動程序初始化一塊網卡時,它創立自己的內部數據結構來描述網卡,記錄需要它管理的與設備相關的狀態信息。當miniport網卡驅動程序調用ndismsetatttibutes或ndismsetattributesex兩ndis庫函數時,它傳遞一個句柄給這數據結構。這樣,當調用miniport驅動程序入口點時,它就傳遞這個句柄來驗證驅動程序所對應的網卡的正確性。這個數據結構為miniport網卡驅動程序所擁有并維護。miniport nic驅動程序還需要維護一組對象,這些對象是系統定義的對象標識符(object idetifier:oid)來標識,以描述驅動程序的性能和當前狀態信息。為查詢這些信息,上層驅動程序調用ndisrequest向ndis接口庫指示oid。oid表示了調用所需的信息類型,如miniport驅動程序所支持的lookahead緩沖區大小等。ndis接到上層驅動程序的查詢請求,將oid傳遞給上邊緣函數miniportqueryinformation實現對oid的查詢,如果上層驅動程序請求改變狀態信息則調用miniportsetinformation實現對oid的設置。典型的miniport nic驅動程序必須有一些函數來通過ndis接口實現上層驅動程序與硬件的通信。這些函數稱為上邊緣服務函數。

          這些上邊緣服務函數由驅動程序的開發者根據驅動程序面向的特定低層網絡類型和硬件以及相應環境,可以有選擇地實現,但必須保證驅動程序最基本的功能,這些基本功能包括初始化、發送、中斷處理、重置、參數查詢與設置和報文接收。

          miniportinitialize:操作系統根據系統配置信息,檢測出網卡已安裝時,由ndis接口在初始化時調用,主要完成低層網絡類型確定,對應于物理網卡的邏輯網卡初始化,中斷信息注冊,網卡與主機通訊方式的確認。i/o端口的申請與注冊,內存映像,mib的初始化,物理網卡的驗證與初始化等。

          miniportreconfigure:支持網卡參數動態變化,和miniportinitilize一樣由ndis接口以初始化級別調度執行(不能屏蔽中斷,必須由驅動程序承認并清除在此期間產生的中斷),支持即插即用和軟配置的網卡在動態改變參數時,必須提供此函數。

          miniportqueryinformation:查詢網卡的狀態以及網卡驅動程序的操作或統計參數,如是否支持組通訊、網卡的物理速率是否支持回環、是否支持直接拷貝等,這些參數以oid方式統一管理。

          miniportsetinformation:ndis接口或協議驅動程序通過調用此接口改變驅動程序維護的oid庫,一些操作參數的改變也將同時改變驅動程序狀態,例如組地址的設置。

          miniportreset:包括網卡硬件重置和驅動程序軟件重置,軟件重置包括驅動程序狀態重置,以及一些相關的參數重置,還需考慮有些參數的恢復,重置時不必完成所有正在活躍的外部請求,但必須釋放已占用的外部資源。

          miniporthalt:掛起網卡并釋放該網卡驅動程序占用的所有資源,在此期間不屏蔽中斷。

          miniportisr:高優先級的中斷處理程序,進行的工作包括初始中斷處理類型,決定是否進行中斷轉交,對卡上中斷進行處理 等,該服務類型只在以下情況被調用:

          ndis接口調用miniportinitialize和miniporthalt兩函數時。

          .中斷處理類型設為每此中斷處理過程都調用時。

          為使系統能及時響應所有硬件中斷,高優先級的硬件中斷處理程序應盡可能的減少運行時間,防止長時間的屏蔽低優先級中斷,避免造程中斷丟失。

          miniporthandleinterrupt:由中斷延時處理程序在中斷延時處理時進行調用。ndis排隊所有的延時處理,該服務主要處理發送完成、報文接收、描述符用盡、溢出、網卡異常等中斷。

          miniportsend:ndis收到上層發送請求時經過若干協議處理再向下調用此服務過程,發送的packet已含有llc和mac頭,該服務過程進行邊界對齊、packet約束重整、描述符映射和報文發送、以及發送資源和packet緩沖隊列管理。

          miniporttransferdata:多個已和網卡捆綁的協議驅動程序在接收到報文到達指示后,向網卡驅動程序發出傳送請求以拷貝各自所需的報文數據部分,網卡驅動程序根據各協議驅動程序對單個packet是否進行多次拷貝,以決定是否暫存只允許單次拷貝的packet等。

          miniportcheckhandle:ndis每秒調用此服務函數一次,驅動程序發現網卡異常時報告給ndis由ndis調用miniportreset進行硬件重恢復。

          miniportenableintrrupt:中斷使能。

          miniportdisableinterrupt:中斷屏蔽。

          另外,每個網卡驅動程序必須有一個初始化入口點,由driver entry函數實現,它和系統相關,由操作系統在裝入驅動程序時調用,主要完成初始化ndis wrapper,再由wrapper初始生成驅動程序管理塊并完成相應各種初始化工作,登錄網卡驅動程序所有上邊緣服務入口點,同時寫入ndis版本信息。ndis接口庫包括在ndis.sys中,它是一個核態函數庫,有一套抽象的函數,無論協議驅動程序還是nic驅動程序都連接到這個庫中,以實現上下層之間的操作。

          第二章fddi網卡驅動程序的加載和運行

          第一節 網卡驅動程序的安裝

          windows nt網卡驅動程序安裝的目的是實現網卡相應硬件信息和驅動程序在windows nt注冊庫中的注冊,使windows nt能夠正確識別網卡,了解所必需的軟硬件信息并能在windows nt啟動時加載相應驅動程序。

          網卡驅動程序安裝時,首先在主群組的控制面板中選擇“網絡”,然后添加網卡,指定相應信息文件──oemsetup.inf的路徑,以完成以下兩個必要的操作:

          復制驅動程序到相應的系統目錄(windows nt根目錄system32drivers)中;

          在windows nt注冊庫中存入相應軟硬件信息。

          下面主要以fddi網卡為例介紹安裝驅動程序所必需的工作:

          §2.1.1網卡一般硬件參數

          對于fddi網卡,必須在編寫其oemsetup.inf文件時確定以下硬件參數:

          總線類型:pci(5)……括號中的數字5表示pci總線在ndis中的總線類型代碼;

          廠商代號:0x5588……系統加載時確定網卡的標記,也是編程時確定pci槽號的標識;

          cfid: 0x01;

          介質類型:光纖(3) ……括號中的數字表示光纖在ndis中的介質類型代碼;

          是否支持全雙工:支持。

          對于其它的硬件信息在此inf配置信息文件中可有可無,如若配置,則可在驅動程序的編寫時利用這些信息,方便編程,同時有利于其它應用對其參數的確定和使用。網卡驅動程序的安裝通常將創建登錄表中的四個不同子鍵:

          software registrion鍵,對應于驅動程序,存在于hkey_local_machinesoftwarecompany productnameversion中。我們的fddi網卡驅動程序所對應的是hkey_local_machinesoftwarenet612yhfddiyhfddi1.0;

          網卡的軟件登錄鍵,存在于hkey_local_machinesoftwaremicrosoft windows ntnt3.51networkcardsyhfddi1;

          驅動程序的服務登錄鍵,存在于hkey_local_machinesystemcurrentcontrolsetservices

          網卡的服務登錄鍵,存在于hkey_local_machinesystemcurrentcontrolsetservices

          對于每一個網絡部件,一個名為netrules的特殊子鍵在鄰近的驅動程序或網卡登錄子鍵里創建,netrules標識網絡部件為網絡整體的一部分。

          fddi網卡驅動程序對應的標準軟件登錄表項將出現在以下路徑:

          hkey_local_machinesoftwarenet612yhfddiyhfddi1.0;

          驅動程序對應的標準項的值為:

          description =yhfddi/pci adapter controller

          install date =……

          ……

          refcount =0x01

          servicename =yhfddi

          softwaretype =driver

          title =yhfddi/pci adapter controller

          而且在yhfddi驅動程序相關的netrules子鍵下,這些值項為:

          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網卡在如下路徑的networkcards子鍵里介紹:

          hkey_local_machinesoftwaremicrosoft

          windows ntnt3.51networkcardsyhfddi1;

          網卡的標準項包括以下這些值:

          description =yhfddi/pci adapter controller

          install date =……

          manufacturer =net612

          productname =yhfddi

          servicename =yhfddi01

          title =[01]yhfddi/pci adapter controller

          §2.1.3編寫inf信息配置文件

          gui inf描述語言被windows nt用以書寫系統所有部件的配置文件,當然也可以用以書寫網絡系統各部件的配置文件,該配置文件描述了網絡部件安裝、配置、刪除的執行過程。當網絡部件進行初始安裝或二次安裝(通常通過ncpa進行)時,安裝程序讀取部件對應的配置文件,進行解釋執行。gui inf描述語言由節、命令、邏輯操作、變量規范、流程控制以及一套調用dll或外部程序的機制組成,其中,節是配置文件的主體,節可分為install節(類似于函數),shell節(也類似于函數,但可調用insall和shell節),detect節(不包含命令),一個配置文件一般由若干不同類型的節組成。驅動程序的開發者根據需要可以在配置文件中編寫相應代碼,使得用戶和系統之間能進行交互,并且由用戶決定一些配置參數。

          nt網卡配置文件有其一套規范,驅動程序開發者必須按規范編寫配置文件,一般來說,一個配置文件至少應該提供下面三個節:

          安裝入口點:[identify]shell節。該節主要功能是給出安裝部件的類型名,系統通過它識別該部件屬于哪一大類(display,mouse,scsi,network等)中的哪一類(網絡adapter,driver,transport,service,network和netprovidor),同時,還需要給出映像文件和配置文件所在的源介質及標識。

          [returnoption]shell節。系統執行安裝identify節后,執行該節。它主要功能是檢查所需安裝的部件是否支持的硬件平臺和語言,并給出網卡名(有些配置文件支持多類網卡,此時必須讓用戶進行選擇,并獲得選擇結果)。

          [installoption]shell節。該節是配置文件得主體,也是上次安裝完后再次進行配置、刪除、更新的入口點。主要功能是拷貝映像文件和配置文件,生成配置的各種選項,創建該部件在注冊庫中對應的各種登錄子樹并更新重寫。

          第二節 驅動程序的加載過程

          篇9

          1WDM模式驅動程序

          1.1WDM模式(WindowsDriverModel)

          Windows2000對驅動程序的編寫不再基于以往的Win3.x和Win9x下的VxD(虛擬設備驅動程序)結構,而是基于一種新的驅動模型——WDM(WindowsDriverModel)。

          WDM為Windows98/2000/XP操作系統的設備驅動程序的設計提供了統一的框架。WDM來源于WindowsNT的分層32位設備驅動程序模型(layered32-bitdevicedrivermodel)。它支持更多的特性,如即插即用(PnP)、電源管理、WMI和NT事件。

          1.2設備驅動程序

          設備驅動程序是操作系統的一個組成部分,它由I/O管理器(I/OManager)管理和調動。Windows2000操作系統下的I/O管理器功能描述如圖1所示。

          I/O管理器每收到一個來自用戶應用程序的請求就創建一個I/O請求包(IRP)的數據結構,并將其作為參數傳遞給驅動程序。驅動程序通過識別IRP中的物理設備對象(PDO)來區別是發送給哪一個設備。IRP結構中存放請求的類型、用戶緩沖區的首地址、用戶請求數據的長度等信息。驅動程序處理完這個請求后,在該結構中填入處理結果的有關信息,調用IoCompleteRequest將其返回給I/O管理器,用戶應用程序的請求隨即返回。訪問硬件時,驅動程序通過調用硬件抽象層的函數實現。

          1.3DriverStudio工具簡介

          NuMegaLab公司開發的DriverStudio是一整套開發、調試和檢測Windows平臺下設備驅動程序的工具軟件包。它把DDK(DeviceDevelopmentKit)封裝成完整的C++函數庫,根據具體硬件通過向導生成框架代碼,并且提供了一套完整的調試和性能測試工具SoftICE、DriverMonitor等。

          2應用實例

          本文利用PCI專用接口芯片PCI9052設計了一個數據傳輸控制卡??ㄉ现饕男酒蠵CI9052、FIFO(CY7C4221)、CPLD(MAX7064S)和A/D轉換器(MAX1197)。傳輸卡硬件框圖如圖2所示。面陣CCD得到的視頻信號經過調理電路,生成的視頻調理信號通過A/D轉換器進行數字化處理,送入FIFO中。在CPLD的控制下,數據經過PCI9052送入PCI總線,再傳送到計算機內存中,并顯示在監視器上。驅動程序必須實現如下幾個基本功能:(1)硬件中斷;(2)能支持應用程序獲取數據;(3)能根據外部FIFO(CY7C4221)的狀態啟動或停止突發傳輸。

          在數據輸入過程中,最重要的是對數據進行實時控制,因此需要硬件中斷。在中斷程序中,根據外部FIFO狀態完成數據的讀入。

          2.1用DriverWizard生成驅動程序框架

          DriverStudio中的DriverWorks軟件為開發WDM程序提供了一個完整的框架。它包含一個可快速生成WDM驅動程序框架的代碼生成向導工具DriverWizard,而且還帶有許多類庫。在用DriverWizard生成的程序框架中寫入相對于設備的特定代碼,編譯后即可得到所需的驅動程序。

          在利用DriverWorksV2.7的向導DriverWizard完成驅動程序的框架時共有11個步驟,其中關鍵步驟有:

          (1)在第四步中選中PCI,并在VendorID和DeviceID中分別輸入廠商號和設備號,還需填入PCISubsystemID和PCIRevisionID。這四項可以用網上的免費軟件PCITree或PCIView瀏覽PCI設備,用這兩個軟件也可以得到BAR0~BAR5的資源分配情況和中斷號。

          (2)第七步IRP隊列排隊方法,它決定了驅動程序檢查設備的方式。本設計選SystemManaged,則所有的IRP排隊都由系統(即I/O管理器)完成。

          (3)第九步是最關鍵的一步。首先在Resources中添加資源,在name中輸入變量名,在PCIBaseAddress中輸入0~5的序列號。0~5和BAR0~BAR5一一對應。在設置中斷對話框中,在name欄寫入中斷服務程序的名稱,選中創建中斷服務程序ISR?穴CreateISR?雪,不選創建延遲程序調用DPC(CreateDPC),選中MakeISR/DPCclassfunctions,使ISR/DPC成為設備類的成員函數。

          其次選中Buffer以選取讀寫方式,用于描述與I/O操作相關的數據緩沖區。本設計需要快速傳送大量數據,因此采用DirectI/O方式。

          (4)在第十步中,需要加入與應用程序或者其他驅動程序通信的I/O控制代碼參量。

          2.2驅動程序模塊框圖和代碼分布

          PCI設備驅動程序模塊包括配置空間的訪問模塊、IO端口模塊、內存讀寫模塊和終端模塊等。各模塊之間是對等的。驅動程序模塊框圖如圖3所示。

          驅動程序初始化模塊代碼段放在#pragmacode_seg(″INT″)和#pragmacode_seg()之間。在系統初始化完成后,這部分代碼從內存中釋放,防止占用系統寶貴的內存資源。#pragmacode_seg()之后是驅動程序和系統的許多模塊的實現部分。這部分在驅動程序運行后不會從內存中釋放。

          2.3驅動程序主要模塊的實現

          (1)配置空間的訪問模塊

          DriverWorks的KPciConfiguration類封裝了訪問PCI設備配置空間的所有操作。首先初始化這個類的實例:

          KpciConfigurationPciConfig()m_Lower.TopOfStack());

          /?觹m_Lower是KpnpLowerDevice類的對象。m_LowerTopOfStack()返回當前設備堆棧頂部的設備對象。*/

          初始化完后可以直接利用成員函數ReadHeader/WriteHeader函數訪問所有的配置寄存器。

          為了確定映射空間的類型和大小,先向目標基地址寄存器寫入0Xffffffffh,然后回讀該寄存器的值。如果最低位為1,表示映射于I/O空間,反之為存儲空間;如果映射于存儲空間,從第四位開始計算0的個數可以確定內存空間的大小;如果是I/O方式,從第二位開始計算0的個數可確定I/O空間的大小,最大為256字節。如果設備的存儲空間超過256字節,要實現設備的整個存儲部分的訪問,就必須采用內存映射。

          (2)I/O操作模塊

          Driverworks的KIoRange類封裝了I/O端口訪問的操作。部分代碼如下:

          {……

          KIORangeDevIoPort();//創建實例

          NTSTATUSstatus=DevIoPort().Initialize(pResListTranslated,pResListRaW,PciConfig.BaseAddressIndexToOrdinal(0));

          /*第一個參數為轉換后的資源列表指針;第二個參數為原始資源列表指針;第三個參數中的0為I/O口對應的基地址,用來轉換成特定端口資源的序數?*/

          If(NT_SUCCESS(status))

          {……

          DevIoPort.inb(0,LineBuf1,10);

          /*成功初始化后可分別用KIoRange類的成員函數inb(/outb)從端口中讀/寫字節*/

          }

          else{Invalidate();returnstatus;

          /*未能初始化成功,錯誤信息在status中*/

          {

          ……}

          (3)內存讀寫模塊

          DriverWorks的KMemoryRange類封裝了端口訪問的操作。

          status=m_MemoryRange().Initialize(pResListTranslated,pResListRaw,PciConfig.BaseAddressIndexToOrdinal(0));

          此函數的參數、意義及具體用法與I/O端口的操作基本相同。

          內存對象也用來發送控制字,以控制CPLD的開始和停止等。實際上控制字是通過PCI9052發送的。該控制字地址已被映射成PCI的內存空間。所以定義一個指向內存空間的內存對象,通過該對象即可發送控制字。

          (4)中斷模塊

          在中斷模塊,首先要激活PCI9052中斷使能位,然后判斷硬件中斷響應是否產生,如果有,則進行突發傳輸,讀入FIFO中的數據。

          BOOLEANTranCard::Isr_MyIrq(void)

          {if(//中斷未產生)

          {……

          returnFALSE;}

          else

          {/*如果產生硬件中斷,設置命令寄存器,進行突發數據傳輸*/

          returnTRUE;}

          }

          為了將硬件中斷與編寫的中斷服務程序連接在一起,采用InitializeAndConnect方法,部分代碼如下:

          NTSTATUSTranCardDevice?押?押OnStartDevice(KIrpI)

          {……

          status=m_MyIrq.InitializeAndConnect(

          pResListTranlated,

          LinkTo(Isr_MyIrq),

          This;)

          ……}

          2.4驅動程序的調用

          編寫驅動程序本身不是最終目的,最終目的是調用驅動程序管理資源,并為用戶應用程序使用。驅動程序加載以后,它的許多進程處于Idle狀態,實際上需要用戶應用程序去調用激活。應用程序利用Win32API直接調用驅動程序,實現驅動程序和應用程序的信息交互。

          首先用CreateFile()打開設備,獲得一個指向設備對象的句柄。使用CreateFile函數時應注意:由于驅動程序是*.sys,所以第一個參數應該是這個設備對象的標志連接(symboliclink)。該標志連接名有一個設置數據文件搜索路徑的數字號,而這個數字號通常是零。如果這個連接名是″TranCard″,則傳遞給CreateFile的宇符串就是:″\\\\.\\TranCard0″。例如:

          HANDLEhDevice=CreateFile(″\\\\.\\TranCard0″)GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL?,OPEN_EXISTING,0,NULL);

          然后用DeviceIoControl()進行數據的傳送。最后用CloseHandle()關閉設備句柄。

          下面是應用DeviceIoControl()程序片段。

          {……

          m_b=DeviceIoControl(hDevice,TRANCARD_IOCTL_

          RECEIVE(buffer,sizeof,buffer,NULL,0,&buffersize,NULL);

          ……}

          2.5驅動程序的調試

          篇10

          引 言

          VxWorks操作系統是美國WindRiver公司于1983年設計開發的一種嵌入式實時操作系統(RTOS),是嵌入式開發環境的關鍵組成部分。良好的持續發展能力、高性能的內核以及友好的用戶開發環境,在嵌入式實時操作系統領域占據一席之地。它以其良好的可靠性和卓越的實時性被廣泛地應用在通信、軍事、航空、航天等高精尖技術及實時性要求極高的領域中,如衛星通訊、軍事演習、彈道制導、飛機導航等。

          1 嵌入式系統

          嵌入式系統是以嵌入式計算機為技術核心,面向用戶、面向產品、面向應用,軟硬件可裁減的,適用于對功能、可靠性、成本、體積、功耗等綜合性嚴格要求的專用計算機系統。和通用計算機不同,嵌入式系統是針對具體應用的專用系統,目的就是要把一切變得更簡單、更方便、更普遍、更適用;它的硬件和軟件都必須高效率地設計,量體裁衣、去除冗余,力爭在同樣的硅片面積上實現更高的性能。

          嵌入式系統主要由嵌入式處理器、外圍硬件設備、嵌入式操作系統以及特定的應用程序等四部分組成,是集軟硬件于一體的可獨立工作的“器件”;用于實現對其它設備的控制、監視或管理等功能。

          嵌入式系統應具有的特點是:要求高可靠性;在惡劣的環境或突然斷電的情況下,要求系統仍然能夠正常工作;許多嵌入式應用要求實時處理能力,這就要求嵌入式操作系統(EOS)具有實時處理能力;嵌入式系統中的軟件代碼要求高質量、高可靠性,一般都固化在只讀存儲器中或閃存中,也就是說軟件要求固態化存儲,而不是存儲在磁盤等載體中。

          2 設備驅動程序

          Vxworks5.4中驅動程序主要分為三種:字符、塊以及網絡驅動程序。本文所介紹的網卡驅動程序則屬于網絡設備驅動程序。

          2.1 網絡設備驅動程序設計

          網絡的各功能部件圖1所示,網絡設備驅動程序實際上是處理硬件和上層協議之間的接口程序。網絡傳輸協議層分發數據在應用程序接口和網絡接口之間。網絡化網絡協議(如IP協議)發送數據在網絡主機之間。連接/接口層使能主機隸屬于硬件到相同物理媒質的通信。

          在Vxworks5.4中,網卡驅動程序又分為END(Enhanced Network Driver)和BSD兩種。它們分別處于如圖2所示結構中。

          2.1.1 BSD驅動程序設計

          在Vxworks5.4中,網絡驅動程序都是基于BSD UNIX版本4.3基礎上的,這些驅動程序都定義在一個全局例程中,那就是attach子程序,xxattach( )子程序中包含5個函數指針,它們都被映射到ifnet結構中,這5個函數可見表1,它們在IP協議層任何地方被調用。

          表1 網絡接口處理

          驅動程序入口xxattach( )調用ether_attach( )來把上述5個函數映射到ifnet結構中,ether_attach( )調用如下:

          ether_attach(

          (IFNET *) & pDrvCtrl->idr,

          unit,

          "xx",

          (FUNCPTR) NULL,

          (FUNCPTR) xxIoctl,

          (FUNCPTR) ether_output( ), /* generic ether_output */

          (FUNCPTR) xxReset

          );

          pDrvCtrl->idr.ac_if.if_start = (FUNCPTR)xxTxStartup;

          上述參數中,需要一個接口數據記錄(Interface Data Record (idr)),unit號和設備名,下面四個參數就是相關驅動程序的函數指針。第一個函數指針指的是init( )例程,這個例程可要可不要,第二個函數指針指的是ioctl( )接口,它允許上層來控制設備狀態;第三個函數指針指的是把數據包送到物理層;最后一個函數指針指的是如果TCP/IP堆棧決定需要復位的話,它就復位這個設備。

          接著下面那一句代碼表示添加數據傳輸例程到IDR,ether_output( )例程被調用后,傳輸開始例程就被TCP/IP協議堆棧調用。

          篇11

          1 引言

          計算機軟件技術的發展日新月異,給高等院校相關專業的教學帶來了很大的挑戰,為了更好地適應不斷變化的社會就業需求,就必須在傳統的計算機專業教學模式的基礎上開辟出一條新路。

          在這樣的背景下,樂山師范學院計算機科學學院早在2005年就開始開展校企合作辦學,與企業聯合培養校企合作方向的學生,至今已是第八屆。相比普通班,校企合作教改班所開設的專業課程更符合于當前計算機人才市場的需求,典型的特點就是注重對學生的專業技能尤其是程序設計和軟件開發能力的系統性培養,嚴格按照軟件工程師的培養模式來開展相關的理論和實踐教學環節,這在很大程度上改變了以往只注重專業理論教學的局限性。

          在對近幾年教改學生的就業情況進行分析以后,明確肯定了校企合作教學模式為我院本科人才培養體系的改革起到了決定性的促進作用,學生的專業技能有了明顯的增強,也大大提高了畢業生的就業率。

          但與此同時也認識到存在的一些問題:首先,傳統的以程序設計語言語法描述為主線的教學方式,以及模式化的實驗內容,使教師在教學過程中容易將重點偏向理論,降低了對學生實踐能力的鍛煉和考核;其次,我們的軟件工程師主要是在教室和機房這樣的環境下培養出來的,缺乏真刀真槍的實踐鍛煉機會;最后,雖然校企合作人才培養方案的整體實施效果不錯,但也很難培養出高層次的計算機專業人才。

          如果以上幾點不能有效地解決,那么校企合作辦學的成效和前景將受到限制,因此迫切地需要一種途徑去驅動程序設計類專業課程的教學模式改革,經過長期、反復的思考和摸索,我們認為通過開展學科專業競賽活動來推動課程教學改革是比較可行的。而在種類繁多的計算機學科專業競賽中,最權威、級別最高的就是《ACM/ICPC國際大學生程序設計競賽》。

          本教改項目結合ACM競賽來促進計算機專業教學體系特別是程序設計類課程的教學改革,教改實施對象主要為計算機科學學院軟件工程專業方向的學生。首先針對程序設計類課程教學存在的問題以及問題產生的原因進行分析,然后在ACM競賽模式和特點的基礎上,嘗試通過結合ACM競賽來改革課程開設體系和課程教學模式,最后提出了解決問題的具體措施,并在實際教學應用中取得了一定的成效。

          2 當前程序設計類課程教學存在的問題

          2.1 人才培養模式陳舊,實踐教學比例不足

          在傳統的被動教學模式中,學生缺乏學習主動性、創新性和行業競爭力。而計算機專業課程大多屬于實踐型課程,強調動手能力。為了加深對理論知識的理解,必須提高實踐教學質量,理論和實踐教學的學時分配要作適當調整。

          2.2 實踐內容模板化,缺乏創新能力的培養

          首先,設計性、綜合性實驗偏少,很難培養學生的創造性思維;其次,實驗內容嚴重脫離了現代軟件工程過程,更談不上對綜合型應用問題的解決;最后,在實踐教學過程中,教師干預太多,學生處于被動完成實驗任務的角色。

          2.3 缺乏互助學習能力,團隊協作意識較差

          當前軟件項目的開發都是以團隊形式實施的,團隊成員之間需要合理分工和無障礙溝通。但在傳統教學模式中,以項目組為單位來開展教學活動的機會非常少,更談不上互助學習和團隊協作了。

          2.4 課程考核模式單一,缺乏激勵機制

          課程考核主要采用傳統考核模式,考核內容受限于教材知識點,缺乏對學生知識結構與實踐技能的綜合考察,不利于學生綜合實踐能力和創新能力的培養,最終形成“高分低能”的現象。

          3 改革措施

          本教改項目主要通過以下幾個方面來實施以ACM競賽促進程序設計類課程教學改革的方案。

          3.1 改革課程開設計劃

          全面分析了目前程序設計類專業課程教學中存在的一些問題(比如教法和學法等方面),結合ACM的競賽大綱和競賽模式來調整開課計劃,把原計劃一學期的《程序設計基礎》課程的教學時間調整為一學年,第一學期是程序設計的入門教學,主要介紹高級程序設計語言編程基礎;第二學期是程序設計的進階教學,主要介紹算法設計與分析。

          3.2 改革課程實踐教學模式[1]

          (1)實驗內容分級化:

          將實驗內容分成知識型(單一算法)、應用型(算法和實際問題結合)和綜合型(若干小算法的綜合,用于解決一個較大規模的問題)。不同級別題型的權值不同,每一級別中又包含若干個相同權值的題目,學生可以根據自身情況選擇不同級別的題型和題目數量,這樣既考慮到了不同層次學生的學習需求,又達到了統一的實驗目的。

          (2)實驗題目趣味化:

          傳統的程序設計類實驗題目普遍比較枯燥,難以調動學生的學習興趣和設計思路。參考ACM的海量題集,由任課教師將實驗題目生活化和趣味化,使學生自主選擇合理的數據結構和算法來解題,這樣可以充分激發學生的學習主動性和積極性,將被動學習轉化為主動學習,更好地達到了實踐教學的目的。

          (3)實驗時間分散化:

          考慮到實驗課時非常有限,可參照ACM競賽平臺來構建“程序設計在線評測系統”,功能包括用戶管理、題庫管理、在線提交、在線排名、在線討論等。學生注冊后可在任何時間登陸該系統進行選題、提交、評測和討論等自主學習環節,將有限的課內練習時間延續到課外。

          3.3 開發資源網站

          在全面搜集ACM競賽相關資源的前提下,以程序員協會的學生會員為主力設計并開發了“ACM資源網站”,并掛靠在學院的Web服務器上,以該資源網為平臺來開展競賽的宣傳、組織、培訓等活動,同時也為相關課程的理論實踐教學和學生自主學習提供了一個優質的信息化平臺。

          3.4 建設學生梯隊

          依托于樂山師范學院第二課堂課程《ACM程序設計》的開設,以樂山師范學院三星級社團“程序員協會”為活動主體,在全校范圍內吸納對計算機編程和競賽感興趣的學生,成立“ACM競賽興趣小組”,通過舉辦專業講座、學生科研、協會內部競賽、協會沙龍等活動,為本專業學生提供一個進一步增強職業技能的交流和學習平臺,同時也要在興趣小組中發現適合參加ACM競賽的后備人才,面向各年級構建ACM競賽梯隊。

          3.5 建立激勵機制

          增設創新學分,設置創新環節,搭建創新實踐的平臺,讓學生有更多的機會展示自己的專業特長。將參加ACM等學科競賽納入學生的綜合測評,通過設立競賽獎學金制度來引導學生積極參加課外科技活動、不斷提高自身的創新素質。

          3.6 組織參賽

          在本教改項目的實施過程中,還要積極組織學生參加各個級別的ACM賽事。對于每一次競賽,首先成立競賽領導小組,分析官方公布的競賽大綱,及時、準確地改革專業教學體系目標和課程開設計劃;其次根據往屆參賽經驗,結合本次競賽的具體情況制定出競賽活動方案,將競賽的宣傳、組織、選拔、培訓、參賽、獎勵等環節制度化;然后選拔ACM參賽隊伍,指派經驗豐富且取得過優異成績的教練對參賽隊員進行長期、深入、全方位的強化培訓和指導;最后通過對競賽成績的分析再次調整專業課程開設計劃和教學模式。[2]

          3.7 改革考核手段

          ACM模式的重要特色之一是完善而嚴謹的考核機制,所以我們大膽嘗試將ACM的考核方式借鑒到程序設計類課程的考核環節中,采用ACM模式的黑箱測試,將學生在“程序設計在線評測系統”中獲得的成績以50%的權重加入到課程考核指標當中。這一方面減少了教師的工作量,降低了考核錯誤率,另一方面做到了客觀、公正,更好地發掘了學生的創新能力,提高其對知識點的掌握程度。

          4 要解決的關鍵問題

          4.1 課程教學形式的改革,特別是如何處理實踐教學和理論教學的比重關系,以及如何讓學生能夠真正地解決問題,而不是按照設定好的思路去模仿著解決問題。

          4.2 課程評價體系的改革,尤其是目前的實踐環節評價機制弊端明顯,嚴重束縛了學生的創新能力,錯誤地引導學生把自己改造為一個受制于理論教材的傀儡。

          4.3 差異化教學,考慮到ACM競賽的難度較大,所以必須考慮到在將ACM融入到專業課程教學過程之后,如何確保整體教學質量并解決好部分學生學習能力較差的問題。

          4.4 在ACM競賽中取得更好的成績,必須建立有效的組織、選拔、培訓、參賽、總結等相關機制。

          5 結語

          ACM競賽對程序設計類專業課程的教學改革起到了積極的推動作用,從教學隊伍建設的角度來看,它在提高教師的教學水平、科研能力、促進專業的對外交流等方面都起到了重要的作用;從學生培養的角度來看,它在提高學生的學習興趣、自學能力、創新能力、求真務實的科學態度上有很大的幫助。

          總之,通過合理的應用ACM競賽這個平臺,可以使我們的計算機專業教學更趨科學化、規范化,可以讓我們的學生開拓視野,促進實踐型、創新型人才的培養,提高學生的就業競爭力。

          參考文獻:

          [1]常子楠.基于ACM模式的程序設計類課程實踐教學探索[J].計算機教育,2010(16):144-146.

          [2]項煒.以學科競賽促進計算機專業教學改革的探索[J].改革與開放,2009(12):207.

          篇12

          1.1 Linux操作系統

          Linux是一套可以免費使用和自由傳播的類UNIX操作系統,其實際上只是一個操作系統的內核,主要用于Intel x86系列CPU的計算機上[ ]。

          談及Linux的起源,其靈感源自于UNIX。UNIX操作系統于1969年由Bell實驗室設計開發,之后Linus Torvalds設計了Linux,該系統在發展初期就得到了廣大程序員的幫助,逐步發展成為現今這樣一個擁有自己版權的完整的系統。

          Linux具有很多特點,如支持多種體系結構,支持大量的設備,具有完善的網絡功能,開放源代碼,軟件資源豐富,內核穩定等,可總結為以下幾點:

          (1)強大的編程能力[ ]。由于Linux源自于世界各地成千上萬的程序員和黑客,使得Linux就猶如加入到了一個高手如云的編程組織中,同時,由于GPL的存在,Linux開放源碼,吸引更多專業人士的加入,在這種需求的刺激下,Linux提供的開發工具功能也越來越完善,越來越強大。

          (2)完善的組網能力。Linux具有強大的組網能力,它對當前的TCP/IP協議[ ]提供了完全的支持,同時也支持下一代Internet協議IPv6。在安全性方面,Linux內核中包括了IP防火墻代碼、IP防偽及IP服務質量控制等特性。現階段,Linux廣泛用于服務器,其可以作為Windows客戶機的打印和文件服務器,也可用做NT的文件和打印服務器,甚至可作為Macintosh客戶機的文件和打印服務器。另外,Linux還包括了一個Ftp服務器、一個電子郵件傳輸程序以及POP和IMAP郵件服務程序。

          (3)Linux是自由開放的。Linux是自由軟件,允許成千上萬的人檢查軟件,修改軟件,最終可以按照用戶自己的意愿來定義自由軟件,可以定制自己的Linux。

          (4)系統穩定。Linux提供了完全的內存保護機制,每個進程都運行在各自的虛擬地址空間中,不會損壞進程或內核使用的地址空間。一臺運行Linux的機器啟動一次可以運行數個月。在安全性的較量上,Linux明顯比Windows98和NT占上風。據統計分析,Linux是目前最安全的操作系統。

          1.2 嵌入式系統

          最早期的8位/16位系統,大多都是沒有操作系統的,然而在進入32位時代之后,系統軟件變得越來越復雜,出現了控制能力不夠,維護成本過高,系統升級困難等問題,促使了操作系統的迅猛發展。而嵌入式操作系統,則被定義為“以應用為中心、以計算機技術為基礎、軟硬件可裁剪、適應應用系統,對功能、可靠性、成本、功耗等方面有嚴格要求的專用計算機系統”。

          嵌入式操作系統的特點有:提供較好的內核管理、多任務管理、資源管理、穩定性好、可裁剪和配置、滿足實時性需求、針對性強等。隨著計算機信息技術的不斷發展,嵌入式操作系統也在不斷演化升級,常見的有uC/OSⅡ操作系統,eCOS操作系統,VxWorks嵌入式實時操作系統,WinCE操作系統以及Linux操作系統等。嵌入式Linux利用嵌入式系統實時性、穩定性的特性和Linux相輔相成,很好的彌補了Linux實時性差的缺點,使得Linux在嵌入式領域發展迅速。近年來,嵌入式Linux操作系統的應用相當熱門,已經廣泛應用于筆記本電腦、連網裝置、網絡電視等各式各樣的通信基礎產品中。

          2 系統硬件環境

          2.1 Intel的XScale系統結構

          XScale系統結構是對StrongARM的系統結構的擴充和改進。Intel的第一個StrongARM處理器SA-110實現了ARM系統結構的第4版,即ARMv4內核。StrongARM是ARM公司的注冊商標,最初由ARM公司與當時DEC公司聯合開發,由DEC生產和銷售,但是后來由Intel生產。SA-110是第一個采用哈佛結構的ARM內核,因此,它有兩個獨立的高速緩存和兩個MMU。這樣取指令與讀/寫就不需要在時間上互相錯開,從而提高了訪問高速緩存的速度。

          2.2 PXA27x處理器

          PXA27x處理器是Intel公司在2004年4月12日正式的當前最新的嵌入式處理器。它的時鐘頻率從312到624MHz,并內建64MB(megabytes)的堆棧型IntelStrataFlash內存。它內置了Intel公司的無線MMX技術,能夠為3D游戲與影片應用提供更高的效能,顯著提升多媒體性能。312MHz的CPU(PXA27x系列中最低時鐘頻率的產品)將達到520MHzARMCPU的多媒體處理效能,而鐘頻達到624MHz則可以具備775MHzARMCPU的表現。

          3 系統軟件環境的建立

          3.1 嵌入式操作系統的選擇

          嵌入式操作系統的選擇主要從以下幾個方面加以考慮。

          ①操作系統的硬件支持:首先是否支持目標平臺,其次可移植性。②開發工具的支持程度:選擇嵌入式操作系統時必須考慮與之相關的開發工具。在線仿真器(ICE)、編譯器、匯編器、鏈接器、調試器以及模擬器等不同程度的影響到嵌入式軟件的開發。

          ③能否滿足應用要求:應用對操作系統的要求包括實時性能、不同語言的支持、標準兼容性、技術支持、源代碼還是目標代碼等等。

          若找不到一個合適的操作系統或者買不起昂貴的商用操作系統,可以考慮自己建立一個操作系統。

          3.2 系統結構設計

          Trident PNX8471芯片平臺能夠接收BTSC(Broadcast Television System Committee),該平臺有兩個硬盤接口、一個MII 接口(Media Independent Interface,介質無關接口或稱為媒體獨立接口,它是IEEE-802.3定義的以太網行業標準。它包括一個數據接口,以及一個MAC和PHY之間的管理接口)、2個USB2.0接口、1個USB1.1接口、5路TS輸入接口、2路I2C,支持3D圖形加速。在性能上支持:視頻支持1080P60輸出,支持H.264、MPEG2、VC-1、DiVX、AVS等格式,同時也支持RMVB格式480P的輸出,3DTV支持H.264 MVC 1080P30輸出;音頻支持BTSC、CH3/4,輸出支持YPbPr、RGB、Y/C、CVBS;TS處理方面最大支持5路基帶輸入和4路DMA輸入,最大支持192個Filter。

          Trident PNX8471芯片平臺的編譯使用GNU3.81,Perl版本5.8.8,支持Android2.3,Linux內核版本2.6.34。平臺在基于Android的架構上增加了數字電視相關的功能模塊。實現本項目的EPG功能,同時兼顧EPG功能的擴展性,我們需要在硬件抽象層增加Demux模塊,用來接收PSI/SI數據,這個部分將是Program模塊、Event模塊、Time模塊公用的模塊;在Libraries層增加Program模塊、Event模塊、Time模塊,用來實現節目、事件、時間的功能;在應用框架層(Application Framework)增加獲取EPG功能的EPG JNI接口;在應用層增加EPG的呈現。

          4 結語

          嵌入式系統已成為以高速CPU和嵌入式操作系統為核心的軟硬件綜合系統。系統兼容性好,效率高,而且具備文件和目錄管理、設備支持、多任務、網絡支持、圖形窗口及用戶界面等功能。

          參考文獻:

          [ ]彭曉明,王強.Linux核心源代碼分析[M].北京:人民郵電大學出版社,2000.

          [2]李善平,劉文峰.Linux與嵌入式系統[M].北京:清華大學出版社,2006.3.

          篇13

          文章編號:1004-373X(2010)03-131-03

          Design and Implement of New Voltage Monitoring Instrument Based on STC12C5A60S2

          CHEN Weifeng,DENG Xiaoying,LV Tianwen

          (College of Physics Science and Technology,Yangzhou University,Yangzhou,225002,China)

          Abstract:A design based on micro-controller STC12C5A60S2 is introduced because of the demand of monitoring the real-time voltage on power grid.This system consists of the voltage data acquisition module and the display module,which can display the real time and real-time voltage.It contains the functions as below:warning when the voltage beyond or above the limit and the setting of ratio and system coefficient,and the statistic of the voltage etc.The latest and high effective 1T8051 single chip microcomputer and memory are used to fasten the speed of execution and storage.The program is edited by the high-level language,which contains the subroutines such as initialization of the system and the key scanning,handling of menu and statistic of the voltage.

          Keywords:voltage monitoring instrument;STC12C5A60S2 micro-controller;real time;D/C conversion

          0 引 言

          電壓監測系統是對電網電壓質量進行監測并自動記錄的智能化儀表系統,為統計電壓的合格率及其他參數、反映電壓質量的管理提供正確的數據[1]。電壓監測系統的最小組合為一臺智能電壓監測儀。通過儀表的使用,即可實現對電壓監測點的各種電壓參數進行測量并記錄,同時給出電壓合格率、電壓偏高不合格率、電壓偏低不合格率等計算結果。電壓監測系統的另外┮恢腫楹鮮怯傻繆辜嗖庖羌由系緲?、通讯患吧衔挥嬎銠C等配套設備組成。電壓監測儀所記錄的數據很多,通過儀表鍵盤來查詢抄錄十分耗時耗工,而直接用小打印機打印也有許多缺點和不便之處[2]。本系統可實現電網電壓集中監測,并有查詢、統計報表、電壓越限報警、典型工作日設定、系統變比和電壓值誤差系數可調整等一系列功能[3]。

          1 系統設計

          采集模塊以高性能微處理器STC12C5A60S2為核心[4],由信號變換、實時時鐘、串行通信和大容量串行存儲器等模塊電路構成。整個系統結構組成如┩1所示。

          圖1 系統結構

          STC12C5A60S2是宏晶科技今年新推出的一款處理器,全面兼容傳統的51系列。STC12C5A60S2是┮桓鍪敝/及其周期,增強型51內核,速度比普通的8051快8~12倍。工作電壓比較寬,為3.3~5.5 V。增加第二復位功能引腳,并且具有外部掉電檢測電路,可在掉電時,及時將數據保存進E2PROM。內部有1 280 B的RAM數據存儲器。芯片內部有E2PROM功能,擦寫次數達10萬次以上。具有ISP/IAP功能,8通道10位高速ADC,速度可達2.5×105次/s,2路PWM還可作2路D/A使用。內部已經集成了獨立的波特率發生器,此系列單片機串行通信的速率可以不由內部定時器T1的溢出率來決定,這樣可以讓T1來實現定時或者計數的功能。此系列的單片機還有雙串口的功能,一個串口可以被系統使用,剩下的串口可以用來作系統程序調試信息的輸出,避免一個串口被占用的情況下,只能使用I/O口去模擬UART時序的麻煩。

          監測系統是弱電系統,而電網電壓一般是220 V左右的交流電,不能由系統直接進行測量。必須把測量的電壓通過帶緩沖器的降壓器,降至3~4 V的交流小信號。

          降壓之后的電壓信號為交流小信號,再通過真有效值轉換芯片AD536轉換成有效值相等的直流信號并輸出[5]。

          AD536轉換輸出的直流信號通過V/F變換芯片LM331輸出其直流信號所對應頻率的數字脈沖,供單片機進行采集,從而單片機計算出直流信號的大小。在本設計中沒有采用傳統的A/D轉換器把模擬信號變成數字信號,而是采用LM331進行V/F變換[6]。

          V/F變換的電路圖如圖2所示。

          圖2 V/F變換電路圖

          LM331的動態范圍寬,可達100 dB;線性度好,最大非線性度失真小于0.01%,工作頻率低到0.1 Hz時尚有較好的線性;變換精度高,數字分辨率可達12 b;電路簡單,只需接入幾個外部元件就可方便構成V/F變換電路,并且容易保證轉換精度[7]。根據上面的電路和數據手冊可以得出LM331輸出頻率的計算公式:

          Fout=Vb2.09 VR2+R1R41R5C4

          LM331輸出的數字脈沖通過光耦TLP521進行隔離,再送入單片機的定時器T1進行計數。定時器T0用來定時,每隔1 s鐘單片機在T0的定時中斷服務程序中讀取T1計數器的值,因為間隔是1 s,所以讀出來的值就是LM331輸出脈沖頻率的大小。由上面的公式可以計算出AD536輸出的有效值Vb,進而可以推算出此時測量電網電壓的大小[1]。

          根據要求,此系統需要記錄歷史電壓。這里選擇鐵電存儲器FM24C512,它是一款容量高達512 KB的非易失性存儲器,它采用了先進的鐵電處理技術[8]。原理圖如圖3所示。

          圖3 FM24C512原理圖

          FM24C512以總線速度進行寫操作,無須延時。┫亂桓鱟芟咧芷誑梢粵⒓純始,無需進行數據輪詢,最高總線頻率高達1 MHz。另外,FM24C512具有比E2PROM高得多的寫操作次數。而且,因為寫操作不需要在內部提升電路寫電路的電源供電電壓,所以,在寫操作過程中,FRAM比E2PROM消耗的功率要低得多。

          FM24C512使用I2C通信協議,簡化了與微控制器的接口電路。它使用極少的管腳,占用極小的板空間,只使用兩個管腳和處理器進行通信,一個是時鐘線SCL,另一個是數據線SDA。因為所使用的主處理器沒有相關的I2C通信接口,所以只能用兩個I/O口去模擬I2C的時序。時序圖如圖4所示。

          圖4 FM24C512工作時序圖

          在記錄歷史電壓時,實時時間芯片DS1302產生的時間作為記錄電壓的參考[9]。DS1302是美國DALLAS公司推出的一種高性能、低功耗、帶RAM的實時時鐘電路,它可以對年、月、日、周日、時、分、秒進行計時,具有閏年補償功能,工作電壓為2.5~5.5 V。采用三線接口與CPU進行同步通信,并可采用突發方式┮淮未送多個字節的時鐘信號或RAM數據。DS1302內部有一個31×8的用于臨時性存放數據的RAM寄存器。DS1302是DS1202的升級產品,與DS1302兼容,但增加了主電源/后備電源雙電源引腳,同時提供了對后備電源進行涓細電流充電的能力[10]。它與單片機的連接如圖5所示。

          DS1302與CPU的連接只需要三條線,即時鐘線(SCLK)、數據線(IO)、復位線(RST)。相應的時序圖如圖6所示。

          圖5 DS1302與單片機的連接

          圖6 DS1302工作時序圖

          根據圖6,就可以編出相應讀取DS1302時間的子程序。

          uchar Rd_1302(uchar add)

          {

          uchar ucda;

          Ds_Rst = 0;//先把復位口拉低

          Ds_Clk = 0;//再把時鐘口清零

          Ds_Rst = 1;//把復位口至高,準備寫入地址

          Input_Byte(add);//設定操作寄存器的地址

          ucda = OutPutByte(); //讀出相應寄存器數據

          Ds_Rst = 0;//把時鐘線恢復至低電平

          return ucda; //返回讀取的數據

          }

          為了增強人機的交互性能,選用金鵬電子的OCMJ12232液晶顯示模塊作為系統的顯示部分。OCMJ12232的顯示方式為點陣圖形,可以顯示任意圖形或者漢字,內帶8 192個中文點陣,具有并行和串行兩種接口方式。本設計采用了串行接口方式,具有占用I/O資源少,編程簡單等特點。

          2 流程設計

          系統程序由顯示模塊、按鍵掃描模塊、頻率計數模塊、記錄統計模塊、系統菜單模塊等組成。在軟件編寫過程中,記錄統計模塊較為復雜,其算法為:程序判斷是否到了下一秒鐘,如果沒有則繼續采集電壓再進行判斷,否則進行有關電壓秒記錄的處理;接著判斷是否到了一分鐘,如果沒有則退出,否則進行有關電壓分鐘記錄的處理;下一步再判斷是否到了一小時,如果沒有則退出,否則進行有關電壓小時記錄的處理;以此類推,還

          要判斷是否滿了一天、一個月的情況。其中,還需要判斷是否是典型工作日,每個月可以設置三個典型工作日,典型工作日中每個小時的記錄都被保存下來,以便用戶查看。流程圖如圖7所示。

          圖7 軟件流程圖

          3 結 語

          本文詳細介紹了基于STC12C5A32AD的電壓監測系統,適用于0~480 V交流電壓的監測。本設計已經完成了設計和調試,并通過了客戶的驗收,成功運行在電網公司的監控大廳。

          參考文獻

          [1]杜秀芳,曹玉強,張靜.智能型真有效值電壓檢測儀[J].兵工自動化,2006,25(5),84-87.

          [2] 張建民,黃劍.DC-100/C電壓監測系統的研制[J].華東電力,2001(4):31-32.

          [3]孔,段崢輝.GSM短信電壓監測儀的應用分析[J].電力設備,2005,12(6):61-63.

          [4]宏晶科技.STC12C5A60AD系列單片機器件手冊[EB/OL].,2009.

          [5]趙鵬,李志剛.AD536的性能及其應用[J].國外電子測量技術,2004(2):17-19.

          [6]劉濱.VM-I型電壓監測記錄儀的結構與功能[J].吉林電力技術,1997(2):50-51.

          [7]漆文輝.變電站電壓質量監測系統的研制[J].儀器儀表學報,2002,23(5):192-197.

          主站蜘蛛池模板: 国产91久久精品一区二区| 精品国产一区二区三区久久久狼| 动漫精品一区二区三区3d| 亚洲性色精品一区二区在线| 亚洲熟女综合色一区二区三区 | 国产精品自拍一区| 成人精品一区二区三区电影 | 久99精品视频在线观看婷亚洲片国产一区一级在线 | 国产成人一区二区三区高清| 精品一区二区三区| 国产精品福利一区| 久久久久久免费一区二区三区 | 一区二区免费国产在线观看| 亚洲AV本道一区二区三区四区| 欧美日本精品一区二区三区 | 午夜福利一区二区三区在线观看 | 国产视频一区在线观看| 日本无码一区二区三区白峰美| 亚洲国产成人精品久久久国产成人一区二区三区综 | 男人的天堂精品国产一区| 无码少妇一区二区性色AV| 亚洲性色精品一区二区在线| 国产成人无码AV一区二区在线观看| 亚洲国产欧美国产综合一区| 亚洲国产高清在线一区二区三区| 欧洲无码一区二区三区在线观看 | 精品一区二区三区无码免费直播| 国产日韩AV免费无码一区二区| 中文字幕精品一区二区日本| 亚洲国产精品一区二区第一页免 | 亚洲日本中文字幕一区二区三区| 福利一区二区在线| 国产精品一区在线麻豆 | 亚洲av午夜福利精品一区| 日韩在线一区高清在线| 搡老熟女老女人一区二区| 精品一区二区久久| 一区二区三区视频网站| 波多野结衣在线观看一区 | 成人h动漫精品一区二区无码| 无码国产精品一区二区免费vr |