帳號:
密碼:
最新動態
產業快訊
CTIMES / 文章 /
嵌入式USB主控端設計
 

【作者: Lane Hauck】   2008年10月09日 星期四

瀏覽人次:【7649】

開發嵌入式USB主控端所需的程式碼基本上是一個相當耗費腦力的工作,只要想到我們必須將原本在具有豐富資源與大型作業系統上運作的多功能個人電腦以4到8K的程式碼取代,以便能夠與各種獨立的USB設備溝通,就能瞭解這個任務有多麼艱鉅。


那麼為什麼要開發嵌入式USB主控端呢?答案非常簡單,因為這是目前電腦周邊設備的主流規格,如果您想要讓嵌入式系統能夠與記憶卡、指紋掃描器、印表機、滑鼠、鍵盤、音訊數位化設備,甚至馬克杯保溫器溝通,那麼USB就是應該選擇的方向。


USB主控端控制器

主機板

早期的USB主控端控制器使用PCI匯流排與主機板溝通,但目前USB功能已經內建到主機板上的晶片組中,這些採用PCI介面為基礎的控制器負責了許多USB的經常性工作,例如對PC以及多個USB設備間的USB封包進行順序安排與優先權判斷,一個USB資訊交換可以涵蓋數十個甚至上百個封包,這些都必須由主控端控制器來處理,這些控制器分別為低速與全速設備用的UHCH/OHCI,以及高速設備用的EHCI。


嵌入式系統

嵌入式主控端比起主機板而言複雜度較低、尺寸較小,同時成本也較便宜,尺寸較小的原因是它們使用了比PCI更簡單的介面,設計較簡單則是因為採用封包而非資訊交換方式,另一方面,則由嵌入式韌體而非控制器邏輯來處理何時以及如何發送每個封包。


雖然乍看之下有些限制,但先讓我們考量可能採用嵌入式主控端的情況,常見的目的是讀寫USB記憶卡,通常稱為UMD,也就是USB記憶設備。直到提供更小尺寸同時價格更低連接器的UMD出現前,Compact Flash記憶卡是與大容量記憶體介接最受歡迎的方式,在這個應用上經濟規模產生了效用,現在我們已經可以用相當便宜的價格為嵌入式系統添加數GBytes的的記憶空間。


如果必須與其中某個特定設備溝通,例如一個UMD,那麼並不一定需要PC所提供的各種廣泛支援,基本上,由於PC無法預測可能插入的擴充功能,同時在同一時間也可能必須處理多個USB設備,因此需要大量的驅動程式儲存空間、強大的處理效能以及複雜的驅動程式堆疊來應付,但在嵌入式系統中,所需進行的編碼則是針對預先選定的設備,因此這類型嵌入式做法的名稱可以稱為單點式解決方案。


第一個列舉步驟

要對如何進行嵌入式主控端專案提出討論,我們首先檢討USB主控端進行USB設備列舉的步驟,列舉動作是USB主控端找出特定USB設備特性與要求的溝通程序,以USB規格來說,這是每個設備都必須的共通步驟,因此以下的討論可以適用於每個USB主控端應用的前端動作,在列舉動作後,主控端會對設備進行組態並開始加以運作,基本上相當清楚地,這就牽涉到了隨設備特性不同的額外程式碼。


《圖一 將USB設備插入具備嵌入式主控端的微控制器系統,軟體就能夠與設備相互溝通並取得它的特性。》
《圖一 將USB設備插入具備嵌入式主控端的微控制器系統,軟體就能夠與設備相互溝通並取得它的特性。》

圖一中的程式碼是由Keil ARM7電路板、MCB2130以及包含Maxim公司MAX3421E主控端控制器的配接板所產生,ARM7使用SCLK頻率高達26MHz的SPI匯流排與MAX3421E暫存器組溝通,Keil電路板則配備有可以用來與執行終端應用程式PC連線的串列連接埠。


這篇文章將描述如圖一中程式碼各項事件順序,此外,圖三也顯示了產生圖一中程式碼的匯流排交通LeCory(CATC)匯流排的追蹤結果。



《圖二 USB封包的匯流排追蹤結果以及啟動並評估要求的C語言程式碼。》
《圖二 USB封包的匯流排追蹤結果以及啟動並評估要求的C語言程式碼。》

主控端傳送動作的詳細介紹

圖二為一個USB資料封包,也是USB訊息基本單位的匯流排動作追蹤結果,雖然圖中所指的為MAX3421E所採用的暫存器名稱,但任何嵌入式主控端控制器都會擁有類似的暫存器。


要發出這個封包,微控制器會遵行以下的步驟:


  • ●微控制器在功能位址暫存器中載入周邊設備的位址,主控端使用設定位址指令為每個周邊指定一個獨特位址,這個步驟只有在改變位址時才需要重複執行。


  • ●微控制器在傳送暫存器中載入封包辨識碼PID “IN”以及端點編號,並載入HXFR暫存器來發送封包,主控端控制器接著等待回應,並將任何接收的資料儲存到先進先出(FIFO)緩衝器中並進行位元組總數的更新、錯誤檢查以及在最後更新結果碼,並發出傳送完成的中斷要求。


  • ●微控制器檢查結果碼,最常見的結果為成功與NAK忙碌,當然也可能有各種錯誤情況,例如匯流排逾時無回應、CRC檢查碼錯誤以及設備佔據太多時間等。


  • ●如果設備為忙碌中,主控端會重送IN要求並持續直到設備發出資料回應,當主控端顯示HRSL=ACK時,微控制器會讀取一個位元組總數暫存器並由資料輸入FIFO取得所指出的位元組數。


  • 所有的封包都會以這些步驟進行,只有在資料上有些微不同,例如傳送動作可能不包含任何資料,或者是將送出資料載入資料輸出FIFO、寫入位元組總數並以OUT封包的PID寫入HXFR暫存器。



等待設備連線後並加以重置

USB主控端在沒有設備插入的狀態下,USB的D+與D-接腳會通過15KΩ的電阻連接到地,USB設備透過在其中一個資料線與3.3V間連接一個內部1500Ω電阻來標示本身的存在。


  • ●拉升D-代表低速設備(1.5Mbps);


  • ●拉升D+代表全速設備(12Mbps)。



因此主控端控制器就能夠偵測這些匯流排的變化,並透過旗標位元與中斷,例如MAX3421E中的CONDETIRQ來指出設備插入或拔出的動作發生。


在偵測到連接動作後,主控端會發出一個USB匯流排重置指令,定義為最短50ms的單端零值,也就是兩個資料線都為低電位,之後回復到靜止匯流排狀態,接著設備必須在發出Set_Address需求前最少等待10ms,以便讓設備有足夠的重置回復時間。


在這些動作完成後,主控端會發出一系列的CONTROL傳送動作來進行USB設備的列舉步驟。


關於CONTROL傳送

CONTROL傳送包含了USB的運作碼,使用如表一中的格式,典型的主控端CONTROL傳送動作包含在FIFO中填入8個目標位元組,接著使用SETUP封包辨識碼PID來發送封包。


(表一) 填入這些8位元組來對USB設備發出CONTROL要求

位元組編號

欄位名稱

代表意義

0

bmRequestType

要求型態

1

bRequest

實際要求內容

2

wValueL

依要求不同

 

3

wValueH

4

wIndexL

依要求不同

 

5

wIndexH

6

wLengthL

要求資料位元組總數

 

7

wLengthH


Transfer0:取得設備描述符

主控端使用取得描述符要求來與USB設備進行溝通,這些要求可以參考USB規格書中的第9章,這個特殊要求的型態為“設備”,要進行這個要求,我們將8位元組的字串寫入主控端控制器的資料FIFO,接著將周邊位址設為0,例如設定暫存器PERADDR=0並發送出這個封包。


  • ●BYTE Get_Descriptor_Device[8] =


  • {0x80,0x06,0x00,0x01,0x00,0x00,0x08,0x00};



雖然USB設備的描述符為18個位元組長度,但這個要求只要求8個位元組,原因是全速設備允許能夠在Endpoint 0端點擁有四個可能的maxPacketSize值,分別為8、16、32或64 Bytes,由於事先無法得知設備的maxPacketSize,因此要扮演合適的主控端,在取得正確的數值前必須不能要求超過8個位元組,雖然由設備傳回的設備描述符為18個位元組長度,但是聰明的USB架構設計師在描述符的第8個位元組安排了我們所需的數字:EP0 maxPacketSize,在取得這個數字後,我們就可以藉以調整接下來對這個設備的EP0要求長度。


關於USB傳送長度

USB傳送動作的位元組總數由以下法則決定:


  • ●主控端要求如wLengthH/L欄位中的長度;


  • ●周邊送出較小的要求以及可用位元組總數。



周邊以較短或空資料封包來代表記錄的結束,較短封包為低於maxPacketSize的數值。


在主控端開始進行傳送動作後,它會等待設備回應或匯流排逾時發生,接著進行回應的評估、設定結果碼並對微控制器發出中斷,由周邊送入的資料儲存在FIFO中,圖一中設備描述符的前8個位元組透過首先讀取位元組總數暫存器,接著由RCVFIFO讀取並輸出8個位元組。


由設備讀取送入資料的程式必須處理兩個細節,首先設備被允許在資料尚未準備完成時送出NAK(Negative ACKnowledge),主控端只需重複送出要求直到取得資料為止,至於設備可允許持續送出NAK的時間長度則由使用者決定,就算時間長達數個小時也依然符合USB規格。


第二個細節則包含多重封包資料傳送,這對擁有長度比它的endpoint 0 maxPacketSize描述符還長的設備相當普遍,因此主控端必須發出多個IN要求並將這些由多個封包所取得的資料加以組合。


Transfer1:設定位址

由於在第一個要求時設定位址為0,因此這時必須給予每個設備一個獨一無二的位址,雖然規格並沒有嚴格要求應該在這個步驟前發出另一個USB匯流排重置信號,但這帶來了一個相當重要的觀點,那就是知道PC會進行這樣的動作,雖然不知道為什麼,但為了安全性還是加以跟隨。


我們可以將周邊位址設定為1到127中的任何一個數值,如果我們要透過USB集線器與超過一個設備溝通,那麼這些獨一無二位址就可以讓設備在邏輯上有效分隔。


Transfer2:再次取得設備描述符

重複這個步驟的原因是這時會有兩個不同情形,也就是目前我們已經取得maxPacketSize的數值,同時USB設備也位於不同的位址,這時要求的長度為18個位元組。


  • ●PERADDR=7


  • BYTE Get_Descriptor_Device[8] =


  • {0x80,0x06,0x00,0x01,0x00,0x00,0x12,0x00};



圖一中顯示了完整的設備描述符,同時也顯示出設備在送出資料前所送出的NAK次數(10/0),這兩個數字指出了NAK在CONTROL傳送資料階段與狀態階段的次數,列出的有關組態、VendorID以及ProductID等資訊則由18個設備描述符中取得。


Transfer3~6:取得字串描述位元組

設備可以提供也可以不提供描述設備的字串,主控端透過發出取得描述符字串要求來取得這些資訊,由以下設備描述符位元組我們可以看出,字串是否存在可以由iManufacturer、iProduct以及iSerialNumber等位置中是否有非0的值來表示。



《公式一》 - BigPic:644x252
《公式一》 - BigPic:644x252

Transfer4:取得組態描述符

組態描述符為9個位元組長度,它包含了包括組態描述符本身加上其後描述符,例如介面、端點以及選用類別描述符的總位元組數,主控端發出取得組態描述符指令要求,要求長度為9個位元組,如圖一中我們可以看出,第三與第四個描述符位元組(20 00)指出整個組態描述符以及其他附屬描述的總長度,請注意USB採Little-Endian設計,因此0x20 0x00代表32個位元組。


Transfer5:再次取得組態描述符

主控端接著發出相同的要求,但要求長度為0x20,圖一顯示了32個位元組長度的完全組態資料,接下來的資訊則使用於USB規格第9章中所描述的方式由32個位元組資料進行解碼,由於每個描述符都以長度位元組開頭,因此主控端可以簡單地透過將長度位元組加到一個指標器,接著以鏈結串列的方式取出資料來取得各個獨立的描述位元組。


資料交替

當主控端或周邊送出多重封包資料時,會使用兩個資料PID,分別為DATA0與DATA1,這些為能夠協助USB進行錯誤偵測的機制之一,在每個端點上都有一個用來決定使用那一個DATA PID的資料交替位元,在重置後的第一個資料封包,不管是送到或由端點送出,都使用DATA0發送,而在兩端,也就是發送與接收端同意資料正確後,也就是發出或收到ACK交握信號時,就會切換它的數值,因此接下來的資料封包發送通常就擁有交替的PID值,如DATA0、DATA1、DATA0等,因此如果接收到資料封包的資料PID不符合交替值時,就代表發生錯誤。


主控端控制器提供了各種協助管理資料交替的機制,部分需要主控端韌體在程式碼中維持交替值,並為每個資料傳送動作預設交替值,其他則可能自動管理交替動作並在發生交替值不符時發生警告,不管那種情況,在進行端點切換時都必須先儲存目前的交替狀態。


以下為管理資料交替的法則:


  • ●在CONTROL傳送SETUP與STATUS階段的交替值為預先設定,因此主控端程式並不需要加以初始化;


  • ●BULK傳送的交替值依以上描述進行,也就是收到ACK信號時讓資料交替值進行變動;


  • ●主控端控制器晶片通常維持了相同端點的連續傳送動作資料交替;


  • ●如果主控端先傳送資料到端點endpoint 1,接著再切換到端點endpoint 2,那麼它首先必須儲存endpoint 1的交替狀態,並重新載入所儲存的endpoint 2交替狀態。



電源考量

USB主控端透過VBUS接線提供USB周邊5V的電源,PC擁有提供給每個USB連接埠500mA電流的能力,但嵌入式系統則通常沒有這樣充裕的電源。


如果USB設備提出採用匯流排供電的要求,那麼也會在它的組態描述符中標示出由VBUS連線所需的最大電流,PC主控端使用這項資訊來加總設備要求的電源總額,並在電源要求無法符合時對使用者發出警告,例如採用匯流排供電的集線器可以對每個下屬連接埠供應100mA的電流,如果設備表示本身為匯流排供電並要求250mA,那麼當它插入這樣規格的集線器時,將會得到一個錯誤訊息視窗來建議將它插入其他連接埠。


主控端基本上並不會實際測量VBUS的電流,而是使用信賴式系統設計,由周邊來告知本身的電源要求,大部分的PC主控端都在VBUS上加有保險絲,並將限額安排在高於500mA限制之上來保護電源系統。


以上的描述基本上為理論狀態,接下來討論現實的情況,如果有人在嵌入式主控端的A型連接器插入一個1A的馬克杯保溫器的話,那麼會發生什麼情形?由於這樣的設備只想由VBUS電源取得電力,很明顯地並不像正式的USB設備會告知本身的電源要求,但基於USB已經成為相當普遍的標準,所以必須要有任何東西都可能插入的心理準備,因此嵌入式主控端必須對VBUS上連接器上5V電源的電流加以限制,一個完成這個目標的方法是採用限流開關,首先,它扮演VBUS電源的開關,會在過電流時自動讓負載離線,並透過FLAG輸出接腳來表示這個情況。


當USB匯流排重置動作不正確時,最少會有一個USB設備進入鎖定狀態,這個情況通常發生在USB主控端電源啟動前設備已經插入的情況,因此以0.2秒的時間切換電源可以產生確保的重置動作。



《圖三 這個CATC(LeCroy)匯流排追蹤圖顯示了本篇文章中所描述的主機端列舉步驟與過程。》
《圖三 這個CATC(LeCroy)匯流排追蹤圖顯示了本篇文章中所描述的主機端列舉步驟與過程。》

列舉動作之外

在執行以上描述的步驟後,主控端韌體會繼續檢查標準USB類別,例如人機介面設備或大容量儲存設備的描述符,接著執行設備特定程式碼來實際操作這些設備,不管設備所支援的類別為何,文章中所描述的列舉步驟都一樣通用。


結語

使用USB設備再也不是能夠具有無限資源以及大量內建多種設備型式驅動程式PC的專利,目前大部分的周邊設備都採用USB型式,因此開發適合小型嵌入式系統的USB主控端連接程式就變得相當有意義,雖然市場上已經有許多主控端控制器可以來完成低階的工作,但也必須撰寫主控端韌體來控制這些晶片,如果需要的是將介接設備限制在目標產品的USB單點式解決方案,那麼韌體本身就可以相當簡單。


(作者任職於美商美信(Maxim)公司)


相關文章
USB供電5.8 GHz RF LNA具有輸出電源保護
選擇USB轉接驅動器的須知三要點
輕鬆有趣地提高安全性:SoC元件協助人們保持健康
醫療設備高效電源管理之高性能設計
聚焦工業與網通 以生態系統觀點布局市場
comments powered by Disqus
相關討論
  相關新聞
» 貿澤開售TI新款車用乙太網路實體層收發器DP83TG721-Q1
» InnoVEX 2025沙龍座談 助新創搶攻亞洲市場
» 醫生實測:ChatGPT在診斷疾病方面更勝一籌
» 研究:成功掌握AI潛力的關鍵在於適應全球地緣政治與監管環境
» Red Hat收購Neural Magic 帶來生成式AI模型優化演算法


刊登廣告 新聞信箱 讀者信箱 著作權聲明 隱私權聲明 本站介紹

Copyright ©1999-2024 遠播資訊股份有限公司版權所有 Powered by O3  v3.20.2048.3.144.254.200
地址:台北數位產業園區(digiBlock Taipei) 103台北市大同區承德路三段287-2號A棟204室
電話 (02)2585-5526 #0 轉接至總機 /  E-Mail: webmaster@ctimes.com.tw