《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 設(shè)計(jì)應(yīng)用 > VxWorks中低速串行設(shè)備驅(qū)動(dòng)的層次化設(shè)計(jì)方法
VxWorks中低速串行設(shè)備驅(qū)動(dòng)的層次化設(shè)計(jì)方法
來源:微型機(jī)與應(yīng)用2013年第3期
曾 勇
(中國西南電子技術(shù)研究所,四川 成都 610036)
摘要: 針對(duì)傳統(tǒng)開發(fā)模式存在的問題,在原有工程基礎(chǔ)上對(duì)低速串行設(shè)備驅(qū)動(dòng)程序進(jìn)行了更改、封裝,并提出了一種低速串行設(shè)備驅(qū)動(dòng)層次化設(shè)計(jì)方法。
Abstract:
Key words :

摘  要: 針對(duì)傳統(tǒng)開發(fā)模式存在的問題,在原有工程基礎(chǔ)上對(duì)低速串行設(shè)備驅(qū)動(dòng)程序進(jìn)行了更改、封裝,并提出了一種低速串行設(shè)備驅(qū)動(dòng)層次化設(shè)計(jì)方法。
關(guān)鍵詞: 層次化設(shè)計(jì)方法;低速串行設(shè)備;設(shè)備驅(qū)動(dòng)

 隨著通信技術(shù)的發(fā)展,低速串行設(shè)備動(dòng)態(tài)擴(kuò)展和多低速串行設(shè)備全雙工通信技術(shù)在嵌入式領(lǐng)域的應(yīng)用越來越廣泛。利用現(xiàn)場可編程門陣列FPGA(Field Programmable Gates Army)完全可以將若干接口電路的功能集成到一片F(xiàn)PGA中,這不僅具有集成度高、體積小和功耗低等優(yōu)點(diǎn),而且還具有用戶可編程能力,同時(shí)還可實(shí)現(xiàn)整個(gè)系統(tǒng)的功能重構(gòu)以及項(xiàng)目過程中一些特殊低速串行設(shè)備傳輸方式,這是專用低速串行設(shè)備實(shí)現(xiàn)芯片所不具備的功能。
 嵌入式系統(tǒng)一般采用PowerPC+FPGA的架構(gòu)方式,F(xiàn)PGA主要完成底層接口協(xié)議處理,PowerPC的任務(wù)主要實(shí)現(xiàn)控制功能。FPGA與PowerPC通過內(nèi)部總線(Local Bus)方式連接,F(xiàn)PGA實(shí)現(xiàn)基于總線的時(shí)序操作;采用內(nèi)存映射方式,F(xiàn)PGA實(shí)現(xiàn)的多個(gè)低速串行設(shè)備的設(shè)置、操作寄存器以及FIFO的入口出口映射為PowerPC可尋址的一段內(nèi)存空間,根據(jù)系統(tǒng)設(shè)計(jì)方法采用中斷復(fù)用方式或者使用多個(gè)PowerPC中斷號(hào)。
在驅(qū)動(dòng)程序傳統(tǒng)開發(fā)過程中,F(xiàn)PGA實(shí)現(xiàn)的多個(gè)低速串行設(shè)備驅(qū)動(dòng)程序的設(shè)計(jì)不受驅(qū)動(dòng)體系約束,只是簡單地根據(jù)上層應(yīng)用的需求提供接口,導(dǎo)致應(yīng)用程序代碼可移植性、可讀性差,開發(fā)流程并行度不高,層次性不明確。實(shí)際調(diào)試過程中則需要應(yīng)用程序人員、驅(qū)動(dòng)開發(fā)人員同時(shí)對(duì)各自的程序進(jìn)行修改、重新編譯。
本文在原有工程基礎(chǔ)上對(duì)FPGA驅(qū)動(dòng)程序進(jìn)行了更改、封裝,實(shí)現(xiàn)了基于FPGA的多個(gè)低速串行設(shè)備在VxWorks系統(tǒng)的標(biāo)準(zhǔn)I/O設(shè)備驅(qū)動(dòng),并在此基礎(chǔ)上提出了一種低速串行設(shè)備驅(qū)動(dòng)層次化設(shè)計(jì)方法。
1 低速串行設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)
 在VxWorks中,串行設(shè)備是一種特殊字符設(shè)備。與字符設(shè)備不同的是,串行設(shè)備的驅(qū)動(dòng)程序并不是直接掛在I/O系統(tǒng)中,而是通過虛擬設(shè)備ttyDrv來使用[1]。ttyDrv與I/O系統(tǒng)以及真實(shí)驅(qū)動(dòng)程序之間的關(guān)系如圖1所示。
ttyDrv和tyLib實(shí)現(xiàn)了以下的功能[2]:(1)I/O系統(tǒng)請(qǐng)求(在驅(qū)動(dòng)表中增加入口函數(shù),創(chuàng)建設(shè)備描述符等);(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)。

 真實(shí)的低速串行設(shè)備驅(qū)動(dòng)函數(shù)(xxDrv)通過ttyDrv安裝的回調(diào)函數(shù)在I/O系統(tǒng)和設(shè)備之間移動(dòng)數(shù)據(jù);tyLib提供了2個(gè)回調(diào)函數(shù)(tyITx和tyIRd)。
1.1 標(biāo)準(zhǔn)驅(qū)動(dòng)程序的構(gòu)造
 SIO_DRV_FUNCS結(jié)構(gòu)體是串行設(shè)備驅(qū)動(dòng)程序的一個(gè)重要的組成部分,它是驅(qū)動(dòng)函數(shù)的入口,在串行設(shè)備的驅(qū)動(dòng)程序中必須要有一個(gè)包含指向SIO_DRV_FUNCS指針的結(jié)構(gòu)(xx_CHAN),xx_CHAN包含了xxDrv中所需要的設(shè)備特定信息,以及提供給高層函數(shù)的底層操作函數(shù);由于系統(tǒng)不知道驅(qū)動(dòng)函數(shù)中所使用的數(shù)據(jù)結(jié)構(gòu),VxWorks提供了一個(gè)數(shù)據(jù)結(jié)構(gòu)SIO_CHAN來進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換[3]。SIO_CHAN結(jié)構(gòu)僅定義了一個(gè)指向SIO_DRV_FUNCS結(jié)構(gòu)體的指針。
 FPGA實(shí)現(xiàn)的多個(gè)低速串行設(shè)備驅(qū)動(dòng)程序的結(jié)構(gòu)構(gòu)造實(shí)例如下:
 typedef struct{
    /*SIO_CHAN*MUST*be first*/
    SIO_CHAN sio;/*standard SIO_CHAN element*/
    UINT32*    inBase;    /*FIFO入口地址*/
    UINT32*    outBase;        /*FIFO出口地址*/
    UINT32*    baudFreqSetBase;    /*波特率設(shè)置地址*/
    UINT32* IntSourceBase;/*中斷源寄存器地址*/
    UINT32* inNumBase;    
/*FIFO有效數(shù)據(jù)長度寄存器地址*/
    SEM_ID RecvSem;/*對(duì)應(yīng)的信號(hào)量*/
    UINT32    intLevel;
    UINT32    IntSourceMask;/*中斷源寄存器掩碼*/
    /*callbacks*/
    STATUS  (*getTxChar) (void*,char*);
    void     (*putRcvChar) (void*,char);
    void *    getTxArg;
    void *    putRcvArg;
    } FPGA_CHAN;
1.2 驅(qū)動(dòng)函數(shù)和回調(diào)函數(shù)的掛接
 ttyDrv通過SIO_DRV_FUNCS提供的入口對(duì)xxDrv的服務(wù)進(jìn)行訪問,xxDrv通過回調(diào)函數(shù)來訪問ttyDrv提供的服務(wù)[4]。xxDrv驅(qū)動(dòng)函數(shù)在SIO_DRV_FUNCS中的掛接實(shí)例如下:
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ū)動(dòng)程序標(biāo)準(zhǔn)操作函數(shù)的實(shí)現(xiàn)
1.3.1 標(biāo)準(zhǔn)寫函數(shù)

 標(biāo)準(zhǔn)的I/O系統(tǒng)寫函數(shù)write()調(diào)用tyWrite()函數(shù)——ttyDrv加載在驅(qū)動(dòng)表中的寫入口函數(shù),tyWrite()函數(shù)將數(shù)據(jù)放入環(huán)形緩沖隊(duì)列中并調(diào)用驅(qū)動(dòng)函數(shù)fpgaTxStartup()發(fā)起一次傳輸過程。write函數(shù)的調(diào)用關(guān)系如圖2所示。

2 低速串行設(shè)備的加載
?。?)根據(jù)實(shí)際需求修改config.h中NUM_TTYS宏;
?。?)參照sysSerialHwInit()函數(shù)實(shí)現(xiàn)FpgaSerialHwInit(),對(duì)NUM_TTYS個(gè)低速串行設(shè)備結(jié)構(gòu)體FPGA_CHAN進(jìn)行初始化以及驅(qū)動(dòng)函數(shù)和回調(diào)函數(shù)的掛接;
?。?)參照sysSerialHwInit2()函數(shù)實(shí)現(xiàn)FpgaSerialHwInit2(),掛接中斷處理函數(shù)fpgaRcvInt();
?。?)調(diào)用ttyDevCreate()函數(shù)創(chuàng)建tty設(shè)備,添加設(shè)備驅(qū)動(dòng)表,生成環(huán)形數(shù)據(jù)緩沖區(qū),安裝回調(diào)函數(shù)tyITx()和tyIRd()。
3 低速串行設(shè)備驅(qū)動(dòng)層次化設(shè)計(jì)方法
 在不同的系統(tǒng)設(shè)計(jì)中,PowerPC和FPGA硬件連接方式不盡相同,如不同的片選信號(hào)、總線上數(shù)據(jù)線高低位的不同接法,中斷管腳接法的不同,導(dǎo)致FPGA實(shí)現(xiàn)的寄存器映射地址及使用的中斷號(hào)存在差異;針對(duì)不同的應(yīng)用程序和應(yīng)用場所,外部接口對(duì)應(yīng)的設(shè)備也會(huì)發(fā)生相應(yīng)的變化。以上這些都會(huì)破壞程序的獨(dú)立性、設(shè)備無關(guān)性。需要對(duì)驅(qū)動(dòng)程序、應(yīng)用程序進(jìn)行重新編譯、燒寫,不利于版本的管理以及外場設(shè)備的維護(hù)。這是在設(shè)備驅(qū)動(dòng)設(shè)計(jì)中需要考慮的一個(gè)問題。
由此本文提出了一種層次化的低速串行設(shè)備驅(qū)動(dòng)設(shè)計(jì)方法。將驅(qū)動(dòng)程序的實(shí)現(xiàn)分為三層,硬件分離層、設(shè)備加載層和功能描述層,各自實(shí)現(xiàn)的功能如下:
 (1)硬件分離層:通過XML文件實(shí)現(xiàn)低速串行驅(qū)動(dòng)程序結(jié)構(gòu)初始化和硬件設(shè)備實(shí)現(xiàn)差異的分離;
 (2)設(shè)備加載層:實(shí)現(xiàn)低速串行設(shè)備在VxWorks系統(tǒng)的標(biāo)準(zhǔn)I/O設(shè)備驅(qū)動(dòng)的加載;
?。?)功能描述層:通過XML文件實(shí)現(xiàn)應(yīng)用程序和低速串行設(shè)備之間的映射關(guān)系以及串行設(shè)備功能的描述。
低速串行設(shè)備驅(qū)動(dòng)層次化設(shè)計(jì)方法流程如圖5所示。

3.1 層次化設(shè)計(jì)驅(qū)動(dòng)程序的實(shí)現(xiàn)
 嵌入式操作系統(tǒng)中,通常都使用Flash作為主存介質(zhì)。在Flash上建立TFFS文件系統(tǒng),建立文件系統(tǒng)后,類似于在Windows操作系統(tǒng)下對(duì)硬盤操作一樣,進(jìn)行數(shù)據(jù)的拷貝、刪除以及文件的建立等操作。XML作為配置文件的主要優(yōu)點(diǎn)是改變參數(shù)配置時(shí)不需要改變和重新編譯應(yīng)用程序,只需在XML文件中更改就可以了。TinyXML是一個(gè)簡單小巧、且很容易集成到其他程序中的C++XML解析器。即TinyXML解析一個(gè)XML文檔并由此生成一個(gè)可讀、可修改、可保存的文檔對(duì)象模型(DOM)。本文的實(shí)現(xiàn)過程中使用TinyXML對(duì)XML文檔進(jìn)行解析。
 低速串行設(shè)備驅(qū)動(dòng)層次化設(shè)計(jì)方法建立在文件系統(tǒng)之上,VxWorks可以動(dòng)態(tài)地加載用戶程序,并在系統(tǒng)中加入對(duì)XML文件進(jìn)行解析和存儲(chǔ)的功能。
 硬件分離層:FpgaSerialHwInit()通過讀取設(shè)備對(duì)應(yīng)的BSP_Config.xml文件,對(duì)多個(gè)低速串行設(shè)備結(jié)構(gòu)體FPGA_CHAN中的各個(gè)寄存器地址進(jìn)行初始化以及驅(qū)動(dòng)函數(shù)和回調(diào)函數(shù)的掛接。
設(shè)備加載層:實(shí)現(xiàn)標(biāo)準(zhǔn)I/O設(shè)備驅(qū)動(dòng)的加載。
 功能描述層:應(yīng)用程序通過讀取USER_Config.xml文件,獲取設(shè)備的對(duì)外連接狀態(tài)及設(shè)備提供的功能,對(duì)多個(gè)低速串行設(shè)備read、write以及ioctl等操作。
通常設(shè)備驅(qū)動(dòng)人員只需要進(jìn)行對(duì)BSP_Config.xml和USER_Config.xml兩個(gè)配置文件進(jìn)行修改、更新。
3.2 XML配置文件的設(shè)計(jì)及實(shí)現(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é)點(diǎn)*/
    ……
node=rootNode->FirstChild("System");
/*獲取匹配的子節(jié)點(diǎn)*/
itemElement=node->ToElement();/*轉(zhuǎn)換為元素*/
itemElement->Attribute("Type",&dValue);/*讀取屬性*/
XML文件的保存和更新方法如下:
TiXmlDocument doc;
doc.Parse(demoXmlCfg);
/*讀取需要保存的XML文件框架結(jié)構(gòu)*/
rootNode=doc.FirstChild("Settings");/*獲取根節(jié)點(diǎn)*/
    ……
node=rootNode->FirstChild("System");
/*獲取匹配的子節(jié)點(diǎn)*/
itemElement=node->ToElement();/*轉(zhuǎn)換為元素*/
itemElement->SetDoubleAttribute("Type",Type)
;/*更新屬性*/
    ……
doc.SaveFile(CONFIG_FILE_NAME);
/*存儲(chǔ)更新配置文件*/

 


 本文提出并實(shí)現(xiàn)了一種VxWorks低速串行設(shè)備驅(qū)動(dòng)的層次化設(shè)計(jì)方法,通過驅(qū)動(dòng)程序功能分層設(shè)計(jì)方式,屏蔽各層的實(shí)現(xiàn)細(xì)節(jié),克服了嵌入式系統(tǒng)開發(fā)過程中,由于設(shè)備驅(qū)動(dòng)程序的設(shè)計(jì)不受驅(qū)動(dòng)體系約束帶來的程序代碼的可移植性、可讀性差,開發(fā)流程并行度不高,層次性不明確等不足之處;在實(shí)際的工程實(shí)現(xiàn)中節(jié)約了開發(fā)時(shí)間,極大地提高了效率。
參考文獻(xiàn)
[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ā)實(shí)踐[M].北京:人民郵電出版社,2004.

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。