2011-06-03 11:14:17|??分類: TI 達芬奇視頻處 |??標簽:
|字號大中小
?訂閱
DAVINCI開發原理之一----ARM端開發環境的建立(DVEVM)
1. 對DAVINCI平臺,TI在硬件上給予雙核架構強有力的支撐,在DSP端用DSP/BIOS來支持音視頻算法的運行,在ARM端用MontaVista Linux(MV)來支持其對外設的管理。對于ARM與DSP之間的數據交互,則用Code Engine和Codec Server來加以管理。
2. 在DAVINCI的開發程序分為codec部分和應用程序部分。開發應用程序前,需要搭建軟硬件開發環境。硬件環境包括: DAVINCI開發板DVEVM(含 TMS320DM6446的DSP和ARM的雙核芯片及豐富的外設)、CCD攝像頭、LCD顯示器、硬盤(如果不用NFS來映射文件系統,則可通過本地的 硬盤上的文件系統)、串口線。其次是與DVEVM配套的ARM端軟件開發環境。環境搭建好后,需要對Linux主機進行相關配置才能使用DVEVM開發 板。對嵌入式系統開發,開發板上首先需要一個bootloader 來初始化硬件,然后會通過bootloader的參數設置來啟動系統。如啟動bootloader后,通過tftp來下載MV Linux內核鏡像文件到內存運行內核,然后通過NFS來啟動Linux主機上的目標文件系統,并通過DHCP服務器來為開發板分配IP地址,這樣就可以 進行基于IP的網絡視頻應用開發。下面配置ARM端軟件開發環境的各個模塊。
3. TFTP服務器的配置:
>檢查Linux是否安裝了TFTP服務
$ rpm -qa|grep tftp
tftp-0.32-4
tftp-server-0.32-4
否則從Linux安裝盤重新用rpm安裝tftp相關模塊,并打開tftp的服務。
4. 配置NFS服務器:
NFS是一種在網絡上的機器間共享文件的方法,文件就如同位于客戶的本地硬盤驅動器上一樣。可以將之看成是一種文件系統的格式,Red Hat Linux既可以是NFS服務器也可以是NFS客戶,這意味著它可以把文件系統導出給其他系統,也可以掛載從其他機器上導入的文件系統。DVEVM的 NFS主要用來把主機Linux上的MV Linux映射到DVEVM板上去,使得DVEVM在自身無文件系統的情形下,可以正常的執行各種任務。
5. DHCP服務器的配置:
配Linux主機和DVEVM的IP。比較簡單。
6. bootloader的燒寫:
是操作系統內核運行前運行的一段程序,通過這段程序來初始化硬件設備、建立內存空間的映射表,從而將系統的軟硬件環境初始化,以便為最終調用操作系統內核準備正確的環境,燒寫前準備如下軟硬件設施:
軟件部分:U-Boot image(即文件u-boot.bin);文件falshwriter.out;CCS 3.2或以上版本
硬件部分:>連接到DAVINCI DVEVM的JTAG硬件仿真器;
? ?? ?? ? >一條連接PC與DACINCI DVEVM的RS323的串口線;
? ?? ?? ? >跳線J4應該被標識為"CS2 SELECT",并確認"FLASH"被選擇;
? ?? ?? ? >使S3的1和2設置為OFF
準備好上述軟硬環境后,即可以開始燒寫了,燒寫例程見附錄(U-boot example.rar),燒寫過程很簡單,累死emulation.
7. 設置DVEVM的啟動參數
#setenv bootargs console=ttyS0,115200n8 noinitrd rw ip=......詳細參數說明見U-BOOT說明文檔。
至此,我們ARM端的初步開發環境建立起來了,可以做一些比較簡單的開發程序,如例:
$mkdir ~/workdir/filesys/ope/hello
$cd ~/workdir/filesys/ope/hello
$vi hello.c
#include<stdio.h>
int main() {
printf("hello world! welcome to DAVINCI test");
return 0; }
$arm_v5t_le-gcc hello.c -o hello? ?/*保存后,用交叉編譯工具arm_v5t_le-gcc編譯程序:*/
#cd /opt/hello? ? /*編譯生成二進制文件hello后,啟動DAVINCI DVEVM板,通過超級終端運行下命令*/
#./hello
****************************************************************************************************************************************
DAVINCI開發原理之二----DSP端開發環境的建立(DVSDK)
在一中只是建立了DVEVM的開發環境,只能進行ARM端程序的開發,如果需要開發DSP端的算法就還需要安裝使用DVSDK,該軟件包包括如下內容:
>Monta Vista Linux Profession Edition v4: 相對于DVEVM發布的montavista linux demo版本來說,這個完全專業版包含了DevRocket IDE和相關服務支持,要全面的多;
>DM6446x SoC Analyzer(DSA): 這個軟件是安裝在windows OS上的,用來觀測分析DSP端和ARM上運行中程序的負載、資源沖突以及性能瓶頸等,不是一定得要,我沒有使用過,好像是要另外付費的;
>DSP/BIOS for linux: DSP/BIOS是一個可升級的實時DSP內核,linux版本相對于window版本來說,不包含相應的圖形分析工具;
>TI Codegen Tools for linux: 與DSP相關的一些編譯、連接工具;
>Framework Components: 主要是用來支持DSP端算法開發的一些模塊,能夠管理符合xDAIS標準的算法模塊,分配內存和DMA資源。這些模塊是被CE來使用的,但如果有必要在DSP端程序也可以使用它們;
>Digital Video Test Bench(DVTB): 這是一個在ARM端運行,基于腳本語言的測試codec的應用程序。用戶不需要寫任何C代碼就可以處理Linux I/O, codec API以及一些與線程有關的問題;
>CCS: 運行在windows OS上的集成開發環境,用來開發基于DSP的應用程序和相關算法;
? ?? ?有了以上DVSDK相關套件,就可以構建DSP端的相關開發組建,其中Codec Engine Romote Server運行在DSP/BIOS上,而在RS中封裝了相關算法,在算法的封裝中要用到一些xDAIS的框架組件。DSP和GPP之間的通訊由DSP /BIOS Link來完成。
1. DVSDK的安裝與配置
>安裝:linux下的操作,比較簡單,只是要注意DVSDK的版本必須與DVEVM版本號一致。且最好把相關的DVSDK安裝在dvevm_#_#_#下。
>配置:在dvevm_#_#_#目錄下的Rules.make文件控制了大部分的編譯行為,該文件被dvevm_#_#_#目錄及其一些子目錄下 的Makefile文件所包含,對DSP端應用程序的編譯需要修改相應的文件,具體根據你實際DVSDK軟件包的安裝路徑。里面要求指定DVEVM、 CE、XDAIS、DSP LINK、CMEM、codec server、RTSC、FC、DSP/BIOS、linux kernel等等包的路徑。
2. DVTB的安裝和使用
? ?? ?數字視頻測試平臺(DVTB)是不用C代碼而直接利用一些腳本語言來測試DSP端算法的工具。在DVSDK安裝后,會在dvevm_#_#_#目錄下有 個dvtb的目錄,就在此執行安裝,然后到DSP的可執行目錄下去運行(DSP的可執行目錄下必須要有cmemk.ko, dsplink.ko等文件),如/nfshost/mydemos.
? ? DVTB的命令語法如下:<Command> <class> <options>
? ? 通過DVTB命令,可以控制audio/vpbe/bpfe等外設或各音視頻編解碼器,來完成一些測試工作。具體安裝過程和命令使用方法可以參考:\opt\dvevm_#_#_#\dvtb_#_#\目錄下文檔。暫時還沒有用到。
3. XDC(Express DSP Component)的配置
? ?? ?XDC是用來編譯和打包的工具,能夠創建實時軟件組件包RTSC(Real Time Software Component).與其他編譯工具一樣,它能根據源文件和庫文件編譯生成可執行文件。不同的是它能夠自動的進行性能優化和版本控制。XDC還能夠根據 所提供的配置腳本語言產生代碼,這一特性在編譯如編解碼器、服務器和引擎等可執行程序時尤為重要。
>XDC的調用語法格式: XDC <target files> <XDCPATH> <XDCBUILDCFG>
? ?target files: 指編譯產生的目標文件。可以通過命令腳本來指定要產生哪些目標文件;
? ?XDCPTH:? ?? ? 編譯時所要查找的目錄;
? ?XDCBUILDCFG: 由"config.bld"文件指定,包含了與平臺有關的編譯指令。后面細說。
? ?以上命令模式可能在參數過多是很復雜,通常把它寫成shell腳本來運行。
>與XDC相關的三個配置文件:
package.xdc: 主要包含與包package有關的信息:依賴信息、模塊信息、版本信息。由自己提供。
package.bld: 主要作用是定義一個包應該如何被編譯。文件內容用Javascript來描述。其中包含目標平臺集的定義[MVArm9,Linux86]、編譯版本的定 義[release]、確定源文件集、生成的可執行文件信息等等。 這兩個文件都是在server目錄下,可見每個codec都有自己的package信息描述文件,然后XDC根據再依之生成一個package包。
config.bld: 這個文件處在codec_engine_##目錄下,為各個codec所共有,它主要定義了與平臺有關的特性,包含如下幾部分:DSP Target、Arm Target、Linux Host Target、Build Targets、Pkg.attrs.Profile、Pkg.lib等具體信息。通常都是基于TI提供的模板對這三個配置文件做修改。
*******************************************************************************************************************************************************
DAVINCI開發原理之三----達芬奇編解碼引擎Codec Engine(CE)
DaVinci是DSP和ARM雙核架構的SOC芯片。對芯片與外界的交互通過ARM端的Montavista Linux和相關驅動與應用程序來管理,DSP端只處理編解碼相關的算法。DSP和ARM之間的通訊和交互是通過引擎(Engine)和服務器 (Server)來完成的。
1. 編解碼引擎(Codec Engine)
a. 核心引擎API
? ?? ?從應用來說,CE就是用來調用xDAIS算法的一組API的集合,用戶可以通過這些API來實例化和調用xDAIS算法。達芬奇提供了一組VISA接 口,用于給應用程序與xDM兼容的xDAIS算法相交互。需要注意,不管算法是運行在本地(ARM端),還是遠端(DSP端),也不管硬件體系是只有 ARM或是只有DSP或兩者都有,也不管OS是Linux、VxWorks、DSP/BIOS,還是WinCE,對算法的接口調用都是一致的。這點通過引 擎的配置文件*.cfg可以看出來,而且通過配置文件可以決定自己的codec是運行在ARM端還是DSP端。
? ???CE包括核心引擎API和VISA API,核心引擎API相關接口模塊為:初始化模塊(CERuntime_)、CE運行時模塊(Engine_)、抽象層內存模塊(Memory_); VISA API的接口模塊我們常用的有: 視頻編碼接口(VIDENCx_)、視頻解碼接口(VIDDECx_)、音頻編碼接口(AUDENCx_)、音頻解碼接口(AUDDECx_),各模塊分 別包含在對應的頭文件中。
? ?? ? 應用程序必須使用CE的核心引擎的三個相關模塊去打開和關閉編解碼引擎的實例。 需要注意的是引擎的句柄是非線程保護的,對單獨使用CE的每個線程來說,必須執行Engine_open并管理好自己的引擎句柄,而對多線程應用來說,也 可以順序的訪問一個共享的引擎實例,我們目前采用的就是后者,只定義了一個引擎句柄,多個解碼器共用。編解碼引擎同時還提供相關的API用以訪問系統的內 存使用狀況和CPU的負載信息,接口如下:
? ?>Engine_open:? ?? ?? ?打開一個編解碼引擎;
? ?>Engine_close:? ?? ???關閉一個編解碼引擎,通常是在刪除算法實例后調用之來釋放相關資源;
? ?>Engine_getCpuLoad:? ?獲取CPU的使用百分比;
? ?>Engine_getLastError: 獲取最后一個失敗操作所引發的錯誤代碼;
? ?>Engine_getUsedMem:? ?獲取內存使用狀況
? ?? ?具體定義引擎所需要包含的頭文件和如何定義和使用引擎可參考工程實例example_dsp1. 目前我們都是多個解碼器共用一個引擎句柄,比如:
? ? static String engineName? ?= "videodec"; /*定義引擎名字,ceapp.cfg配置文件中會用到*/
? ? Engine_Handle ceHandle_264 = NULL; /*創建一個264解碼器引擎句柄*/
? ? Engine_Error errorcode; /*用于返回引擎打開的狀況信息,不同返回值代表的意義可參考相應頭文件*/
? ? ceHandle_264 = Engine_open(engineName, NULL, &errorcode);
? ?? ? 根據上述理解,我覺得如果多個線程需要單獨使用自己的引擎時,應該可以定義多個引擎名字,創建多個引擎句柄,此時每個線程必須單獨執行Engine_open(),并管理好自己的引擎句柄。
b. VISA API
@創建一個算法實例: *_create()
? ?? ?編解碼引擎ceHandle_264創建完畢后,可以通過它來創建自己的算法實例,需要調用*_create(),其中*可以是VIDEO或AUDIO的相應編解碼模塊的名字,例如:
? ?static String decoderName = "h264dec"; /*定義解碼模塊名字,用于標識算法名字,ceapp.cfg會用到*/
? ?VIDDEC_Handle 264Handle;? ?? ?? ?? ?? ?/*創建解碼器句柄*/
? ?264Handle = VIDDEC_create(ceHandle_264, decoderName, NULL); /*在引擎上分配和初始化解碼器,第三個參數可以用來初始化算法的相關參數,這些參數控制著算法的各種行為,參數結構依VISA中編碼或解碼器的不同而不 同,具體結構內容可參考頭文件*/
@關閉一個算法實例: *_delete()
? ?VIDDEC_delete(264Handle); /*注意:只有當與算法相關的內存片清除后,才可以調用之刪除算法實例*/
@控制一個算法實例: *_control()
? ?VIDDEC_control(264Handle, XDM_SETPARAME, dynamicParamsPtr, &encStatus);
? ?? ?第一個參數是已經打開的算法實例句柄; 第二個參數是一整型的command id,它定義在xdm.h中; 第三個參數是需要動態改變算法的參數,比如在create中第三個參數已經為解碼器初始化了一些參數,在這里可以對之做修改,但修改有條件,其具體結構內 容可以參考頭文件; 第四個參數是一個結構體變量,不同模塊具有不同的結構,具體參考頭文件。
@通過算法實例處理數據: *_process()
? ?status = VIDDEC_process(264Handle &inBufDesc,&outBufDesc, &inArgs, &outArgs);
? ?? ?第二和第三個參數是XDM_BufDesc類型的結構體,其中包含了內存片段的數目和開始地址以及長度信息;第四第五個參數分別為算法實例提供輸入和輸出地址。
? ?
? ???上述所有結構體都可以在: \opt\dvevm_#_#\xdais_#_#\packages\xdais\dm下面找到,并可以做修改。只是現在還不知道這些結構體具體怎么使用。
? ?
c. 編譯"一個"編解碼引擎----引擎配置文件(ceapp.cfg)
? ?? ? 引擎的配置文件是以*.cfg文件形式存儲的,目前我們工程里面含兩個*.cfg: app里面含ceapp.cfg,里面包含對引擎的配置,還有一個是video_copy.cfg,在server下,是對服務器的配置文件之一,后面會 講到。ceapp.cfg通過Makefile文件使用package.xdc來產生一個*.c文件和一個鏈接命令腳本文件。一個引擎配置文件包含如下內 容: 引擎的名字以及包含在引擎內的編解碼器和它們的名字。從這里可以看出,前面定義"h264dec"等名字的作用,用于應用程序中標識算法類別,也可以看出 一個引擎是可以由幾個編解碼器模塊共用的。我們以ceapp.cfg文件的內容為例說明配置參數的含義:
/*--------------set up OSAL----------------*/
var osalGlobal = xdc.useModule('ti.sdo.ce.osal.Global');
osalGlobal.runtimeEnv = osalGlobal.DSPLINK_LINUX;
注:這兩句是設置全局的模塊使配置腳本生效,然后是設置引擎的運行環境,即需要用的DSP/BIOS Link和Linux OS).
/*--------------get codec modules;i.e.implementation of codecs-------*/
var H264DEC = xdc.useModule('codecs.h264dec.H264DEC');
注:設置需要用到的編解碼器,即我們將要用到給定目錄下的H264DEC。注意我們目前使用的都是codec目錄下ti提供的videnc_copy,實際上我們可以修改的,另前面我們定義解碼器的名字時用的小寫的'h264dec',這里配置改成大寫.
/*---------------Engine Cofiguation---------------*/
var Engine = xdc.useModule('ti.sdo.ce.Engine');
var demoEngine = Engine.create("videodec", [
? ?? ?? ???{name: "h264dec", mod: H264DEC, local: false},
? ?? ???/* {name: "h264enc", mod: H264ENC, local: false} ... 如果有的話*/
? ? ]);
注:首先使ti.sdo.ce目錄下的引擎可用,然后用create()創建一個引擎。每個引擎都有一個名字,這個名字會被開發人員用到(如打開引擎的時 候,前面我們定義的引擎名字是"h264dec")。create()的參數是一關于算法描述的數組,每個算法描述包含下面幾個字段:
>name: 算法實例的名字,在標識算法時要用到,VIDEC_creat()等VISA API的參數,如前面定義264解碼器名字"h264dec";
>mod: 用來標識實際的算法實現模塊,通常就是name的大寫,如H264DEC.
>local: 如果為真,算法實例在ARM端實現,否則通過codec server來創建DSP端的算法實例。
demoEngine.server = "./encodeCombo.x64P";
注:用于指明Codec Server.
********************************************************************************************************************************************************
DAVINCI開發原理之四----達芬奇編解碼服務器(Codec Server)
編解碼服務器(CS)就是一個二進制文件,它集成了編解碼器,框架組件和一些系統代碼,當CS運行在DSP上時,它使用了DSP/BIOS作為其內核。 CS同時包括了對客戶請求的相關DSP/BIOS線程。CS可以代表實際的DSP硬件、導入到DSP上的鏡像文件以及正在運行的任務,其配置需要兩個步 驟:
? ?>通過TCF腳本語言配置DSP/BIOS;
? ?>通過XDC配置剩下的組件,比如:FC組件、DSP/BIOS Link、Codec Engine等。
? ?配置完成的服務器鏡像文件是在引擎配置文件(ceapp.cfg)中使用的,如前所述的demoEngine.server = "./encodeCombo.x64P";
a. 編譯一個編解碼服務器
? ?? ? CS鏡像文件的創建過程是通過前面介紹的XDC工具來完成的,所不同的是,CS在創建時需要一個main.c和相關的BIOS配置腳本.tcf文件.
>tcf: 腳本文件主要是對DSP/BIOS內核進行配置,如: 定義DSP的內存映射,設置DSP的中斷向量表,創建和初始化其他DSP/BIOS數據對象等,具體可參見video_copy.tcf,注意我在里面添 了一個關于trace的參數配置是原來沒有的。
>main.c: 只要你的算法實現了XDM接口,就需要一個main.c的程序去初始化CE,然后用其他配置腳本來創建一個服務器鏡像*.x64P. 在main.c里面除了調用CERuntime_init()初始化CE外,就是對于trace相關函數的初始化和處理,這部分暫時沒有細究。另有一點值 得注意,在這里可以實現對cache的重新配置,因為在tcf文件里面對cache的配置可能會不起作用,這是可以在這里以函數代碼的方式來配,這點以前 沒有注意過。這里有點不明白的是,在ceapp_init()中已經做了一次CERuntime_init(),為何在CS處還要做一次?(我覺得是因為 先編譯CS,生成*.x64P,然后才編譯app端,這樣就可以理解成: 只要你的算法實現了XDM接口,就需要對CE做初始化CERuntime_init(),而CS的編譯是調用了經XDM封裝后的codec生成 的*.a64P的)
>XDC相關文件:
>>>package.xdc
? ? /*--------------聲明包名-----------------*/
? ? package server{}? ?
? ? (我們目前的.xdc是: package server.video.copy, 此即\server\video_copy\..xdc,應該無需改動)
>>>package.bld: 聲明所必須包含的包,鏈接命令腳本,tcf文件和一些源文件,定義編譯屬性、平臺和對象等。
>>>server.cfg: 這是CS配置的重點,說明如下。
/*第一部分: 聲明運行環境和各種編解碼模塊, 與CE.cfg類似*/
/*--------------set up OSAL----------------*/
var osalGlobal = xdc.useModule('ti.sdo.ce.osal.Global');
osalGlobal.runtimeEnv = osalGlobal.DSPLINK_BIOS;
注:這兩句是設置全局的模塊使配置腳本生效,然后是設置引擎的運行環境,即需要用的DSP/BIOS Link,與CE.cfg有點區別).
/*---------------server Cofiguation---------------*/
var Server = xdc.useModule('tisdo.ce.Server');
Server.threadAttrs.stackSize = 16384;
Server.threadAttrs.priority = Server.MINPRI;
/*--------------get codec modules;i.e.implementation of codecs-------*/
var H264DEC = xdc.useModule('codecs.h264dec.H264DEC'); //與CE.cfg同,注意H264DEC標識的使用。
Server.algs = [
{name:"h264dec", mod:H264DEC,threadAttrs:{stackSize:4096,stackMemId:0,priority:Server.MINPRI+1} }, {...if have..},
? ?];
/*第二部分: DSKT2 and DMAN3的配置:XDAIS算法內存和DMA的分配,參考配置文件*/
*********************************************************************************************************************************************************
DAVINCI開發原理之五----引擎(CE)與服務器(CS)的工作原理
編解碼引擎CE和服務器CS之間的關系可以比作客戶機和應用服務器之間的關系,本質上是遠過程調用思想在雙核上的實現。
1. 遠過程調用(RPC)的工作原理
? ?? ? 遠過程調用最初是用在C/S架構上進行互操作的一種機制,是OS中進程間通訊在網絡環境中的延伸。其目的是使得應用程序在調用另一個遠程應用程序(在另外 一個節點上,或本節點上的另一個進程中)時,采用與本地調用相同的調用方式,就像本地進行的調用過程一樣,如下圖所示:
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?
其過程如下:
1. 客戶按本地調用的方式,直接調用本地的客戶指代(stub),客戶指代具有與服務器相同的過程接口;
2. 客戶指代不進行任何邏輯處理,只是一個中介,因此它僅將客戶的調用請求進行加工、打包,向低層通訊機制發出請求信息;
3. 客戶端通過低層通訊機制將消息傳送給服務器端的通訊機制;
4. 由于一個服務器節點上可能運行多個服務器程序,因此服務器端需要部分的解析消息,找出客戶希望調用的服務器程序;
5. 服務器骨架(skeleton)對消息進行解析,從中獲得調用者的參數,然后調用服務器程序;
6. 服務器程序執行相應的過程;(上面沒有標出這一操作,其余步驟以此類推)
7. 服務器程序將結果返回給服務器骨架;
8. 服務器骨架將結果打包,向低層通信機制發出應答消息;
9. 服務器端通訊機制將消息傳送給客戶端通信機制;
10. 由于一個客戶端節點上也可能有多個調用點,因此通信機制需要部分的解析返回的消息,找出消息應該返回給哪個應用程序,并將消息發送給對應的客戶指代;
11. 客戶指代從消息中解析出結果,返回給客戶程序。
從上過程分析可見,RPC過程中客戶指代的主要工作包括:
1. 建立客戶與服務器之間的連接;
2. 將客戶的高層調用用語句打包為一條低層的請求消息(RPC的編排),然后向服務器發出請求信息;
3. 等到服務器返回應答消息;
4. 接收來自服務器的應答消息,并將來自低層的應答消息解析為可以返回的數據(RPC的還原);
5. 將返回值傳送給客戶指代。
對應服務器骨架也包含上述類似的功能。
2. 引擎與服務器的通訊框架
? ?在ARM端,對視頻類程序來說,應用程序首先把采集到的原始圖像信號,通過VISA接口調用相關的Codec存根函數,由存根函數調用相關的 Engine API函數,也就是SPI(service provider interface)接口,但由于實際的Codec算法在遠端(DSP端),所以必須由引擎把信號進行封裝,通過OS抽象層與DSP Link通訊把打包后的數據發送出去,如下圖所示:
? ?? ?? ?? ???
? ?? ? 當數據進入DSP端后,服務器上的算法實例(codec)接收到相關的數據信息,但這時的信息是被封裝過的,必須由服務器骨架對數據進行解析,從中獲得調 用者的VISA接口參數,然后調用相關的xDM Codec實例,數據的返回方法與之相逆。在這個過程中,ARM端看做客戶機,DSP端看做服務器,把server看做服務區骨架,codec看做服務區 上的應用程序。
3. 引擎與服務器的通訊細節實例
? ?這里分析一個實際的調用代碼的過程。 在視頻類程序中,一般是通過像VIDDEC_process(a,b,c)這樣的VISA接口函數來調用遠端算法的。對內部的工作細節是: 首先在應用程序(ARM端app.c)中調用VIDDEC_process(a,b,c)[ceapp_decodeBuf()調用 VIDDEC_process(),這個調用只是客戶端發送個接口信號],這里首先是調用引擎上的Engine API,也就是服務提供者接口(SPI)VIDDEC_p_process(a,b,c),從這可以看出在app.c中要有一次 CERuntime_init()的調用。然后通過引擎CE的操作系統抽象層OSAL把參數a,b,c和調用信息VIDDEC_p_process()打 包發送給DSPLink;然后通過DSPLink中轉打好包的信息給DSP端的服務器骨架;最后服務器CS解析收到的信息包,由解析后的數據得知我們要調 用VIDDEC_process()這一VISA API函數,并解析出所用參數為a,b,c[video_copy.c中調用VIDEC_TI_process(),這里的調用才是真正的遠端服務器上執 行算法]。從這可以看出在server在編譯時,main.c需要調用一次CERuntime_init()。這一服務器骨架就知道如何調用本地(DSP 端)的xDM算法以及其他方法了。這整個過程對用戶來說是透明的,也就是說應用程序只需要調用Linux端的VISA API接口函數即可。接下來的內部工作由引擎CE和服務器CS來解決。數據從DSP端返回ARM端的過程與之相逆。如下圖:
1. 對DAVINCI平臺,TI在硬件上給予雙核架構強有力的支撐,在DSP端用DSP/BIOS來支持音視頻算法的運行,在ARM端用MontaVista Linux(MV)來支持其對外設的管理。對于ARM與DSP之間的數據交互,則用Code Engine和Codec Server來加以管理。
2. 在DAVINCI的開發程序分為codec部分和應用程序部分。開發應用程序前,需要搭建軟硬件開發環境。硬件環境包括: DAVINCI開發板DVEVM(含 TMS320DM6446的DSP和ARM的雙核芯片及豐富的外設)、CCD攝像頭、LCD顯示器、硬盤(如果不用NFS來映射文件系統,則可通過本地的 硬盤上的文件系統)、串口線。其次是與DVEVM配套的ARM端軟件開發環境。環境搭建好后,需要對Linux主機進行相關配置才能使用DVEVM開發 板。對嵌入式系統開發,開發板上首先需要一個bootloader 來初始化硬件,然后會通過bootloader的參數設置來啟動系統。如啟動bootloader后,通過tftp來下載MV Linux內核鏡像文件到內存運行內核,然后通過NFS來啟動Linux主機上的目標文件系統,并通過DHCP服務器來為開發板分配IP地址,這樣就可以 進行基于IP的網絡視頻應用開發。下面配置ARM端軟件開發環境的各個模塊。
3. TFTP服務器的配置:
>檢查Linux是否安裝了TFTP服務
$ rpm -qa|grep tftp
tftp-0.32-4
tftp-server-0.32-4
否則從Linux安裝盤重新用rpm安裝tftp相關模塊,并打開tftp的服務。
4. 配置NFS服務器:
NFS是一種在網絡上的機器間共享文件的方法,文件就如同位于客戶的本地硬盤驅動器上一樣。可以將之看成是一種文件系統的格式,Red Hat Linux既可以是NFS服務器也可以是NFS客戶,這意味著它可以把文件系統導出給其他系統,也可以掛載從其他機器上導入的文件系統。DVEVM的 NFS主要用來把主機Linux上的MV Linux映射到DVEVM板上去,使得DVEVM在自身無文件系統的情形下,可以正常的執行各種任務。
5. DHCP服務器的配置:
配Linux主機和DVEVM的IP。比較簡單。
6. bootloader的燒寫:
是操作系統內核運行前運行的一段程序,通過這段程序來初始化硬件設備、建立內存空間的映射表,從而將系統的軟硬件環境初始化,以便為最終調用操作系統內核準備正確的環境,燒寫前準備如下軟硬件設施:
軟件部分:U-Boot image(即文件u-boot.bin);文件falshwriter.out;CCS 3.2或以上版本
硬件部分:>連接到DAVINCI DVEVM的JTAG硬件仿真器;
? ?? ?? ? >一條連接PC與DACINCI DVEVM的RS323的串口線;
? ?? ?? ? >跳線J4應該被標識為"CS2 SELECT",并確認"FLASH"被選擇;
? ?? ?? ? >使S3的1和2設置為OFF
準備好上述軟硬環境后,即可以開始燒寫了,燒寫例程見附錄(U-boot example.rar),燒寫過程很簡單,累死emulation.
7. 設置DVEVM的啟動參數
#setenv bootargs console=ttyS0,115200n8 noinitrd rw ip=......詳細參數說明見U-BOOT說明文檔。
至此,我們ARM端的初步開發環境建立起來了,可以做一些比較簡單的開發程序,如例:
$mkdir ~/workdir/filesys/ope/hello
$cd ~/workdir/filesys/ope/hello
$vi hello.c
#include<stdio.h>
int main() {
printf("hello world! welcome to DAVINCI test");
return 0; }
$arm_v5t_le-gcc hello.c -o hello? ?/*保存后,用交叉編譯工具arm_v5t_le-gcc編譯程序:*/
#cd /opt/hello? ? /*編譯生成二進制文件hello后,啟動DAVINCI DVEVM板,通過超級終端運行下命令*/
#./hello
****************************************************************************************************************************************
DAVINCI開發原理之二----DSP端開發環境的建立(DVSDK)
在一中只是建立了DVEVM的開發環境,只能進行ARM端程序的開發,如果需要開發DSP端的算法就還需要安裝使用DVSDK,該軟件包包括如下內容:
>Monta Vista Linux Profession Edition v4: 相對于DVEVM發布的montavista linux demo版本來說,這個完全專業版包含了DevRocket IDE和相關服務支持,要全面的多;
>DM6446x SoC Analyzer(DSA): 這個軟件是安裝在windows OS上的,用來觀測分析DSP端和ARM上運行中程序的負載、資源沖突以及性能瓶頸等,不是一定得要,我沒有使用過,好像是要另外付費的;
>DSP/BIOS for linux: DSP/BIOS是一個可升級的實時DSP內核,linux版本相對于window版本來說,不包含相應的圖形分析工具;
>TI Codegen Tools for linux: 與DSP相關的一些編譯、連接工具;
>Framework Components: 主要是用來支持DSP端算法開發的一些模塊,能夠管理符合xDAIS標準的算法模塊,分配內存和DMA資源。這些模塊是被CE來使用的,但如果有必要在DSP端程序也可以使用它們;
>Digital Video Test Bench(DVTB): 這是一個在ARM端運行,基于腳本語言的測試codec的應用程序。用戶不需要寫任何C代碼就可以處理Linux I/O, codec API以及一些與線程有關的問題;
>CCS: 運行在windows OS上的集成開發環境,用來開發基于DSP的應用程序和相關算法;
? ?? ?有了以上DVSDK相關套件,就可以構建DSP端的相關開發組建,其中Codec Engine Romote Server運行在DSP/BIOS上,而在RS中封裝了相關算法,在算法的封裝中要用到一些xDAIS的框架組件。DSP和GPP之間的通訊由DSP /BIOS Link來完成。
1. DVSDK的安裝與配置
>安裝:linux下的操作,比較簡單,只是要注意DVSDK的版本必須與DVEVM版本號一致。且最好把相關的DVSDK安裝在dvevm_#_#_#下。
>配置:在dvevm_#_#_#目錄下的Rules.make文件控制了大部分的編譯行為,該文件被dvevm_#_#_#目錄及其一些子目錄下 的Makefile文件所包含,對DSP端應用程序的編譯需要修改相應的文件,具體根據你實際DVSDK軟件包的安裝路徑。里面要求指定DVEVM、 CE、XDAIS、DSP LINK、CMEM、codec server、RTSC、FC、DSP/BIOS、linux kernel等等包的路徑。
2. DVTB的安裝和使用
? ?? ?數字視頻測試平臺(DVTB)是不用C代碼而直接利用一些腳本語言來測試DSP端算法的工具。在DVSDK安裝后,會在dvevm_#_#_#目錄下有 個dvtb的目錄,就在此執行安裝,然后到DSP的可執行目錄下去運行(DSP的可執行目錄下必須要有cmemk.ko, dsplink.ko等文件),如/nfshost/mydemos.
? ? DVTB的命令語法如下:<Command> <class> <options>
? ? 通過DVTB命令,可以控制audio/vpbe/bpfe等外設或各音視頻編解碼器,來完成一些測試工作。具體安裝過程和命令使用方法可以參考:\opt\dvevm_#_#_#\dvtb_#_#\目錄下文檔。暫時還沒有用到。
3. XDC(Express DSP Component)的配置
? ?? ?XDC是用來編譯和打包的工具,能夠創建實時軟件組件包RTSC(Real Time Software Component).與其他編譯工具一樣,它能根據源文件和庫文件編譯生成可執行文件。不同的是它能夠自動的進行性能優化和版本控制。XDC還能夠根據 所提供的配置腳本語言產生代碼,這一特性在編譯如編解碼器、服務器和引擎等可執行程序時尤為重要。
>XDC的調用語法格式: XDC <target files> <XDCPATH> <XDCBUILDCFG>
? ?target files: 指編譯產生的目標文件。可以通過命令腳本來指定要產生哪些目標文件;
? ?XDCPTH:? ?? ? 編譯時所要查找的目錄;
? ?XDCBUILDCFG: 由"config.bld"文件指定,包含了與平臺有關的編譯指令。后面細說。
? ?以上命令模式可能在參數過多是很復雜,通常把它寫成shell腳本來運行。
>與XDC相關的三個配置文件:
package.xdc: 主要包含與包package有關的信息:依賴信息、模塊信息、版本信息。由自己提供。
package.bld: 主要作用是定義一個包應該如何被編譯。文件內容用Javascript來描述。其中包含目標平臺集的定義[MVArm9,Linux86]、編譯版本的定 義[release]、確定源文件集、生成的可執行文件信息等等。 這兩個文件都是在server目錄下,可見每個codec都有自己的package信息描述文件,然后XDC根據再依之生成一個package包。
config.bld: 這個文件處在codec_engine_##目錄下,為各個codec所共有,它主要定義了與平臺有關的特性,包含如下幾部分:DSP Target、Arm Target、Linux Host Target、Build Targets、Pkg.attrs.Profile、Pkg.lib等具體信息。通常都是基于TI提供的模板對這三個配置文件做修改。
*******************************************************************************************************************************************************
DAVINCI開發原理之三----達芬奇編解碼引擎Codec Engine(CE)
DaVinci是DSP和ARM雙核架構的SOC芯片。對芯片與外界的交互通過ARM端的Montavista Linux和相關驅動與應用程序來管理,DSP端只處理編解碼相關的算法。DSP和ARM之間的通訊和交互是通過引擎(Engine)和服務器 (Server)來完成的。
1. 編解碼引擎(Codec Engine)
a. 核心引擎API
? ?? ?從應用來說,CE就是用來調用xDAIS算法的一組API的集合,用戶可以通過這些API來實例化和調用xDAIS算法。達芬奇提供了一組VISA接 口,用于給應用程序與xDM兼容的xDAIS算法相交互。需要注意,不管算法是運行在本地(ARM端),還是遠端(DSP端),也不管硬件體系是只有 ARM或是只有DSP或兩者都有,也不管OS是Linux、VxWorks、DSP/BIOS,還是WinCE,對算法的接口調用都是一致的。這點通過引 擎的配置文件*.cfg可以看出來,而且通過配置文件可以決定自己的codec是運行在ARM端還是DSP端。
? ???CE包括核心引擎API和VISA API,核心引擎API相關接口模塊為:初始化模塊(CERuntime_)、CE運行時模塊(Engine_)、抽象層內存模塊(Memory_); VISA API的接口模塊我們常用的有: 視頻編碼接口(VIDENCx_)、視頻解碼接口(VIDDECx_)、音頻編碼接口(AUDENCx_)、音頻解碼接口(AUDDECx_),各模塊分 別包含在對應的頭文件中。
? ?? ? 應用程序必須使用CE的核心引擎的三個相關模塊去打開和關閉編解碼引擎的實例。 需要注意的是引擎的句柄是非線程保護的,對單獨使用CE的每個線程來說,必須執行Engine_open并管理好自己的引擎句柄,而對多線程應用來說,也 可以順序的訪問一個共享的引擎實例,我們目前采用的就是后者,只定義了一個引擎句柄,多個解碼器共用。編解碼引擎同時還提供相關的API用以訪問系統的內 存使用狀況和CPU的負載信息,接口如下:
? ?>Engine_open:? ?? ?? ?打開一個編解碼引擎;
? ?>Engine_close:? ?? ???關閉一個編解碼引擎,通常是在刪除算法實例后調用之來釋放相關資源;
? ?>Engine_getCpuLoad:? ?獲取CPU的使用百分比;
? ?>Engine_getLastError: 獲取最后一個失敗操作所引發的錯誤代碼;
? ?>Engine_getUsedMem:? ?獲取內存使用狀況
? ?? ?具體定義引擎所需要包含的頭文件和如何定義和使用引擎可參考工程實例example_dsp1. 目前我們都是多個解碼器共用一個引擎句柄,比如:
? ? static String engineName? ?= "videodec"; /*定義引擎名字,ceapp.cfg配置文件中會用到*/
? ? Engine_Handle ceHandle_264 = NULL; /*創建一個264解碼器引擎句柄*/
? ? Engine_Error errorcode; /*用于返回引擎打開的狀況信息,不同返回值代表的意義可參考相應頭文件*/
? ? ceHandle_264 = Engine_open(engineName, NULL, &errorcode);
? ?? ? 根據上述理解,我覺得如果多個線程需要單獨使用自己的引擎時,應該可以定義多個引擎名字,創建多個引擎句柄,此時每個線程必須單獨執行Engine_open(),并管理好自己的引擎句柄。
b. VISA API
@創建一個算法實例: *_create()
? ?? ?編解碼引擎ceHandle_264創建完畢后,可以通過它來創建自己的算法實例,需要調用*_create(),其中*可以是VIDEO或AUDIO的相應編解碼模塊的名字,例如:
? ?static String decoderName = "h264dec"; /*定義解碼模塊名字,用于標識算法名字,ceapp.cfg會用到*/
? ?VIDDEC_Handle 264Handle;? ?? ?? ?? ?? ?/*創建解碼器句柄*/
? ?264Handle = VIDDEC_create(ceHandle_264, decoderName, NULL); /*在引擎上分配和初始化解碼器,第三個參數可以用來初始化算法的相關參數,這些參數控制著算法的各種行為,參數結構依VISA中編碼或解碼器的不同而不 同,具體結構內容可參考頭文件*/
@關閉一個算法實例: *_delete()
? ?VIDDEC_delete(264Handle); /*注意:只有當與算法相關的內存片清除后,才可以調用之刪除算法實例*/
@控制一個算法實例: *_control()
? ?VIDDEC_control(264Handle, XDM_SETPARAME, dynamicParamsPtr, &encStatus);
? ?? ?第一個參數是已經打開的算法實例句柄; 第二個參數是一整型的command id,它定義在xdm.h中; 第三個參數是需要動態改變算法的參數,比如在create中第三個參數已經為解碼器初始化了一些參數,在這里可以對之做修改,但修改有條件,其具體結構內 容可以參考頭文件; 第四個參數是一個結構體變量,不同模塊具有不同的結構,具體參考頭文件。
@通過算法實例處理數據: *_process()
? ?status = VIDDEC_process(264Handle &inBufDesc,&outBufDesc, &inArgs, &outArgs);
? ?? ?第二和第三個參數是XDM_BufDesc類型的結構體,其中包含了內存片段的數目和開始地址以及長度信息;第四第五個參數分別為算法實例提供輸入和輸出地址。
? ?
? ???上述所有結構體都可以在: \opt\dvevm_#_#\xdais_#_#\packages\xdais\dm下面找到,并可以做修改。只是現在還不知道這些結構體具體怎么使用。
? ?
c. 編譯"一個"編解碼引擎----引擎配置文件(ceapp.cfg)
? ?? ? 引擎的配置文件是以*.cfg文件形式存儲的,目前我們工程里面含兩個*.cfg: app里面含ceapp.cfg,里面包含對引擎的配置,還有一個是video_copy.cfg,在server下,是對服務器的配置文件之一,后面會 講到。ceapp.cfg通過Makefile文件使用package.xdc來產生一個*.c文件和一個鏈接命令腳本文件。一個引擎配置文件包含如下內 容: 引擎的名字以及包含在引擎內的編解碼器和它們的名字。從這里可以看出,前面定義"h264dec"等名字的作用,用于應用程序中標識算法類別,也可以看出 一個引擎是可以由幾個編解碼器模塊共用的。我們以ceapp.cfg文件的內容為例說明配置參數的含義:
/*--------------set up OSAL----------------*/
var osalGlobal = xdc.useModule('ti.sdo.ce.osal.Global');
osalGlobal.runtimeEnv = osalGlobal.DSPLINK_LINUX;
注:這兩句是設置全局的模塊使配置腳本生效,然后是設置引擎的運行環境,即需要用的DSP/BIOS Link和Linux OS).
/*--------------get codec modules;i.e.implementation of codecs-------*/
var H264DEC = xdc.useModule('codecs.h264dec.H264DEC');
注:設置需要用到的編解碼器,即我們將要用到給定目錄下的H264DEC。注意我們目前使用的都是codec目錄下ti提供的videnc_copy,實際上我們可以修改的,另前面我們定義解碼器的名字時用的小寫的'h264dec',這里配置改成大寫.
/*---------------Engine Cofiguation---------------*/
var Engine = xdc.useModule('ti.sdo.ce.Engine');
var demoEngine = Engine.create("videodec", [
? ?? ?? ???{name: "h264dec", mod: H264DEC, local: false},
? ?? ???/* {name: "h264enc", mod: H264ENC, local: false} ... 如果有的話*/
? ? ]);
注:首先使ti.sdo.ce目錄下的引擎可用,然后用create()創建一個引擎。每個引擎都有一個名字,這個名字會被開發人員用到(如打開引擎的時 候,前面我們定義的引擎名字是"h264dec")。create()的參數是一關于算法描述的數組,每個算法描述包含下面幾個字段:
>name: 算法實例的名字,在標識算法時要用到,VIDEC_creat()等VISA API的參數,如前面定義264解碼器名字"h264dec";
>mod: 用來標識實際的算法實現模塊,通常就是name的大寫,如H264DEC.
>local: 如果為真,算法實例在ARM端實現,否則通過codec server來創建DSP端的算法實例。
demoEngine.server = "./encodeCombo.x64P";
注:用于指明Codec Server.
********************************************************************************************************************************************************
DAVINCI開發原理之四----達芬奇編解碼服務器(Codec Server)
編解碼服務器(CS)就是一個二進制文件,它集成了編解碼器,框架組件和一些系統代碼,當CS運行在DSP上時,它使用了DSP/BIOS作為其內核。 CS同時包括了對客戶請求的相關DSP/BIOS線程。CS可以代表實際的DSP硬件、導入到DSP上的鏡像文件以及正在運行的任務,其配置需要兩個步 驟:
? ?>通過TCF腳本語言配置DSP/BIOS;
? ?>通過XDC配置剩下的組件,比如:FC組件、DSP/BIOS Link、Codec Engine等。
? ?配置完成的服務器鏡像文件是在引擎配置文件(ceapp.cfg)中使用的,如前所述的demoEngine.server = "./encodeCombo.x64P";
a. 編譯一個編解碼服務器
? ?? ? CS鏡像文件的創建過程是通過前面介紹的XDC工具來完成的,所不同的是,CS在創建時需要一個main.c和相關的BIOS配置腳本.tcf文件.
>tcf: 腳本文件主要是對DSP/BIOS內核進行配置,如: 定義DSP的內存映射,設置DSP的中斷向量表,創建和初始化其他DSP/BIOS數據對象等,具體可參見video_copy.tcf,注意我在里面添 了一個關于trace的參數配置是原來沒有的。
>main.c: 只要你的算法實現了XDM接口,就需要一個main.c的程序去初始化CE,然后用其他配置腳本來創建一個服務器鏡像*.x64P. 在main.c里面除了調用CERuntime_init()初始化CE外,就是對于trace相關函數的初始化和處理,這部分暫時沒有細究。另有一點值 得注意,在這里可以實現對cache的重新配置,因為在tcf文件里面對cache的配置可能會不起作用,這是可以在這里以函數代碼的方式來配,這點以前 沒有注意過。這里有點不明白的是,在ceapp_init()中已經做了一次CERuntime_init(),為何在CS處還要做一次?(我覺得是因為 先編譯CS,生成*.x64P,然后才編譯app端,這樣就可以理解成: 只要你的算法實現了XDM接口,就需要對CE做初始化CERuntime_init(),而CS的編譯是調用了經XDM封裝后的codec生成 的*.a64P的)
>XDC相關文件:
>>>package.xdc
? ? /*--------------聲明包名-----------------*/
? ? package server{}? ?
? ? (我們目前的.xdc是: package server.video.copy, 此即\server\video_copy\..xdc,應該無需改動)
>>>package.bld: 聲明所必須包含的包,鏈接命令腳本,tcf文件和一些源文件,定義編譯屬性、平臺和對象等。
>>>server.cfg: 這是CS配置的重點,說明如下。
/*第一部分: 聲明運行環境和各種編解碼模塊, 與CE.cfg類似*/
/*--------------set up OSAL----------------*/
var osalGlobal = xdc.useModule('ti.sdo.ce.osal.Global');
osalGlobal.runtimeEnv = osalGlobal.DSPLINK_BIOS;
注:這兩句是設置全局的模塊使配置腳本生效,然后是設置引擎的運行環境,即需要用的DSP/BIOS Link,與CE.cfg有點區別).
/*---------------server Cofiguation---------------*/
var Server = xdc.useModule('tisdo.ce.Server');
Server.threadAttrs.stackSize = 16384;
Server.threadAttrs.priority = Server.MINPRI;
/*--------------get codec modules;i.e.implementation of codecs-------*/
var H264DEC = xdc.useModule('codecs.h264dec.H264DEC'); //與CE.cfg同,注意H264DEC標識的使用。
Server.algs = [
{name:"h264dec", mod:H264DEC,threadAttrs:{stackSize:4096,stackMemId:0,priority:Server.MINPRI+1} }, {...if have..},
? ?];
/*第二部分: DSKT2 and DMAN3的配置:XDAIS算法內存和DMA的分配,參考配置文件*/
*********************************************************************************************************************************************************
DAVINCI開發原理之五----引擎(CE)與服務器(CS)的工作原理
編解碼引擎CE和服務器CS之間的關系可以比作客戶機和應用服務器之間的關系,本質上是遠過程調用思想在雙核上的實現。
1. 遠過程調用(RPC)的工作原理
? ?? ? 遠過程調用最初是用在C/S架構上進行互操作的一種機制,是OS中進程間通訊在網絡環境中的延伸。其目的是使得應用程序在調用另一個遠程應用程序(在另外 一個節點上,或本節點上的另一個進程中)時,采用與本地調用相同的調用方式,就像本地進行的調用過程一樣,如下圖所示:
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?


其過程如下:
1. 客戶按本地調用的方式,直接調用本地的客戶指代(stub),客戶指代具有與服務器相同的過程接口;
2. 客戶指代不進行任何邏輯處理,只是一個中介,因此它僅將客戶的調用請求進行加工、打包,向低層通訊機制發出請求信息;
3. 客戶端通過低層通訊機制將消息傳送給服務器端的通訊機制;
4. 由于一個服務器節點上可能運行多個服務器程序,因此服務器端需要部分的解析消息,找出客戶希望調用的服務器程序;
5. 服務器骨架(skeleton)對消息進行解析,從中獲得調用者的參數,然后調用服務器程序;
6. 服務器程序執行相應的過程;(上面沒有標出這一操作,其余步驟以此類推)
7. 服務器程序將結果返回給服務器骨架;
8. 服務器骨架將結果打包,向低層通信機制發出應答消息;
9. 服務器端通訊機制將消息傳送給客戶端通信機制;
10. 由于一個客戶端節點上也可能有多個調用點,因此通信機制需要部分的解析返回的消息,找出消息應該返回給哪個應用程序,并將消息發送給對應的客戶指代;
11. 客戶指代從消息中解析出結果,返回給客戶程序。
從上過程分析可見,RPC過程中客戶指代的主要工作包括:
1. 建立客戶與服務器之間的連接;
2. 將客戶的高層調用用語句打包為一條低層的請求消息(RPC的編排),然后向服務器發出請求信息;
3. 等到服務器返回應答消息;
4. 接收來自服務器的應答消息,并將來自低層的應答消息解析為可以返回的數據(RPC的還原);
5. 將返回值傳送給客戶指代。
對應服務器骨架也包含上述類似的功能。
2. 引擎與服務器的通訊框架
? ?在ARM端,對視頻類程序來說,應用程序首先把采集到的原始圖像信號,通過VISA接口調用相關的Codec存根函數,由存根函數調用相關的 Engine API函數,也就是SPI(service provider interface)接口,但由于實際的Codec算法在遠端(DSP端),所以必須由引擎把信號進行封裝,通過OS抽象層與DSP Link通訊把打包后的數據發送出去,如下圖所示:


? ?? ?? ?? ???
? ?? ? 當數據進入DSP端后,服務器上的算法實例(codec)接收到相關的數據信息,但這時的信息是被封裝過的,必須由服務器骨架對數據進行解析,從中獲得調 用者的VISA接口參數,然后調用相關的xDM Codec實例,數據的返回方法與之相逆。在這個過程中,ARM端看做客戶機,DSP端看做服務器,把server看做服務區骨架,codec看做服務區 上的應用程序。
3. 引擎與服務器的通訊細節實例
? ?這里分析一個實際的調用代碼的過程。 在視頻類程序中,一般是通過像VIDDEC_process(a,b,c)這樣的VISA接口函數來調用遠端算法的。對內部的工作細節是: 首先在應用程序(ARM端app.c)中調用VIDDEC_process(a,b,c)[ceapp_decodeBuf()調用 VIDDEC_process(),這個調用只是客戶端發送個接口信號],這里首先是調用引擎上的Engine API,也就是服務提供者接口(SPI)VIDDEC_p_process(a,b,c),從這可以看出在app.c中要有一次 CERuntime_init()的調用。然后通過引擎CE的操作系統抽象層OSAL把參數a,b,c和調用信息VIDDEC_p_process()打 包發送給DSPLink;然后通過DSPLink中轉打好包的信息給DSP端的服務器骨架;最后服務器CS解析收到的信息包,由解析后的數據得知我們要調 用VIDDEC_process()這一VISA API函數,并解析出所用參數為a,b,c[video_copy.c中調用VIDEC_TI_process(),這里的調用才是真正的遠端服務器上執 行算法]。從這可以看出在server在編譯時,main.c需要調用一次CERuntime_init()。這一服務器骨架就知道如何調用本地(DSP 端)的xDM算法以及其他方法了。這整個過程對用戶來說是透明的,也就是說應用程序只需要調用Linux端的VISA API接口函數即可。接下來的內部工作由引擎CE和服務器CS來解決。數據從DSP端返回ARM端的過程與之相逆。如下圖:

