基于RTEMS的USB設備驅動(dòng)程序設計

本文引用地址:http://dyxdggzs.com/article/247855.htm
3.2.2 端點(diǎn)狀態(tài)管理
USB設備與主機的通信可以通過(guò)對USB端點(diǎn)狀態(tài)的控制來(lái)完成。USB設備端點(diǎn)可以定義3個(gè)不同狀態(tài):空閑(Idle)狀態(tài)、停止(Halt)狀態(tài)和讀/寫(xiě)(W/R)狀態(tài)。USB硬件抽象層提供USB_ConfigureEndpoint、USB_Write、USB_Read、 USB_EndOfTransfer、USB_Stall、USB_HaIt和USB_ClearHalt七個(gè)功能函數對設備的狀態(tài)進(jìn)行管理,端點(diǎn)的狀態(tài)轉換過(guò)程如圖4所示。

USB_ConfiguIreEndpoint負責配置端點(diǎn)的最大包長(cháng)度和傳輸方向,并將端點(diǎn)狀態(tài)設置為空閑狀態(tài)。端點(diǎn)進(jìn)入空閑狀態(tài),如果上層調用 USB_Write進(jìn)行數據發(fā)送,將發(fā)送緩沖區指向要發(fā)送的數據,設置端點(diǎn)狀態(tài)為寫(xiě)狀態(tài),等待USB主機接收數據(真正的數據傳輸在中斷服務(wù)程序中進(jìn)行)。寫(xiě)完成后,端點(diǎn)回到空閑狀態(tài)。數據接收與發(fā)送類(lèi)似。如果設備出現某種錯誤,主機會(huì )向設備發(fā)送Set_Feature命令,設備接收到 Set_Feature命令,執行USB_Halt進(jìn)入停止狀態(tài)。端點(diǎn)處于停止狀態(tài)時(shí),如果接收到Clear_Feature,則執行USB— ClearHalt清除Halt標志,進(jìn)入Idle狀態(tài);如果USB設備由于某種原因無(wú)法對當前命令進(jìn)行處理(如不能識別命令,或者沒(méi)有準備好進(jìn)行數據傳輸),則執行USB_Stall通知主機發(fā)生錯誤,但端點(diǎn)的狀態(tài)不變。
3.2.3 中斷管理
在USB設備端,存在以下幾類(lèi)中斷:幀起始中斷、設備恢復中斷、設備掛起中斷和端點(diǎn)中斷。硬件抽象層的中斷服務(wù)例程對各類(lèi)中斷進(jìn)行響應,判斷中斷類(lèi)型。如果是與設備狀態(tài)相關(guān)的中斷,則需要調整設備到相應的狀態(tài),同時(shí)調用上層提供的相應回調函數;如果是端點(diǎn)中斷,則按照圖5的流程處理。

3.3 USB設備類(lèi)驅動(dòng)
USB設備類(lèi)驅動(dòng)包含兩個(gè)功能:對標準命令的處理和對基于設備類(lèi)的命令的處理。USB類(lèi)驅動(dòng)根據硬件抽象層提供的接口,與中斷服務(wù)程序協(xié)同管理USB設備和端點(diǎn)的狀態(tài)。通過(guò)為硬件抽象層的中斷服務(wù)程序提供相應的回調函數,完成特定設備類(lèi)要求的操作;同時(shí)根據RTEMS系統的設備管理機制,為應用程序提供設備驅動(dòng)的入口點(diǎn)。
3.3.1 標準命令處理
為了更好地協(xié)調USB主機與設備之間的數據通信,USB規范定義了一套命令,用于完成主機對總線(xiàn)上的USB設備的控制。 USB設備必須對來(lái)自于主機的控制命令做出響應。一般來(lái)說(shuō),命令都是通過(guò)設備的默認管道傳遞到設備的。USB協(xié)議定義了11個(gè)標準命令,用于配置設備、獲得設備的信息等操作。USB設備必須支持這些標準命令。
3.3.2 基于設備類(lèi)的命令處理
除了標準命令以外,USB每種設備類(lèi)的協(xié)議又定義了自己的類(lèi)命令。設備廠(chǎng)商為了使設備實(shí)現某種特殊的功能,還可以定義廠(chǎng)商專(zhuān)有的命令。
所有的命令雖然有不同的內容和使用目的,但也有一些共同的特點(diǎn):所有命令的結構是一樣的;USB命令是在控制傳輸的設置階段從USB主機發(fā)往設備的;如果除命令本身外,主機還打算向設備發(fā)送與命令相關(guān)的信息,那么這些信息將由緊跟在設置階段的數據階段發(fā)出;如果命令要求設備返回信息,這些信息會(huì )在控制傳輸的數據階段從設備端發(fā)出;當命令完成時(shí),設備會(huì )在握手階段返回ACK;設備可以返回Stall,表明不支持當前命令或無(wú)法完成命令要求的操作。
3.3.3 命令的處理流程
當設備接收到新的命令時(shí),硬件抽象層的中斷處理函數會(huì )調用USB設備類(lèi)驅動(dòng)層提供的回調函數;在回調函數中,判斷命令的類(lèi)型,如果是標準命令,則交給標準命令處理函數處理;否則,交給基于設備類(lèi)的命令處理函數處理。因此,要實(shí)現對某種標準USB設備類(lèi)型或非標準USB設備類(lèi)型的命令的支持,只需要在USB 設備類(lèi)驅動(dòng)層添加對該標準設備類(lèi)型命令或者自定義命令的處理函數,這樣使得程序易于擴展。
3.3.4 USB設備驅動(dòng)程序入口函數
RTEMS系統的設備驅動(dòng)程序應該包含下列入口函數:設備初始化例程、設備打開(kāi)例程、設備關(guān)閉例程、從設備中讀出數據的例程、向設備中寫(xiě)人數據的例程和特定于具體設備的設備操作例程。如果一個(gè)設備驅動(dòng)程序不支持某個(gè)特定的入口函數,在設備驅動(dòng)程序地址表中這個(gè)入口函數的地址值應該設置為空。以下6個(gè)函數是驅動(dòng)程序為標準I/O請求提供的入口函數。
①初始化:rtems_device_driver usb_initialize(rtems_device_major_number maior,rtems_device_minor_numberminor,vold*arg)。在RTEMS系統中注冊USB設備的設備名,調用 USB_Init實(shí)現設備的功能和狀態(tài)初始化,注冊中斷。
②打開(kāi):rtems_device_driver usb_open(rtems_device_major_number major,rtems_device_minor_number mi—nor,void*arg)。如果設備已經(jīng)被成功枚舉(處于配置態(tài))并且未被其他任務(wù)打開(kāi),則標記設備已被打開(kāi)標志,成功返回;否則,打開(kāi)失敗。
③關(guān)閉:rtems_device_driver usb_close(rtems_device_major_number major,rtems_device_minor_number mi—nor,void*arg)。清除設備打開(kāi)標志。
④讀操作:rtems_device_driver usb_read(rtems_de—vice_major_number major,rtems_device_minor_numberminor,void*arg)。調用USB_Read(),設置端點(diǎn)為讀狀態(tài),等待主機端發(fā)來(lái)的數據,數據到達后,中斷服務(wù)程序會(huì )把端點(diǎn)設置為空閑狀態(tài),函數將數據返回給應用程序。
⑤寫(xiě)操作:rtems_device_driver usb_write(rtems_de—vice_major_number major,rtems_device_minor_numberminor,void*arg)。調用USB_Write(),設置端點(diǎn)為寫(xiě)狀態(tài),并等待主機接收數據,數據發(fā)送完成后,中斷服務(wù)程序會(huì )將端點(diǎn)設置為空閑狀態(tài),函數返回。
⑥控制操作:rtems_device_driver usb_control(rtems_device_major_number major,rtems_device_minor_num—ber minor,void*arg)。具體操作根據需要定義。將設備驅動(dòng)程序的入口函數地址添加到設備驅動(dòng)程序地址表后,就可以通過(guò)RTEMS提供的I/0系統調用對設備進(jìn)行操作。
結 語(yǔ)
在RTEMS系統的移植和應用開(kāi)發(fā)過(guò)程中,設備驅動(dòng)程序的編寫(xiě)是十分重要的一環(huán)。USB由于其協(xié)議的復雜性,成為驅動(dòng)開(kāi)發(fā)中的難點(diǎn)之一。本文對RTEMS 系統下USB設備驅動(dòng)程序的設計與實(shí)現進(jìn)行了詳細論述,相應程序在A(yíng)T91RM9200開(kāi)發(fā)板上得以實(shí)現和驗證。本設計著(zhù)眼于程序的可移植性和可擴展性,采用層次結構,實(shí)現了硬件平臺與USB具體設備類(lèi)驅動(dòng)的分離,使其能夠方便地移植到其他硬件平臺上并實(shí)現對特定USB設備類(lèi)型的支持。同時(shí),由于與操作系統的耦合度較小,驅動(dòng)程序還可以方便地移植到其他的操作系統上。
評論