引 言 在航空航天和工業(yè)控制等一些嵌入式應(yīng)用領(lǐng)域,,要求控制系統(tǒng)具有嚴(yán)格的實(shí)時(shí)性,,能夠?yàn)槿蝿?wù)提供一個(gè)可預(yù)見的響應(yīng)時(shí)間。一些實(shí)時(shí)操作系統(tǒng)的引入可以有效地滿足任務(wù)的實(shí)時(shí)性要求,,如RTEMS和VxWorks,。在這樣的系統(tǒng)中,如果系統(tǒng)通信模塊的通信速度不高,,或者通信質(zhì)量不可靠,,就會(huì)影響整個(gè)系統(tǒng)的實(shí)時(shí)性能。通用串行總線(USB)由于其高帶寬,、高可靠性的特點(diǎn),,必將越來越多地應(yīng)用到這類系統(tǒng)中。然而由于多數(shù)實(shí)時(shí)操作系統(tǒng)目前并未提供USB主機(jī)和設(shè)備的驅(qū)動(dòng),,而且USB協(xié)議相對(duì)于其他串行通信協(xié)議(RS232,、SPI等)復(fù)雜度較高,使得USB驅(qū)動(dòng)程序的開發(fā)難度較大,。
1 RTEMS及其設(shè)備管理機(jī)制 1.1 RTEMS簡介 RTEMS(Real—Time Executive for MultiprocessorSystem)是一個(gè)為嵌入式應(yīng)用系統(tǒng)提供高性能支持環(huán)境的實(shí)時(shí)操作系統(tǒng)內(nèi)核,,早期用于美國軍方的導(dǎo)彈系統(tǒng)。RTEMS的實(shí)時(shí)性能高于RTLinux,,與VxWorks相比也毫不遜色,。 RTEMS具有如下特點(diǎn):支持多任務(wù);支持同構(gòu)或異構(gòu)多處理器系統(tǒng),;支持事件驅(qū)動(dòng),、基于優(yōu)先級(jí)、占先的調(diào)度算法,,具有單調(diào)速率調(diào)度算法,;支持任務(wù)間的通信和同步;支持優(yōu)先級(jí)繼承算法,,快速響應(yīng)的中斷管理,;支持動(dòng)態(tài)存儲(chǔ)器分配,,具有用戶配置的能力。 RTEMS是微內(nèi)核搶占式的實(shí)時(shí)操作系統(tǒng),,具有實(shí)時(shí)性能好,、運(yùn)行速度快和可靠性高等優(yōu)點(diǎn),在通信,、航空航天,、工業(yè)控制等領(lǐng)域有著非常廣泛的應(yīng)用。 1.2 設(shè)備管理機(jī)制 操作系統(tǒng)的一個(gè)重要功能就是為應(yīng)用程序提供一個(gè)統(tǒng)一的I/O設(shè)備的虛擬接口,,使用戶程序能夠按照相同的模式對(duì)設(shè)備進(jìn)行操作,,無需關(guān)心每個(gè)設(shè)備的具體特性。 RTEMS系統(tǒng)提出了一種設(shè)備抽象模型,,使用這種模型,,應(yīng)用程序通過相同的I/O系統(tǒng)調(diào)用塒沒備進(jìn)行操作,而不必關(guān)心實(shí)現(xiàn)細(xì)節(jié),。RTEMS的I/O管理器提供的系統(tǒng)調(diào)用包括: ◆rIems_io_initialize,初始化一個(gè)設(shè)備驅(qū)動(dòng)程序,; ◆rtems_io_register_name,,注冊(cè)一個(gè)設(shè)備名; ◆rIems_io_lookup_name,,根據(jù)設(shè)備名查找主/副設(shè)備號(hào),; ◆rterns_io_open,打開一個(gè)設(shè)備,; ◆rteros_io_close,,關(guān)閉一個(gè)設(shè)備; ◆rtems_io_read,,從一個(gè)設(shè)備中執(zhí)行讀操作,; ◆rtems_io_write,向一個(gè)設(shè)備中執(zhí)行寫操作,; ◆rteros_io_control,,特殊的設(shè)備服務(wù)。 RTEMS系統(tǒng)使用設(shè)備驅(qū)動(dòng)程序地址表來提供這種抽象,,在這個(gè)表中提供了每個(gè)標(biāo)準(zhǔn)I/O請(qǐng)求處理函數(shù)的入口地址,。RTEMS使用設(shè)備的主設(shè)備號(hào)和副設(shè)備號(hào)來定位它的驅(qū)動(dòng)程序。主設(shè)備號(hào)是設(shè)備驅(qū)動(dòng)程序地址表中相應(yīng)設(shè)備表項(xiàng)的索引,,用于選擇某個(gè)設(shè)備驅(qū)動(dòng)程序,;副設(shè)備號(hào)的用途則依賴于具體的設(shè)備驅(qū)動(dòng)程序,通常用于在相同設(shè)備驅(qū)動(dòng)程序所控制的若干設(shè)備中指定特定的設(shè)備,。在RTEMS系統(tǒng)中,,每個(gè)特定的設(shè)備都有與之相關(guān)聯(lián)的設(shè)備名稱,。RTEMS系統(tǒng)內(nèi)核中包含了一個(gè)“設(shè)備驅(qū)動(dòng)程序文件名表”。這個(gè)表將設(shè)備文件名與設(shè)備的主,、副設(shè)備號(hào)聯(lián)系起來,,應(yīng)用程序可以使用注冊(cè)設(shè)備名查找與一個(gè)設(shè)備相關(guān)聯(lián)的主設(shè)備號(hào)/副設(shè)備號(hào),進(jìn)而通過標(biāo)準(zhǔn)I/0系統(tǒng)調(diào)用和主設(shè)備號(hào)/副設(shè)備號(hào)在設(shè)備驅(qū)動(dòng)程序地址表中找到該設(shè)備的驅(qū)動(dòng)程序的入口函數(shù)地址,,對(duì)設(shè)備進(jìn)行操作,。 RTEMS系統(tǒng)在初始化時(shí),會(huì)調(diào)用各個(gè)設(shè)備驅(qū)動(dòng)程序的初始化函數(shù),,初始化所有的設(shè)備驅(qū)動(dòng)程序,。當(dāng)應(yīng)用程序需要對(duì)設(shè)備進(jìn)行操作時(shí),會(huì)執(zhí)行有關(guān)設(shè)備管理的I/O系統(tǒng)調(diào)用,,RTEMS會(huì)根據(jù)該系統(tǒng)調(diào)用判斷應(yīng)該選擇的設(shè)備驅(qū)動(dòng)程序的入口函數(shù),。由應(yīng)用程序傳遞給RTEMS的信息,將被傳遞給適當(dāng)?shù)脑O(shè)備驅(qū)動(dòng)程序入口函數(shù),。
2 USB通信協(xié)議簡介 USB(Universal Serial Bus,,通用串行總線)是一種在主機(jī)和設(shè)備之間進(jìn)行串行數(shù)據(jù)傳輸?shù)耐ㄐ艆f(xié)議。USB接口由于速度快,、可靠性高,、功耗低等優(yōu)點(diǎn),已成為當(dāng)前微機(jī)的必備接口,,同時(shí)也被廣泛應(yīng)用于嵌入式系統(tǒng)設(shè)計(jì)中心,。USB的物理拓?fù)錇榉謱拥男切徒Y(jié)構(gòu),由3部分組成——USB主機(jī),、USB集線器和USB設(shè)備,,如圖l所示。 USB主機(jī)是USB系統(tǒng)的主控組件,,控制總線上所有USB設(shè)備和USB集線器的數(shù)據(jù)通信過程,,所有的數(shù)據(jù)傳輸都是由USB主機(jī)端發(fā)起的。 USB主機(jī)控制器的復(fù)雜度要遠(yuǎn)遠(yuǎn)高于USB設(shè)備,,典型的USB主機(jī)控制器大約需要10 000個(gè)門電路,,而設(shè)備端的USB接口大約需要1 500個(gè)門電路。正是由于這種設(shè)計(jì)復(fù)雜度的不平等,,使得USB設(shè)備得以在短時(shí)間內(nèi)得到廣泛應(yīng)用,。
3 RTEMS下USB設(shè)備驅(qū)動(dòng)程序的設(shè)計(jì) 3.1 概 述 嵌入式系統(tǒng)的硬件環(huán)境千差萬別,各類USB設(shè)備的類規(guī)范也各不相同,。為了確保程序的可移植性和可擴(kuò)展性,,將程序設(shè)計(jì)為二層結(jié)構(gòu):硬件抽象層和USB設(shè)備類驅(qū)動(dòng)層,如圖2所示,。 硬件抽象層封裝對(duì)底層USB設(shè)備控制器的操作和對(duì)中斷的處理,,通過一些標(biāo)準(zhǔn)方法,,為上層提供一個(gè)底層的硬件抽象,便于移植,。USB設(shè)備類驅(qū)動(dòng)層包含對(duì)標(biāo)準(zhǔn)命令和對(duì)特定設(shè)備類命令的處理,。 3.2 硬件抽象層 硬件抽象層對(duì)USB設(shè)備控制器進(jìn)行操作,實(shí)現(xiàn)以下功能:設(shè)備狀態(tài)管理,、端點(diǎn)狀態(tài)管理和中斷管理,。 3.2.1 設(shè)備狀態(tài)管理 每一個(gè)USB設(shè)備在正常工作前必須完成主機(jī)對(duì)它的配置過程,即總線枚舉,。USB設(shè)備在總線上共有6種狀態(tài):接入態(tài),、加電態(tài)、默認(rèn)態(tài),、地址態(tài),、配置態(tài)和掛起態(tài)。 硬件抽象層提供USB_Init,、USB_Attach,、USB_Disat—tach、USB_Connect,、USB_Disconnect,、USB_SetAddress、USB_ResetAddress,、USB_SetConfiguration和USB_ResetConfiguration九個(gè)函數(shù)對(duì)設(shè)備的狀態(tài)進(jìn)行管理。一般來說,,設(shè)備在總線上的狀態(tài)變化都會(huì)由中斷通知設(shè)備,,中斷服務(wù)程序根據(jù)中斷類型和當(dāng)前狀態(tài)通過提供的功能接口對(duì)沒備進(jìn)行相應(yīng)的操作,確保設(shè)備能夠完成枚舉過程÷順利進(jìn)入配置態(tài),。設(shè)備在硬件抽象層函數(shù)控制下的在總線上的狀態(tài)機(jī)如圖3所示,。由于掛起與恢復(fù)無需軟件干預(yù),因此沒有在狀態(tài)機(jī)中描述這一狀態(tài),。 3.2.2 端點(diǎn)狀態(tài)管理 USB設(shè)備與主機(jī)的通信可以通過對(duì)USB端點(diǎn)狀態(tài)的控制來完成,。USB設(shè)備端點(diǎn)可以定義3個(gè)不同狀態(tài):空閑(Idle)狀態(tài)、停止(Halt)狀態(tài)和讀/寫(W/R)狀態(tài),。USB硬件抽象層提供USB_ConfigureEndpoint,、USB_Write、USB_Read,、USB_EndOfTransfer,、USB_Stall、USB_HaIt和USB_ClearHalt七個(gè)功能函數(shù)對(duì)設(shè)備的狀態(tài)進(jìn)行管理,,端點(diǎn)的狀態(tài)轉(zhuǎn)換過程如圖4所示,。 USB_ConfiguIreEndpoint負(fù)責(zé)配置端點(diǎn)的最大包長度和傳輸方向,,并將端點(diǎn)狀態(tài)設(shè)置為空閑狀態(tài)。端點(diǎn)進(jìn)入空閑狀態(tài),,如果上層調(diào)用USB_Write進(jìn)行數(shù)據(jù)發(fā)送,,將發(fā)送緩沖區(qū)指向要發(fā)送的數(shù)據(jù),設(shè)置端點(diǎn)狀態(tài)為寫狀態(tài),,等待USB主機(jī)接收數(shù)據(jù)(真正的數(shù)據(jù)傳輸在中斷服務(wù)程序中進(jìn)行),。寫完成后,端點(diǎn)回到空閑狀態(tài),。數(shù)據(jù)接收與發(fā)送類似,。如果設(shè)備出現(xiàn)某種錯(cuò)誤,主機(jī)會(huì)向設(shè)備發(fā)送Set_Feature命令,,設(shè)備接收到Set_Feature命令,,執(zhí)行USB_Halt進(jìn)入停止?fàn)顟B(tài)。端點(diǎn)處于停止?fàn)顟B(tài)時(shí),,如果接收到Clear_Feature,,則執(zhí)行USB—ClearHalt清除Halt標(biāo)志,進(jìn)入Idle狀態(tài),;如果USB設(shè)備由于某種原因無法對(duì)當(dāng)前命令進(jìn)行處理(如不能識(shí)別命令,,或者沒有準(zhǔn)備好進(jìn)行數(shù)據(jù)傳輸),則執(zhí)行USB_Stall通知主機(jī)發(fā)生錯(cuò)誤,,但端點(diǎn)的狀態(tài)不變,。 3.2.3 中斷管理 在USB設(shè)備端,存在以下幾類中斷:幀起始中斷,、設(shè)備恢復(fù)中斷,、設(shè)備掛起中斷和端點(diǎn)中斷。硬件抽象層的中斷服務(wù)例程對(duì)各類中斷進(jìn)行響應(yīng),,判斷中斷類型,。如果是與設(shè)備狀態(tài)相關(guān)的中斷,則需要調(diào)整設(shè)備到相應(yīng)的狀態(tài),,同時(shí)調(diào)用上層提供的相應(yīng)回調(diào)函數(shù),;如果是端點(diǎn)中斷,則按照?qǐng)D5的流程處理,。 3.3 USB設(shè)備類驅(qū)動(dòng) USB設(shè)備類驅(qū)動(dòng)包含兩個(gè)功能:對(duì)標(biāo)準(zhǔn)命令的處理和對(duì)基于設(shè)備類的命令的處理,。USB類驅(qū)動(dòng)根據(jù)硬件抽象層提供的接口,與中斷服務(wù)程序協(xié)同管理USB設(shè)備和端點(diǎn)的狀態(tài),。通過為硬件抽象層的中斷服務(wù)程序提供相應(yīng)的回調(diào)函數(shù),,完成特定設(shè)備類要求的操作;同時(shí)根據(jù)RTEMS系統(tǒng)的設(shè)備管理機(jī)制,,為應(yīng)用程序提供設(shè)備驅(qū)動(dòng)的入口點(diǎn),。 3.3.1 標(biāo)準(zhǔn)命令處理 為了更好地協(xié)調(diào)USB主機(jī)與設(shè)備之間的數(shù)據(jù)通信,,USB規(guī)范定義了一套命令,用于完成主機(jī)對(duì)總線上的USB設(shè)備的控制,。USB設(shè)備必須對(duì)來自于主機(jī)的控制命令做出響應(yīng),。一般來說,命令都是通過設(shè)備的默認(rèn)管道傳遞到設(shè)備的,。USB協(xié)議定義了11個(gè)標(biāo)準(zhǔn)命令,,用于配置設(shè)備、獲得設(shè)備的信息等操作,。USB設(shè)備必須支持這些標(biāo)準(zhǔn)命令,。 3.3.2 基于設(shè)備類的命令處理 除了標(biāo)準(zhǔn)命令以外,USB每種設(shè)備類的協(xié)議又定義了自己的類命令,。設(shè)備廠商為了使設(shè)備實(shí)現(xiàn)某種特殊的功能,,還可以定義廠商專有的命令。 所有的命令雖然有不同的內(nèi)容和使用目的,,但也有一些共同的特點(diǎn):所有命令的結(jié)構(gòu)是一樣的,;USB命令是在控制傳輸?shù)脑O(shè)置階段從USB主機(jī)發(fā)往設(shè)備的;如果除命令本身外,,主機(jī)還打算向設(shè)備發(fā)送與命令相關(guān)的信息,,那么這些信息將由緊跟在設(shè)置階段的數(shù)據(jù)階段發(fā)出;如果命令要求設(shè)備返回信息,,這些信息會(huì)在控制傳輸?shù)臄?shù)據(jù)階段從設(shè)備端發(fā)出,;當(dāng)命令完成時(shí),設(shè)備會(huì)在握手階段返回ACK,;設(shè)備可以返回Stall,,表明不支持當(dāng)前命令或無法完成命令要求的操作。 3.3.3 命令的處理流程 當(dāng)設(shè)備接收到新的命令時(shí),,硬件抽象層的中斷處理函數(shù)會(huì)調(diào)用USB設(shè)備類驅(qū)動(dòng)層提供的回調(diào)函數(shù);在回調(diào)函數(shù)中,,判斷命令的類型,,如果是標(biāo)準(zhǔn)命令,則交給標(biāo)準(zhǔn)命令處理函數(shù)處理,;否則,,交給基于設(shè)備類的命令處理函數(shù)處理。因此,,要實(shí)現(xiàn)對(duì)某種標(biāo)準(zhǔn)USB設(shè)備類型或非標(biāo)準(zhǔn)USB設(shè)備類型的命令的支持,,只需要在USB設(shè)備類驅(qū)動(dòng)層添加對(duì)該標(biāo)準(zhǔn)設(shè)備類型命令或者自定義命令的處理函數(shù),這樣使得程序易于擴(kuò)展,。 3.3.4 USB設(shè)備驅(qū)動(dòng)程序入口函數(shù) RTEMS系統(tǒng)的設(shè)備驅(qū)動(dòng)程序應(yīng)該包含下列入口函數(shù):設(shè)備初始化例程,、設(shè)備打開例程,、設(shè)備關(guān)閉例程、從設(shè)備中讀出數(shù)據(jù)的例程,、向設(shè)備中寫人數(shù)據(jù)的例程和特定于具體設(shè)備的設(shè)備操作例程,。如果一個(gè)設(shè)備驅(qū)動(dòng)程序不支持某個(gè)特定的入口函數(shù),在設(shè)備驅(qū)動(dòng)程序地址表中這個(gè)入口函數(shù)的地址值應(yīng)該設(shè)置為空,。以下6個(gè)函數(shù)是驅(qū)動(dòng)程序?yàn)闃?biāo)準(zhǔn)I/O請(qǐng)求提供的入口函數(shù),。 ①初始化:rtems_device_driver usb_initialize(rtems_device_major_number maior,rtems_device_minor_numberminor,,vold*arg),。在RTEMS系統(tǒng)中注冊(cè)USB設(shè)備的設(shè)備名,調(diào)用USB_Init實(shí)現(xiàn)設(shè)備的功能和狀態(tài)初始化,,注冊(cè)中斷,。 ②打開:rtems_device_driver usb_open(rtems_device_major_number major,rtems_device_minor_number mi—nor,,void*arg),。如果設(shè)備已經(jīng)被成功枚舉(處于配置態(tài))并且未被其他任務(wù)打開,則標(biāo)記設(shè)備已被打開標(biāo)志,,成功返回,;否則,打開失敗,。 ③關(guān)閉:rtems_device_driver usb_close(rtems_device_major_number major,,rtems_device_minor_number mi—nor,void*arg),。清除設(shè)備打開標(biāo)志,。 ④讀操作:rtems_device_driver usb_read(rtems_de—vice_major_number major,rtems_device_minor_numberminor,,void*arg),。調(diào)用USB_Read(),設(shè)置端點(diǎn)為讀狀態(tài),,等待主機(jī)端發(fā)來的數(shù)據(jù),,數(shù)據(jù)到達(dá)后,中斷服務(wù)程序會(huì)把端點(diǎn)設(shè)置為空閑狀態(tài),,函數(shù)將數(shù)據(jù)返回給應(yīng)用程序,。 ⑤寫操作:rtems_device_driver usb_write(rtems_de—vice_major_number major,rtems_device_minor_numberminor,,void*arg),。調(diào)用USB_Write(),設(shè)置端點(diǎn)為寫狀態(tài),并等待主機(jī)接收數(shù)據(jù),,數(shù)據(jù)發(fā)送完成后,,中斷服務(wù)程序會(huì)將端點(diǎn)設(shè)置為空閑狀態(tài),函數(shù)返回,。 ⑥控制操作:rtems_device_driver usb_control(rtems_device_major_number major,,rtems_device_minor_num—ber minor,void*arg),。具體操作根據(jù)需要定義,。將設(shè)備驅(qū)動(dòng)程序的入口函數(shù)地址添加到設(shè)備驅(qū)動(dòng)程序地址表后,就可以通過RTEMS提供的I/0系統(tǒng)調(diào)用對(duì)設(shè)備進(jìn)行操作,。
結(jié) 語 在RTEMS系統(tǒng)的移植和應(yīng)用開發(fā)過程中,,設(shè)備驅(qū)動(dòng)程序的編寫是十分重要的一環(huán)。USB由于其協(xié)議的復(fù)雜性,,成為驅(qū)動(dòng)開發(fā)中的難點(diǎn)之一,。本文對(duì)RTEMS系統(tǒng)下USB設(shè)備驅(qū)動(dòng)程序的設(shè)計(jì)與實(shí)現(xiàn)進(jìn)行了詳細(xì)論述,相應(yīng)程序在AT91RM9200開發(fā)板上得以實(shí)現(xiàn)和驗(yàn)證,。本設(shè)計(jì)著眼于程序的可移植性和可擴(kuò)展性,,采用層次結(jié)構(gòu),實(shí)現(xiàn)了硬件平臺(tái)與USB具體設(shè)備類驅(qū)動(dòng)的分離,,使其能夠方便地移植到其他硬件平臺(tái)上并實(shí)現(xiàn)對(duì)特定USB設(shè)備類型的支持,。同時(shí),由于與操作系統(tǒng)的耦合度較小,,驅(qū)動(dòng)程序還可以方便地移植到其他的操作系統(tǒng)上,。
|