RTEMS管理機(jī)制與USB驅(qū)動(dòng)程序設(shè)計(jì)
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è)備由于某種原因無法對當(dāng)前命令進(jìn)行處理(如不能識別命令,或者沒有準(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ù)例程對各類中斷進(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)中斷,則按照圖5的流程處理。
3.3 USB設(shè)備類驅(qū)動(dòng)
USB設(shè)備類驅(qū)動(dòng)包含兩個(gè)功能:對標(biāo)準(zhǔn)命令的處理和對基于設(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ī)對總線上的USB設(shè)備的控制。USB設(shè)備必須對來自于主機(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)對某種標(biāo)準(zhǔn)USB設(shè)備類型或非標(biāo)準(zhǔn)USB設(shè)備類型的命令的支持,只需要在USB設(shè)備類驅(qū)動(dòng)層添加對該標(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請求提供的入口函數(shù)。
①初始化:rtems_device_driver usb_initialize(rtems_device_major_number maior,rtems_device_minor_numberminor,vold*arg)。在RTEMS系統(tǒng)中注冊USB設(shè)備的設(shè)備名,調(diào)用USB_Init實(shí)現(xiàn)設(shè)備的功能和狀態(tài)初始化,注冊中斷。
②打開: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)用對設(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)之一。本文對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)對特定USB設(shè)備類型的支持。同時(shí),由于與操作系統(tǒng)的耦合度較小,驅(qū)動(dòng)程序還可以方便地移植到其他的操作系統(tǒng)上。
評論