引言 ---從推出至今,USB技術(shù)的應(yīng)用范圍主要局限在電腦和外設(shè)領(lǐng)域,但在嵌入式系統(tǒng)中,USB的巨大發(fā)展?jié)摿有待挖掘,其典型應(yīng)用包括KVM接線器、數(shù)碼相機、PDA、打印機、機頂盒和手機,任何具有處理器的電子設(shè)備都可以成為一個嵌入式USB主機。 在一個基于PC的系統(tǒng)中,USB操作需要三種主要元件,即主控制器(常常是PCI子系統(tǒng)的一部分)、USB堆棧和USB類驅(qū)動器。主控制器是集成母板芯片組的組成部分,目前的大多數(shù)PC都在母板上實現(xiàn)了USB2.0。USB堆棧包括用于母板上的驅(qū)動器以及UCHI(通用主控制器接口)、OHCI(開放式主控制器接口)和USB驅(qū)動程序(usbd.sys)。 在一個嵌入式USB系統(tǒng)中,主要元件與基于PC的系統(tǒng)相似,即:嵌入式主控制器硅片、具有OHCI堆棧的實時操作系統(tǒng)(RTOS)和專用驅(qū)動器。 主控制器有多種選擇,有的具有處理器,有的則基于寄存器。RTOS可以從銷售商那里直接購置。最佳方法是選擇能夠配套運行的處理器和RTOS,然后再在其上增加應(yīng)用代碼。如果不使用真正的RTOS,則可編寫簡單的操作系統(tǒng),以履行RTOS的功能。后文將介紹一個這樣的例子。 當在PC上實現(xiàn)USB時,可用資源十分充足,包括512MB的存儲器、20GB~60GB的硬盤驅(qū)動器和工作頻率為2GHz(或更高)的微處理器。此外,Windows、MAC OS和Unix等操作系統(tǒng)對USB提供完善的支持,還有許多從事基于PC的USB應(yīng)用和設(shè)備驅(qū)動器研究的工程師。 另一方面,嵌入式系統(tǒng)通常具有容量小于64KB的存儲器和工作頻率范圍為12MHz~33MHz的處理器,且沒有硬盤驅(qū)動器。由于USB對于嵌入式系統(tǒng)而言是一個比較陌生的領(lǐng)域,因此只有少數(shù)工程師擁有相關(guān)的經(jīng)驗。本文將著力說明如何開發(fā)能夠控制許多USB設(shè)備的嵌入式USB主機系統(tǒng)。 USB基礎(chǔ)知識 先簡要介紹USB的傳輸類型。現(xiàn)在共有4類USB傳輸,即控制型、中斷型、等時型和成批型。中斷、等時和成批型傳輸用于完成點對點數(shù)據(jù)移動?刂菩蛡鬏斢糜谧R別和設(shè)置將能夠與USB主機進行通信的設(shè)備。之后,這些設(shè)備將能夠采用中斷、等時和成批傳輸來進行數(shù)據(jù)傳遞。 圖1對這些傳輸類型進行了圖示。每個USB事務(wù)處理都是由0個或更多個級(通常為1級或3級)所組成的,這些級是“設(shè)置”(Setup)、“數(shù)據(jù)”(Data)和“確認”(Acknowledge)。每一級包括兩個階段或三個階段。這些階段為“權(quán)標”(Token)、“數(shù)據(jù)”(Data)和“信號交換”(Handshake)。 權(quán)標級采用一個PID(分組ID),定義的PID有16種,包括圖1中所示的設(shè)置、輸入和輸出分組ID。圖1示出了控制讀取傳輸,此類傳輸將被用來收集有關(guān)一部連接設(shè)備的信息,控制型傳輸實現(xiàn)了一個設(shè)置級。正如其名稱所表示的那樣,該級被用來對一部設(shè)備進行設(shè)置。USB需要做出響應(yīng)的設(shè)置請求有很多。這里的要點是,控制型傳輸將被嵌入式USB主機用來對連接設(shè)備進行識別和初始化,這些事務(wù)處理的細節(jié)由固件的驅(qū)動器層固件來控制。 與控制型傳輸不同,成批和中斷型傳輸只有一級。這一級具有常見的三個階段,即:權(quán)標、數(shù)據(jù)和信息交換。等時型傳輸與成批和中斷型傳輸相似,只是其沒有信息交換階段。 人機接口設(shè)備(HID)和USB設(shè)備用于實現(xiàn)用戶與PC之間的互動。鑒于人機接口的低速特性,因而只需采用低速USB。低速USB具有800KB/s的數(shù)據(jù)吞吐量,這對應(yīng)于每次傳輸8字節(jié)和每秒傳輸100次(每10ms進行一次傳輸)。用于從HID設(shè)備獲取數(shù)據(jù)的傳輸類型為中斷型傳輸。 來自鍵盤和鼠標裝置的數(shù)據(jù)被格式化為“HID報表”。用于一個鍵盤和鼠標的HID報表分別為8字節(jié)和4字節(jié)。鍵盤和鼠標HID報表的內(nèi)容如表1所示。 HID報表的數(shù)據(jù)可由應(yīng)用層來分析。在本例中,HID數(shù)據(jù)將從系統(tǒng)串行端口送出,并通過HyperTerminal來查看。 案例研究 下面將說明如何構(gòu)建一個用于控制鍵盤和鼠標的簡單嵌入式USB設(shè)計方案,該設(shè)計還能夠控制一個USB集線器,從而可在僅采用嵌入式USB主芯片的單個端口的情況下同時對鍵盤和鼠標提供支持。該設(shè)計的另一個好處是其還能夠支持組合式鍵盤/集線器。 該實現(xiàn)方案采用了一個基于寄存器的USB主控制器和一個基于RISC、用于控制主IC的處理器。RISC處理器的代碼只需通過改變硬件專用層便能夠容易地移植到另一種處理器。 程序流程 程序流程應(yīng)按下述步驟來進行。在上電復(fù)位時,微處理器將對所有的寄存器、計數(shù)器以及全部的設(shè)備結(jié)構(gòu)進行初始化,隨后將進入一個按下列方式執(zhí)行操作的環(huán)路中。 1.檢查主USB端口所發(fā)生的任何狀態(tài)變化(設(shè)備的插入或移除)。 2.檢查所有連接集線器的端口的狀態(tài)變化(在集線器端口上進行設(shè)備的插入或移除)。 3.檢查任何其他連接設(shè)備,以編制HID報表。 檢查主USB端口的狀態(tài)變化只需通過主USB控制器的簡單寄存器讀操作便可完成。如果發(fā)現(xiàn)一部設(shè)備,則其將被計數(shù)。如果變更值表示設(shè)備已被移除,則采用“0”來改寫對應(yīng)的設(shè)備數(shù)據(jù)。 檢查連接集線器的變更值是利用一個從集線器至主機的中斷型傳輸來完成的。如果有設(shè)備被添加或移除,則與上一種情況一樣對其進行計數(shù)。 在檢查設(shè)備的插入和移除的同時還有兩項附加任務(wù)。如果一部連接設(shè)備是一個集線器,則必須檢查其端口,以察看它們是否也包含設(shè)備。如果被移除的設(shè)備是一個集線器,則所有與其相連的設(shè)備也都必須被移除。下面的固件流程部分將對這些程序做進一步概述。 對來自連接HID設(shè)備的數(shù)據(jù)進行檢查也是通過中斷型傳輸來完成的,中斷傳輸?shù)拈g隔時間為10ms,傳輸?shù)亩〞r將交由應(yīng)用代碼來處理。 固件概述 用于該設(shè)計的固件是以一種分層方式來提供的,該分層結(jié)構(gòu)對應(yīng)于上述模型(應(yīng)用->驅(qū)動器->硬件)。 應(yīng)用層定義了三種功能,即FindDevices(發(fā)現(xiàn)設(shè)備)、GetData(獲取數(shù)據(jù))和SendData(發(fā)送數(shù)據(jù))。FindDevices對新連接的USB設(shè)備進行定位和計數(shù),并刪除被移走的設(shè)備。GetData從連接設(shè)備獲取HID報表。SendData將數(shù)據(jù)發(fā)送至設(shè)備。由于沒有理由將數(shù)據(jù)寫至鍵盤或鼠標,因此,該功能在這里似乎并不需要。然而,在一種情形下這種功能卻有可能被派上用場,那就是為控制Caps、Scroll和NumLock LED而將數(shù)據(jù)寫至鍵盤。由于并不是所有的鍵盤都支持用于此類寫操作的中斷端點,因而將需要為此采用一個控制型傳輸。 驅(qū)動器層實際上被分為兩個區(qū)。上部驅(qū)動器層功能包括各種與連接外設(shè)、端口和集線器的識別、配置和狀態(tài)檢查相關(guān)的任務(wù)。 CheckHub負責執(zhí)行主機與集線器之間的中斷型傳輸,以檢查端口變化。FindUSBDevices命令采用控制型傳輸來對設(shè)備進行初始化和計數(shù)。SetAddress向設(shè)備分配USB地址,而SetConfiguration則負責設(shè)定當前的設(shè)備配置。該驅(qū)動器層中的其他關(guān)鍵命令包括GetHidDesc和GetHubDesc,它們分別獲取用于人機接口設(shè)備和集線器的設(shè)備描述符。同樣,GetHubStatus和GetPortStatus命令用于獲取集線器或端口的當前狀態(tài)。PortFeature命令用于設(shè)定或清除諸如Port Enable(端口使能)、Port Power(端口電源)或Port Reset(端口復(fù)位)等集線器端口功能,而GetDesc功能則用于從USB設(shè)備獲取設(shè)備描述符。 下部驅(qū)動層包括VendorRequest命令,該命令用于對控制型傳輸?shù)脑O(shè)置相進行配置。EP0Xfer負責控制一個控制型傳輸?shù)娜齻級,而InterruptXfer則用于控制單級傳輸。 在硬件層上,UsbXfer命令對USB主控制器進行寫操作,以控制一個USB傳輸?shù)膯蝹級。所有的硬件專用寄存器讀和寫代碼也都位于該層之上。 數(shù)據(jù)結(jié)構(gòu) 除了設(shè)備驅(qū)動器之外,還必須定義數(shù)據(jù)結(jié)構(gòu)。如果嵌入式解決方案允許連接8部設(shè)備,則需要維持一系列8部設(shè)備結(jié)構(gòu)。設(shè)備結(jié)構(gòu)中的數(shù)據(jù)將按下列方式寫入。 設(shè)備類型可由其類代碼來識別。同一類型的設(shè)備可通過其銷售商ID和產(chǎn)品ID來區(qū)分。協(xié)議字段用于確定HID報表的大小,4字節(jié)用于鼠標,8字節(jié)用于鍵盤。 設(shè)備由其USB地址來區(qū)分。USB地址是用于對與某個USB端口相連的所有節(jié)點進行尋址的邏輯值。在這里所描述的鍵盤/鼠標實例中,設(shè)備的數(shù)量必須被限制為8個。這意味著地址的數(shù)量也將被限制為8個,再加上一個每個未初始化設(shè)備都必須響應(yīng)的缺省地址—地址“0”。一旦某個邏輯地址被分配給一部設(shè)備,固件將采用SetAddress命令來向該設(shè)備發(fā)出通知,告知其應(yīng)對用于該地址的事務(wù)處理做出響應(yīng)。 |