摘 要: 針對傳統(tǒng)開發(fā)模式存在的問題,,在原有工程基礎上對低速串行設備驅(qū)動程序進行了更改、封裝,,并提出了一種低速串行設備驅(qū)動層次化設計方法,。
關鍵詞: 層次化設計方法;低速串行設備,;設備驅(qū)動
隨著通信技術的發(fā)展,低速串行設備動態(tài)擴展和多低速串行設備全雙工通信技術在嵌入式領域的應用越來越廣泛。利用現(xiàn)場可編程門陣列FPGA(Field Programmable Gates Army)完全可以將若干接口電路的功能集成到一片F(xiàn)PGA中,,這不僅具有集成度高,、體積小和功耗低等優(yōu)點,而且還具有用戶可編程能力,,同時還可實現(xiàn)整個系統(tǒng)的功能重構以及項目過程中一些特殊低速串行設備傳輸方式,,這是專用低速串行設備實現(xiàn)芯片所不具備的功能。
嵌入式系統(tǒng)一般采用PowerPC+FPGA的架構方式,,F(xiàn)PGA主要完成底層接口協(xié)議處理,,PowerPC的任務主要實現(xiàn)控制功能。FPGA與PowerPC通過內(nèi)部總線(Local Bus)方式連接,,F(xiàn)PGA實現(xiàn)基于總線的時序操作,;采用內(nèi)存映射方式,F(xiàn)PGA實現(xiàn)的多個低速串行設備的設置,、操作寄存器以及FIFO的入口出口映射為PowerPC可尋址的一段內(nèi)存空間,,根據(jù)系統(tǒng)設計方法采用中斷復用方式或者使用多個PowerPC中斷號。
在驅(qū)動程序傳統(tǒng)開發(fā)過程中,,F(xiàn)PGA實現(xiàn)的多個低速串行設備驅(qū)動程序的設計不受驅(qū)動體系約束,,只是簡單地根據(jù)上層應用的需求提供接口,導致應用程序代碼可移植性,、可讀性差,,開發(fā)流程并行度不高,層次性不明確,。實際調(diào)試過程中則需要應用程序人員,、驅(qū)動開發(fā)人員同時對各自的程序進行修改、重新編譯,。
本文在原有工程基礎上對FPGA驅(qū)動程序進行了更改,、封裝,實現(xiàn)了基于FPGA的多個低速串行設備在VxWorks系統(tǒng)的標準I/O設備驅(qū)動,,并在此基礎上提出了一種低速串行設備驅(qū)動層次化設計方法,。
1 低速串行設備驅(qū)動程序設計
在VxWorks中,串行設備是一種特殊字符設備,。與字符設備不同的是,,串行設備的驅(qū)動程序并不是直接掛在I/O系統(tǒng)中,而是通過虛擬設備ttyDrv來使用[1],。ttyDrv與I/O系統(tǒng)以及真實驅(qū)動程序之間的關系如圖1所示,。
ttyDrv和tyLib實現(xiàn)了以下的功能[2]:(1)I/O系統(tǒng)請求(在驅(qū)動表中增加入口函數(shù),創(chuàng)建設備描述符等),;(2)管理I/O系統(tǒng)的入口函數(shù),,如tyOpen,,ttyIoctl,tyRead,,tyWrite等,;(3)管理selectLib的調(diào)用;(4)管理數(shù)據(jù)緩沖區(qū)以及緩沖區(qū)上的線程同步互斥,;(5)ttyDrv處理open和ioctl操作(ttyOpen and ttyIoctl),;(6)tyLib處理read和write操作(tyRead and tyWrite)。
真實的低速串行設備驅(qū)動函數(shù)(xxDrv)通過ttyDrv安裝的回調(diào)函數(shù)在I/O系統(tǒng)和設備之間移動數(shù)據(jù),;tyLib提供了2個回調(diào)函數(shù)(tyITx和tyIRd),。
1.1 標準驅(qū)動程序的構造
SIO_DRV_FUNCS結構體是串行設備驅(qū)動程序的一個重要的組成部分,它是驅(qū)動函數(shù)的入口,,在串行設備的驅(qū)動程序中必須要有一個包含指向SIO_DRV_FUNCS指針的結構(xx_CHAN),,xx_CHAN包含了xxDrv中所需要的設備特定信息,以及提供給高層函數(shù)的底層操作函數(shù),;由于系統(tǒng)不知道驅(qū)動函數(shù)中所使用的數(shù)據(jù)結構,,VxWorks提供了一個數(shù)據(jù)結構SIO_CHAN來進行數(shù)據(jù)類型轉(zhuǎn)換[3]。SIO_CHAN結構僅定義了一個指向SIO_DRV_FUNCS結構體的指針,。
FPGA實現(xiàn)的多個低速串行設備驅(qū)動程序的結構構造實例如下:
typedef struct{
/*SIO_CHAN*MUST*be first*/
SIO_CHAN sio,;/*standard SIO_CHAN element*/
UINT32* inBase; /*FIFO入口地址*/
UINT32* outBase,; /*FIFO出口地址*/
UINT32* baudFreqSetBase,; /*波特率設置地址*/
UINT32* IntSourceBase;/*中斷源寄存器地址*/
UINT32* inNumBase,;
/*FIFO有效數(shù)據(jù)長度寄存器地址*/
SEM_ID RecvSem,;/*對應的信號量*/
UINT32 intLevel;
UINT32 IntSourceMask,;/*中斷源寄存器掩碼*/
/*callbacks*/
STATUS (*getTxChar) (void*,,char*);
void (*putRcvChar) (void*,,char),;
void * getTxArg;
void * putRcvArg,;
} FPGA_CHAN,;
1.2 驅(qū)動函數(shù)和回調(diào)函數(shù)的掛接
ttyDrv通過SIO_DRV_FUNCS提供的入口對xxDrv的服務進行訪問,xxDrv通過回調(diào)函數(shù)來訪問ttyDrv提供的服務[4],。xxDrv驅(qū)動函數(shù)在SIO_DRV_FUNCS中的掛接實例如下:
LOCAL SIO_DRV_FUNCS fpgaSioDrvFuncs=
{
fpgaIoctl,, /*Support device specific ioctl cmds*/
fpgaTxStartup, /*Initiates a transmit cycle*/
fpgaCallbackInstall,,
/*Installs access to higher level protocols */
fpgaPollInput,,/*Poll mode input routine*/
fpgaPollOutput /*Poll mode output routine*/
},;
1.3 驅(qū)動程序標準操作函數(shù)的實現(xiàn)
1.3.1 標準寫函數(shù)
標準的I/O系統(tǒng)寫函數(shù)write()調(diào)用tyWrite()函數(shù)——ttyDrv加載在驅(qū)動表中的寫入口函數(shù),tyWrite()函數(shù)將數(shù)據(jù)放入環(huán)形緩沖隊列中并調(diào)用驅(qū)動函數(shù)fpgaTxStartup()發(fā)起一次傳輸過程,。write函數(shù)的調(diào)用關系如圖2所示,。
2 低速串行設備的加載
(1)根據(jù)實際需求修改config.h中NUM_TTYS宏,;
(2)參照sysSerialHwInit()函數(shù)實現(xiàn)FpgaSerialHwInit(),,對NUM_TTYS個低速串行設備結構體FPGA_CHAN進行初始化以及驅(qū)動函數(shù)和回調(diào)函數(shù)的掛接,;
(3)參照sysSerialHwInit2()函數(shù)實現(xiàn)FpgaSerialHwInit2(),,掛接中斷處理函數(shù)fpgaRcvInt(),;
(4)調(diào)用ttyDevCreate()函數(shù)創(chuàng)建tty設備,,添加設備驅(qū)動表,,生成環(huán)形數(shù)據(jù)緩沖區(qū),安裝回調(diào)函數(shù)tyITx()和tyIRd(),。
3 低速串行設備驅(qū)動層次化設計方法
在不同的系統(tǒng)設計中,,PowerPC和FPGA硬件連接方式不盡相同,如不同的片選信號,、總線上數(shù)據(jù)線高低位的不同接法,,中斷管腳接法的不同,導致FPGA實現(xiàn)的寄存器映射地址及使用的中斷號存在差異,;針對不同的應用程序和應用場所,,外部接口對應的設備也會發(fā)生相應的變化。以上這些都會破壞程序的獨立性,、設備無關性,。需要對驅(qū)動程序、應用程序進行重新編譯,、燒寫,,不利于版本的管理以及外場設備的維護。這是在設備驅(qū)動設計中需要考慮的一個問題,。
由此本文提出了一種層次化的低速串行設備驅(qū)動設計方法,。將驅(qū)動程序的實現(xiàn)分為三層,硬件分離層,、設備加載層和功能描述層,,各自實現(xiàn)的功能如下:
(1)硬件分離層:通過XML文件實現(xiàn)低速串行驅(qū)動程序結構初始化和硬件設備實現(xiàn)差異的分離,;
?。?)設備加載層:實現(xiàn)低速串行設備在VxWorks系統(tǒng)的標準I/O設備驅(qū)動的加載,;
(3)功能描述層:通過XML文件實現(xiàn)應用程序和低速串行設備之間的映射關系以及串行設備功能的描述,。
低速串行設備驅(qū)動層次化設計方法流程如圖5所示,。
3.1 層次化設計驅(qū)動程序的實現(xiàn)
嵌入式操作系統(tǒng)中,通常都使用Flash作為主存介質(zhì),。在Flash上建立TFFS文件系統(tǒng),,建立文件系統(tǒng)后,類似于在Windows操作系統(tǒng)下對硬盤操作一樣,,進行數(shù)據(jù)的拷貝,、刪除以及文件的建立等操作。XML作為配置文件的主要優(yōu)點是改變參數(shù)配置時不需要改變和重新編譯應用程序,,只需在XML文件中更改就可以了,。TinyXML是一個簡單小巧、且很容易集成到其他程序中的C++XML解析器,。即TinyXML解析一個XML文檔并由此生成一個可讀,、可修改、可保存的文檔對象模型(DOM),。本文的實現(xiàn)過程中使用TinyXML對XML文檔進行解析,。
低速串行設備驅(qū)動層次化設計方法建立在文件系統(tǒng)之上,VxWorks可以動態(tài)地加載用戶程序,,并在系統(tǒng)中加入對XML文件進行解析和存儲的功能,。
硬件分離層:FpgaSerialHwInit()通過讀取設備對應的BSP_Config.xml文件,對多個低速串行設備結構體FPGA_CHAN中的各個寄存器地址進行初始化以及驅(qū)動函數(shù)和回調(diào)函數(shù)的掛接,。
設備加載層:實現(xiàn)標準I/O設備驅(qū)動的加載,。
功能描述層:應用程序通過讀取USER_Config.xml文件,獲取設備的對外連接狀態(tài)及設備提供的功能,,對多個低速串行設備read,、write以及ioctl等操作。
通常設備驅(qū)動人員只需要進行對BSP_Config.xml和USER_Config.xml兩個配置文件進行修改,、更新,。
3.2 XML配置文件的設計及實現(xiàn)
BSP_Config.xml文件格式示例如下:
const char*bspXmlCfg=
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
"<Settings>"
"<DevSerial>"
"<inBase>\"10xd0100000\"</inBase>"
"<outBase>\"10xd0100100\"</outBase>"
……
"<IntSourceMask>\"10xd0100800\"</IntSourceMask>"
"</DevSerial>"
……
"</Settings>"
USER_Config.xml文件格式示例如下:
const char*userXmlCfg=
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<Settings>"
"<DevSerial>"
"<DevSerial Config Port=\"2\" Baud=\"38400\"
Enabled=\"1\"/>"
"</DevSerial>"
……
"</Settings>"
XML文件的遍歷和讀取方法如下:
TiXmlDocument doc(CONFIG_FILE_NAME);
bool loadOkay=doc.LoadFile(),;/*讀取文件*/
doc.Print(),;/*輸出打印*/
rootNode=doc.FirstChild("Settings");/*獲取根節(jié)點*/
……
node=rootNode->FirstChild("System"),;
/*獲取匹配的子節(jié)點*/
itemElement=node->ToElement(),;/*轉(zhuǎn)換為元素*/
itemElement->Attribute("Type",&dValue);/*讀取屬性*/
XML文件的保存和更新方法如下:
TiXmlDocument doc,;
doc.Parse(demoXmlCfg),;
/*讀取需要保存的XML文件框架結構*/
rootNode=doc.FirstChild("Settings");/*獲取根節(jié)點*/
……
node=rootNode->FirstChild("System"),;
/*獲取匹配的子節(jié)點*/
itemElement=node->ToElement(),;/*轉(zhuǎn)換為元素*/
itemElement->SetDoubleAttribute("Type",Type)
,;/*更新屬性*/
……
doc.SaveFile(CONFIG_FILE_NAME),;
/*存儲更新配置文件*/
本文提出并實現(xiàn)了一種VxWorks低速串行設備驅(qū)動的層次化設計方法,通過驅(qū)動程序功能分層設計方式,,屏蔽各層的實現(xiàn)細節(jié),,克服了嵌入式系統(tǒng)開發(fā)過程中,由于設備驅(qū)動程序的設計不受驅(qū)動體系約束帶來的程序代碼的可移植性,、可讀性差,開發(fā)流程并行度不高,,層次性不明確等不足之處,;在實際的工程實現(xiàn)中節(jié)約了開發(fā)時間,極大地提高了效率,。
參考文獻
[1] Vxworks kernel programmers guide[Z].Wind River Systems Inc,,2006.
[2] Vxworks device driver developers guide[Z]. Wind River Systems Inc, 2006.
[3] 內(nèi)核示例源代碼[Z]. Wind River Systems Inc,, 2006.
[4] 陳智育,,等.VxWorks程序開發(fā)實踐[M].北京:人民郵電出版社,2004.