不管是periodic list or non-periodic list,ED和TD的連接方式大概如下圖所示:
大家都知道USB基本的結構把每個device assign一個address,
並且每個device會有一些endpoints,透過address & endpoint number(ED裡面有address和endpoint欄位),
HC可以區分要把TD送到哪個device,對特定的endpoint做資料傳輸的動作。
不同的ED就代表不同的devices上的endpoint,對每個特定endpoint做動作就是TD。
舉個例子來說Control transferr基本上傳輸到address 0的endpoint 0,
所以address 0 & endpoint 0就佔有一個ED。一個Control transfer後面
接了三個transaction(setup, data, transaction)所以,會有三個TD接在ED後面。
接下來看ED的structure:值得注意的是寫code的時候ed structu要記得16 bytes aligned。
每個field的詳細內容:
spec 4.2.3 Endpoint Descriptor Description裡幾個keypoints:
1. 檢查Halted bit & sKip bit是否有on,若無繼續判斷ED裡是否有可以run的TD為比較HeadP == TailP。
如果不等於,則代表有TD可以被執行。
因此,需要一個dummy TD當空的,作為比較用。
2. 當HC想要修改ED裡面的欄位,如HeadP,則可以設sKip bit。
若是使用把ED整個移除掉,這樣要disable list(在HcControl register裡PeriodicListEnable, IsochronousEnable, ControlListEnable, BulkListEnable看是要砍哪個transfer的ED),整個cost太大。
HCD不應該直接動ED的HeadP/toggleCarry/Halted field,除非Halted & sKip bit有on。
這個可以衍生為只要修改ED or TD有兩種方式。第一:disable ED。第二:set sKip bit。
3. 執行完TD,有錯則設置Halted bit,並且把TD移到Done Queue。
直到HCD處理完錯誤狀況,HC才會繼續處理這個ED,不然HC看到Halted & sKip就直接跳過。
0 意見:
Post a Comment