• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統 > 設計應用 > 用RTDX實現數據的實時雙向傳輸

    用RTDX實現數據的實時雙向傳輸

    作者:電子集團公司第十研究所 劉景元 時間:2005-01-05 來源: 收藏

    2004年8月A版

    摘   要:講述實時數據傳輸()的使用,描述一個用雙向傳遞大量多媒體數據的實現方法。該方法可以方便的應用于其他TI DSP的系統設計中。

    關鍵詞:TI DSP;

    引言

      TI DSP在數字電路中作為信號處理、電路控制的核心設備,廣泛應用于各個行業。在TI DSP系統設計階段,實時數據交換(RTDX)提供了一種目標板和主機之間的雙向實時數據傳輸的方法。它可以應用于大量數據的雙向傳輸,例如應用在多媒體數據進行仿真處理中。但是由于它的實現難度較大以及不處于系統設計的核心位置,所以沒有得到廣泛使用。本文的目的是向讀者描述一種RTDX的具體實現。

    RTDX的使用方法

      RTDX提供了目標板與主機之間的實時數據通信。當系統使用該功能時,DSP上駐留一個小的RTDX片上軟件庫,片上程序通過調用這個軟件庫的API實現JTAG與主機之間的數據傳輸。與DSP目標板相連的主機上也存在一個相應的RTDX主機端軟件庫,客戶編寫的主機端程序通過對象嵌入,實現DSP目標板的實時數據分析,以及向目標板提供新的數據。

      在編寫DSP的軟件上,RTDX的使用方式和C語言文件的IO操作非常相似,如圖1、2所示,在實現數據由DSP到主機的過程中,首先聲明一個RTDX輸出通道,然后對該通道進行操作,最后查詢狀態,看數據是否被發送出去;而從主機端到DSP端的數據傳輸過程中,則聲明一個RTDX輸入通道,然后讀取該通道上的數據。

      在主機端,TI 提供的RTDX庫使用了微軟公司的COM技術,數據的傳輸過程分別如圖3、圖4所示。

    用RTDX實現多媒體數據的

    雙向傳輸

      多媒體數據原始信息往往擁有極大的數據量,DSP在多媒體數據處理中的應用主要是壓縮和解壓縮,但由于DSP自身的限制,它沒有大量的空間存儲多媒體數據,即便這些數據是已經被壓縮過的。在系統的調試階段,如何單獨測試DSP的編碼效率呢?一種可行的解決辦法就是借用DSP目標板相連的主機空間,用RTDX把原始數據傳遞給DSP,DSP對數據處理后再通過RTDX傳回主機。

    系統的整體構架

      由于DSP片上存儲空間有限, TI對RTDX一次在主機和目標DSP之間傳輸的數據長度做了限制,此值不應該超過253個字長為16bit的數據,如果一次傳輸的數據量超過253,則要對數據分片傳遞。本應用中每次傳遞的數據遠遠大于253,所以主機端和目標板都定義了分片長度RTDXBLOCK,RTDXBLOCK=200。傳輸時兩邊同時進行相反的工作,目標板寫數據的時候主機等著讀數據,主機寫數據的時候目標板進行相反的操作。每傳輸RTDXBLOCK大小的數據,兩者的工作進行交換。分段傳遞數據還帶來了很多好處,它可以方便主機與目標板之間的同步,每次數據的發出也是對上一次收到數據的應答;RTDX的特性是讀一個字節,寫一個字節,讀寫采用相同大小段節省了將近一半的時間;inbuffer與outbuffer可以指向相同的地址,又節省了一些內存。

      采用相同大小的段傳輸數據還有一些細節問題要考慮,目標板的第一次操作是否應該先是寫出?以便空出地方來接收下一次被處理的數據。由于每次傳輸數據總量的不對稱性,大部分情況下是輸入的數據比輸出的數據多,目標板先寫出數據會多占用一次傳輸的時間。另一個問題就是數據總量的不對稱性,總是主機或目標板先寫完數據,只剩下某一種操作,這部分時間沒有辦法節省。

      對于數據傳遞過程中可能傳送的一些命令字如,跳過當前幀、程序終止等。做了這樣的考慮,由主機和目標板主程序來填寫和解釋這些命令字,命令字不單獨傳輸,本應用中放在inbufferoutbuffer的第0個位置,與下一塊數據同時傳送。另外,本應用中inbuffer與outbuffer的第1個位置存放的是數據段的實際長度,常用于向主機端指示壓縮后數據的實際長度,以便用于不定長壓縮方式的數據輸出。inbuffer/outbuffer的實際數據的起始位置是可以根據應用自定義的。傳輸程序不負責這些問題,只管從buffer的第一個字節開始傳輸數據。

    軟件設計

      DSP片上實現了一次數據輸入輸出的函數dataIO,它采用C語言編寫,返回值1表示運行過程均正常。有4個參數,分別是輸出Buffer起始位置,輸出Buffer的大小,輸入Buffer的起始位置,輸入Buffer的大小。使用時,在主函數中使用兩個RTDX宏聲明:RTDX_CreateOutput Channel(ochan),RTDX_CreateInput Channel(ichan),然后可以直接調用dataIO進行數據傳輸,dataIO會在第一次運行中自動初始化環境。如圖7所示。dataIO函數經過簡單的修改甚至不修改即可以適用于不同的環境。

      主機端的RTDX過程使用C++實現,因為程序的主要目的就是向目標板傳遞數據和取得數據,所以直接在主程序中作了一個大的循環,同目標板一樣用了4個參數:inbuffer,outbuffer,inbufferlength,outbufferleng。執行時,主程序首先被阻塞,不停的試圖從目標板讀取經過壓縮的數據,直到目標板DSP把壓縮好的數據放到輸出通道上。得到數據后,主程序把這些數據存放在本地文件中,然后把要壓縮的數據寫到輸入通道上傳遞給DSP。這樣反復執行直到傳輸雙方中的一方表示傳輸終止。

    執行過程

      首先把程序寫入目標板DSP中,然后在DSP集成開發環境CCS的tools菜單中選擇RTDX,啟用輸入通道和輸出通道。先后運行DSP程序和主機端程序即可實現數據的雙向傳輸。因為兩邊都使用了阻塞機制,所以程序運行的先后順序無所謂。

    結語

      本應用實現了如下功能:主機端把44.1KHz,16bit采樣的音頻數據傳遞到DSP內存中,每次傳遞1152個數據。DSP對這些數據進行Mp3格式的壓縮,壓縮后的數據長度不確定,最后DSP把這些數據傳回主機端,然后等待下一次傳輸開始。實現基于DSK5416,用CCS2.0作為DSP綜合開發環境。主機端程序用MS VC6.0編譯。

      這種RTDX的實現方法用于2003年德州儀器公司數字信號處理大學挑戰賽決賽項目“使用TMS320C547X實現多媒體數據在TCP/IP網絡傳輸”的設計中,該項目最終獲得大賽三等獎。

     

    參考文獻:

    1. 彭啟琮,‘TMS320C54x 實用教程’ ,電子科技大學出版社,1999

    2. 張雄偉、陳亮、徐光輝,‘DSP集成開發與應用實例’,電子工業出版社,2002

     

    RTDX_CreateOutputChannel( ochan );              //創建一個輸出通道,該操作為宏操作

    ...   

    TARGET_INITIALIZE();

    RTDX_enableOutput( &ochan );                //初始化目標板以及通道使能

    ...

    status = RTDX_write( &ochan, outp , RTDXBLOCK );  

    //發送outp指針所指數據到輸出通道,數據長度由RTDXBLOCK指定,返回實際發送的數據長度*

    *:數據長度指類型為發送數據類型轉換為16位無符號所占長度,outp的數據類型也應為16位無符號數。

    圖1  目標板向主機輸出數據

     

    RTDX_CreateInputChannel( ochan );           //創建一個輸入通道,該操作為宏操作

    ...   

    TARGET_INITIALIZE();

    RTDX_enableInput( &ochan );                     //初始化目標板以及通道使能

    ...

    status = RTDX_read( &ichan, inp, RTDXBLOCK )

    //發送inp指針所指數據到輸出通道,數據長度由RTDXBLOCK指定,返回實際接收的數據長度*

    *:數據長度指類型為發送數據類型轉換為16位無符號所占長度,inp的數據類型也應為16位無符號數。

    圖2   目標板從主機端獲取數據


    hr = rtdx_in.CreateInstance( __uuidof(RTDXINTLib::RtdxExp) ); //創建rtdx實例

    status = rtdx_in->Open( "ichan", "W" );              //創建ichan ,以便向目標板輸入數據*

    status = rtdx_in->Write( sa, &bufferstate);       //把安全數組sa**中的數據寫入目標板

    status = rtdx_in->Close();    //關閉輸入通道

    *:讀寫狀態標志"W"應該大寫,否則會帶來不可預知的錯誤。

    **:在寫入數據時,應該把要寫入的數據放在一個安全數組中。然后調用Write。

    圖3  主機端向目標板傳輸數據


    hr = rtdx_out.CreateInstance( __uuidof(RTDXINTLib::RtdxExp) ); //創建rtdx實例

    status = rtdx_out->Open( "ochan", "R" );       //創建ochan ,以便從目標板獲取數據

    status = rtdx_out->ReadSAI2( &sb );              //把目標板上的數據寫入安全數組sb*,**

    status = rtdx_out->Close();  //關閉輸出通道

    *:從目標板讀取的數據首先被放在安全數組中,然后由使用者讀出。

    **:可以根據目標板的數據格式,通過調用ReadSAI1,ReadSAI2,ReadSAI4,讀取所占字節數不同的數據。例如讀取占用4個8位字節的word類型數據,應該使用ReadSAI4。

    圖4  主機端從目標板獲取數據

    圖5  輸入輸出Buffer的數據格式

    圖6  主機端與目標板的數據傳輸過程圖


    int dataIO(unsigned int * inbuffer,

                     unsigned int * outbuffer,

                     int inbuffer_length,

                     int outbuffer_length);

    int main()

    {     unsigned int inbuffer[FLUSH+2];

           unsigned int outbuffer[FRAME+2];

           while(1)

           {

                  if (dataIO(inbuffer,outbuffer,FLUSH+2,FRAME+2)!=1)

    return;

                  encode();/*進行數據處理*/

           }

    }

    圖7  經過封裝的RTDX函數



    關鍵詞: RTDX 嵌入式

    評論


    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 斗六市| 东乌| 宁都县| 谢通门县| 阳朔县| 新密市| 浦城县| 祥云县| 关岭| 门源| 井研县| 普定县| 卢龙县| 广元市| 许昌市| 上虞市| 临城县| 平凉市| 石城县| 双流县| 尼勒克县| 册亨县| 长白| 揭东县| 仁化县| 赣榆县| 赞皇县| 山阳县| 涟水县| 长宁区| 海原县| 丰台区| 镇雄县| 嘉祥县| 安化县| 朝阳市| 宁化县| 江北区| 睢宁县| 固始县| 连山|