嵌入式系統(tǒng)中USB主機(jī)控制器的設(shè)計(jì)
框架數(shù)據(jù)流
框架代碼執(zhí)行過程是這樣的:上電復(fù)位、微處理器對(duì)所有寄存器和計(jì)數(shù)器以及設(shè)備結(jié)構(gòu)進(jìn)行初始化,然后進(jìn)入如下的循環(huán):
1.檢查主機(jī)USB端口是否存在狀態(tài)改變(設(shè)備插入或去除)。
2.檢查TD處理器,并獲得兩個(gè)SIE上運(yùn)行的所有TD狀態(tài)信息。
3.查看運(yùn)行設(shè)備驅(qū)動(dòng)程序列表并執(zhí)行每個(gè)程序的運(yùn)行函數(shù)。
檢查主機(jī)USB端口以了解狀態(tài)變化需要檢查變量的改變,如果發(fā)生變化,可通過端口變化中斷處理程序設(shè)定變量。如果端口發(fā)生改變,將執(zhí)行枚舉代碼進(jìn)行處理。
通過集線器至主機(jī)的中斷傳輸完成相連集線器變化值檢查,如果發(fā)生設(shè)備添加或去除,它們將像上面那樣枚舉出來。發(fā)現(xiàn)新設(shè)備時(shí),需要找到設(shè)備驅(qū)動(dòng)程序然后裝入。根據(jù)設(shè)備尋找設(shè)備驅(qū)動(dòng)程序的方法有很多種,框架代碼將首先嘗試將某驅(qū)動(dòng)程序與某設(shè)備的供應(yīng)商ID以及產(chǎn)品ID進(jìn)行匹配,但只有存在特定的制造商且特定設(shè)備在特定驅(qū)動(dòng)程序中運(yùn)行這種方法才有效。如果沒有實(shí)現(xiàn)匹配,框架代碼會(huì)嘗試對(duì)設(shè)備的種類和子類進(jìn)行匹配,這可以利用更普通的驅(qū)動(dòng)程序與設(shè)備匹配。
設(shè)備插入和去除檢查還有兩項(xiàng)額外的任務(wù)。如果連接的設(shè)備是集線器,則必須對(duì)其端口進(jìn)行檢查,以查看它們是否帶有設(shè)備。如果去除的設(shè)備是集線器,那么所有與之連接的設(shè)備也必須去除。
通過中斷傳輸還可以檢查來自相連鍵盤和鼠標(biāo)設(shè)備的新數(shù)據(jù),這些傳輸每10毫秒種發(fā)生一次,由TD處理器安排時(shí)序。任務(wù)完成后,TD處理器將傳輸控制轉(zhuǎn)給回調(diào)函數(shù),這時(shí)可提取鍵盤和鼠標(biāo)數(shù)據(jù),并送至應(yīng)用層。
構(gòu)建應(yīng)用
現(xiàn)在介紹如何構(gòu)建一個(gè)簡單的控制鍵盤和鼠標(biāo)的嵌入式USB設(shè)計(jì),該方案使用基于處理器的USB主機(jī)控制器,處理器的代碼包含框架和應(yīng)用固件。首先要做的是確定希望支持設(shè)備的數(shù)量和類型,確定設(shè)備數(shù)量后,可據(jù)此分配URB和驅(qū)動(dòng)程序空間,通過修改名為fwxcfg.h的“個(gè)性化”文件完成URB分配。
每個(gè)鍵盤、鼠標(biāo)或集線器均需要一個(gè)URB來處理傳輸中重復(fù)出現(xiàn)的中斷。此外,在枚舉和其它USB控制傳輸過程中,URB被分配并隨后釋放。一個(gè)較好的經(jīng)驗(yàn)是為系統(tǒng)支持的每個(gè)設(shè)備分配兩個(gè)URB,一個(gè)用于傳輸中重復(fù)出現(xiàn)的中斷,另一個(gè)則用于任何可能的控制傳輸,這些傳輸可能發(fā)生在設(shè)備枚舉或設(shè)備狀態(tài)檢查過程中。雖然每次只能處理一個(gè)控制傳輸,但框架可將其它傳輸排隊(duì),系統(tǒng)支持的URB數(shù)量應(yīng)該等于所支持設(shè)備數(shù)量的兩倍。
接下來,需要為鍵盤和鼠標(biāo)創(chuàng)建驅(qū)動(dòng)程序。由于這些設(shè)備的USB功能非常相近,所以兩個(gè)設(shè)備可以使用一個(gè)驅(qū)動(dòng)程序。該驅(qū)動(dòng)程序可稱為hid_driver(用于人機(jī)界面設(shè)備的驅(qū)動(dòng)程序)。下一步是在驅(qū)動(dòng)程序內(nèi)添加開始、停止以及運(yùn)行函數(shù),以及查找驅(qū)動(dòng)程序的設(shè)備種類編碼,還需要將驅(qū)動(dòng)程序函數(shù)的名稱添加進(jìn)文件drvrlist.h。包含集線器和hid driver的驅(qū)動(dòng)程序聲明如下: #define FWX_DRIVER_LIST {hid_driver, hubclass_driver}
hid_driver啟動(dòng)函數(shù)將分配傳輸中重復(fù)出現(xiàn)的中斷,以獲得鍵盤和鼠標(biāo)數(shù)據(jù)。該函數(shù)內(nèi)的編碼將獲取數(shù)據(jù)并將數(shù)據(jù)傳給編碼應(yīng)用層;停止函數(shù)將釋放重復(fù)出現(xiàn)的中斷傳輸,并通知應(yīng)用層設(shè)備已被去除;運(yùn)行函數(shù)用來檢查來自應(yīng)用代碼的輸入指令。
然后需要為枚舉通報(bào)函數(shù)添加一些代碼,枚舉通報(bào)函數(shù)是枚舉代碼使用的回調(diào)函數(shù),用于報(bào)告設(shè)備枚舉狀態(tài)并處理可能的枚舉錯(cuò)誤。該代碼可將新的枚舉設(shè)備信息傳給應(yīng)用層。
在這里對(duì)集線器提供支持很容易,不需要添加任何代碼,也不需要編寫驅(qū)動(dòng)程序,因?yàn)榭蚣芤寻?qū)動(dòng)程序。所要做的是更改fwxcfg.h中的語句,即將
#undef FWX_INCLUDE_HUB_SUPPORT
改為
#define FWX_INCLUDE_HUB_SUPPORT
并將文件hubclass.c添加進(jìn)項(xiàng)目形成文件,其余事務(wù)由框架處理。
本文小結(jié)
盡管與PC相比,USB主機(jī)系統(tǒng)在計(jì)算資源和經(jīng)驗(yàn)方面存在不足,但開發(fā)人員仍然可以較為簡單地將USB功能加入到嵌入式系統(tǒng)中?,F(xiàn)有多種用于實(shí)現(xiàn)這種功能的USB主機(jī)IC可供選擇,用戶可購買或自行開發(fā)USB主機(jī)堆棧和實(shí)時(shí)操作系統(tǒng)。
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
評(píng)論