USB在同步相量測量單元中的應用
4.6 標準請求處理程序
標準設備請求是由USB協議決定的,由主機發出,以數據包的形式傳送到單片機。當單片機接收到這些標準設備請求時就轉入相應的處理程序。其過程包括:①獲取狀態。②清除特性。③設置特性。④設置地址。⑤獲取設備描述符。⑥設置配置。⑦獲取配置信息。⑧獲取接口信息。⑨設置接口。⑩同步幀。其中同步幀用來設置和報告一個端點的同步幀,在同步傳輸中才使用,如果設備不支持這個請求,返回停止標志。
4.7 主循環程序
主循環程序主要功能是設置單片機的初始化,以及設定各個相關子程序的入口。由于使用了中斷服務程序和一系列的命令接口子程序,主循環程序中涉及USB接口的部分只是設定相關的寄存器。
5 USB驅動程序上位機部分
5.1 驅動程序基本概念
主機驅動程序的功能是將硬件與用戶應用程序連接起來。編寫的方法有多種,可以直接與硬件相連接,在應用程序中直接讀寫系統應將,或者將與硬件直接交換數據的底層工作交給操作系統自動完成,應用程序象讀寫普通文件一樣完成對硬件設備的操作。前一種方法的代碼開銷少,但是編寫的工作量非常大,移植性也較差。后一種方法需要大量庫函數支持,但編寫較為簡單,且移植性好,甚至只需少許修改就可以完成對另一種硬件的支持。在本系統中使用的是由廠商提供的驅動程序,為了充分說明USB系統的工作,還是有必要對主機驅動程序的工作方式做一個介紹。
從驅動程序的角度出發,每個設備都被看成若干個設備對象,這些設備對象的來歷各不相同,每個對象都有驅動程序與之對應。它們根據一定的規則組成設備對象堆棧,也就是對應的驅動程序堆棧。處于最底層的是物理設備對象,它一般由總線生成,驅動程序到達這里的時候,總線只是按照標準作一些動作,即可完成對設備物理上的操作。一個設備只能有一個物理設備對象,但可以有若干個其它的設備對象。功能設備對象是由所編寫的驅動程序生成的,它負責從邏輯上操作設備。其它的層次設備對象可以處于功能設備對象的上面或下面,它由另一些驅動程序或者其它的系統組件生成,可以記錄一些設備信息,但層次設備對象不是必須的。由于驅動程序的這種層次結構,在編寫驅動程序的時候不必考慮內存分配、IO端口配置、DMA申請等。Windows將資源申請全部自動化,由總線完成,編寫驅動程序時只要考慮控制設備本身即可。
5.2 即插即用設備狀態及它們之間的轉換
USB接口設備的一個顯著特點就是接入或者拔出時不需要關閉主機和重新啟動系統,而是可以在系統運行時直接插入或者拔出。這與USB接口的硬件設置有關,USB接口是通過檢測接口上拉電阻來判別是否有設備存在的。當然,還必須有相應的驅動程序來完成對此功能的支持。下面就將簡要描述一個設備完成即插即用的過程。
用戶將設備插入計算機,此時設備還沒有被系統檢測到。要開始對設備進行軟件配置,必須由即插即用管理器以及總線驅動對設備進行枚舉。即插即用管理器,有時還可能要在用戶模式下的組件工作,檢測出設備的驅動程序,包括功能驅動程序以及其它的層次驅動程序。如果此時驅動程序尚未調入,則即插即用管理器調用設備插入例程。驅動程序完成初始化之后,接著必須對設備進行初始化。即插即用管理器調用驅動程序中添加設備的例程來初始化該驅動程序控制的每個設備。當一個驅動程序從即插即用管理器中收到開始設備的請求時,驅動程序使設備啟動并且做好處理IO操作。在Windows2000及更高版本的操作系統中,和停止有關的請求只有在重新分配硬件資源的時候才會使用。意外卸載時是指硬件在物理上被卸載(熱拔出),驅動程序處理這個請求使系統的損失盡可能降低。硬件卸載時,調用相應的卸載請求,使得該設備在軟件上也不可用。如果不對意外卸載進行處理,就有可能造成硬件在物理意義上已不存在,但在系統邏輯中依然存在,造成系統訪問該設備的時候出現錯誤,嚴重的情況可能會造成處理器進入死循環。當在軟件意義上對設備進行停止時,需要等其它請求都操作完畢后才能進行。
5.3 驅動程序結構
USB驅動程序從結構上可以分成兩大部分,驅動程序入口以及處理各個事件的例程。驅動程序入口是由系統定義的一組常數,該部分主要完成兩件工作:一件是將注冊表項復制到一個全局變量中;另一件是給不同的設備事件指示處理例程。剩下的工作就是按照這些設備事件編寫各自的例程。這些設備事件主要包括下面幾個部分:
(1)打開文件:當用戶以打開文件的名義打開設備準備讀寫的時候,調用該部分例程進行準備。
(2)關閉文件:當用戶關閉文件(關閉設備)的時候,調用該例程清掃系統。
(3)即插即用處理:處理即插即用相關的事件,該部分例程包括許多硬件相關的子程序,具體功能見第2節。
(4)處理讀操作:當用戶讀取文件時,調用該例程將接口芯片緩沖區內的信息返回主機。
(5)處理寫操作:當用戶寫文件時,調用該例程將數據以包的形式發送到接口芯片。
(6)設備操作:該部分例程完成對設備硬件的控制,一般含有IO控制碼,這些控制碼在用戶頭文件中定義,該例程根據不同的IO控制碼,完成對設備的各項控制任務。
(7)驅動程序初始化:當第一次安裝硬件時調用該部分例程,創建物理設備對象。對所涉及的各個變量進行初始化。這部分程序一般操作系統中有自帶。
(8)驅動程序的卸載:用于清除硬件在系統中留下的痕跡,釋放全局變量中注冊表路徑字符串所占用的內存,將資源歸還系統。
(9)電源管理:所有和電源相關的例程都由這里發出,它發出的請求可以是指定一種新的電源狀態,或者查詢更改一種狀態是否可靠。此部分對于總線供電的USB設備較為重要,涉及設備的掛起和喚醒等操作。在本系統中此部分無作用,所有下位機設備都是自供電形式的,設備處于長時工作狀態。
5.4 USB設備讀寫
USB設備的讀寫操作是大部分用戶主要關心的內容。由于設備驅動程序的作用,用戶應用程序和USB設備的讀寫操作變的非常簡單,用戶打開USB設備就像打開文件一樣。這是在添加設備中申請了一個符號鏈接,并在啟動設備例程中將此鏈接激活而實現的。USB中的讀寫操作分為四種:
(1)控制型:控制型傳輸主要為對USB本身的配置,前面所描述的USB配置實際上都是通過控制傳輸實現的。
(2)批量型:批量型傳輸用來處理大量的對時間要求不緊迫的數據。底層協議保證了無差錯的傳輸,但不保證傳輸時延。
(3)中斷型:中斷型傳輸對服務時間有較強的限制,但一次傳輸的數據量不多,主要為一些需要實時相應的消息。
(4)同步型:同步傳輸可以保證傳輸時延、保證帶寬和保證恒定的數據傳輸速率,但是在傳送失敗的情況下。不使用“重試”來傳輸數據,因而可能會有一定的出錯概率。
對USB接口的讀寫是按照與數據文件讀寫相同的方式進行的,第一步要打開文件,即打開設備。當用戶以打開文件的名義打開設備時,首先要檢查設備的狀態,看設備是否處于工作狀態,設備的接口信息是否已經準備好。接著檢查從上面傳下來的文件對象的合法性(指針不為空)。然后檢查文件名的長度,當為0時,說明打開的只是設備本身;不為0時說明打開的是某個管道,調用管道相關例程,將管道明轉換為指向對應管道綜合信息的指針即可。讀寫USB設備實際上是調用同一個傳輸例程的,所區別的是傳輸方向符不同,由于通訊雙方遵守的都是USB協議,所有的數據包的格式都是一致的,所以這沒有什么問題。驅動程序控制的上位機讀寫過程和單片機的情況類似,所不同的是,單片機使用的接口芯片將數據放入硬件緩沖區內,而上位機的驅動程序則會構建一個虛擬的緩沖區來完成相同的工作。當要發送的數據大于緩沖區的容量時,同單片機的情況一樣,也要對數據進行分割。當數據發送完畢之后,例程返回一個發送成功的標志。
5.5 USB上位機應用程序設計簡介
編寫好驅動程序以后,要在應用程序中調用USB設備,其做法就與調用硬件類似,可以使用WIN32 API函數像調用程序文件一樣對設備進行讀寫,也可以使用如同串口的mscomm那樣的控件來實現。由于本系統的上位機程序是用VB開發的,顯然調用成品動態鏈接庫能減少很多工作量。這里就調用由廣州周立功單片機發展有限公司開發的稱為easyd12.dll的動態鏈接庫。
6 結論
USB接口的驅動程序編寫是一項繁瑣的工作,由于硬件條件的限制,上述程序僅在仿真器上運行通過,無法實地調試,其中必然存在很多漏洞和不足。USB接口本身是并不是為智能儀表開發的,作為批量數據傳輸用的USB總線在智能儀表上使用顯得有些復雜。在更高性能的通用型總線出現以前,為了實現信息的高速傳輸使用USB還是一個性價比較好的方案。本系統只使用了USB的部分功能,付出的軟硬件資源代價卻與一個完整功能的USB傳輸系統沒有多大區別。如果能開發出一種比USB總線更簡便易用的通用型總線,那一定會引起智能儀表的革命。實際上,現在用驅動程序完成的工作完全可以用純硬件的方式來實現,不過目前而言,代價必然較大。如果能找到一個方法來直接控制USB接口各個引腳的電平,那么即使用中規模集成電路也可以完成同步串行通訊的工作,遺憾的是,在整個設計過程中,本人始終沒有發現這種方法,涉及USB協議以及計算機主板上相關控制器的最底層內容仍然無法洞悉。
評論