參考框架
RF5 主要實現三個功能,存儲管理,執行緒模型和通道封裝,對於不同的套用,我們只需在這三個元素上做修改,而對於整個應用程式,不用從頭設計,這樣大大簡化了開發者的開發難度,縮短了開發時間。
RF5適用於包含大量的算法,且要求多執行緒,多通道的套用,如圖像處理,多媒體套用等,以Ti提供的實例mpeg2loopback為例,對RF5進行分析。
RF5包含的元素有:
RF5框架包含四個基本的數據處理元素,處在最頂層的是執行緒,執行緒總是順序的執行所包含的通道,執行緒在一個比較高級的級別上把數據組織在一起,他們可以與別的執行緒,設備驅動以及別的類似結構進行通訊,在mpeg2lookback實例中,創建了三個執行緒分別是tskVideoInput,tskVideoOutput和tskProcess。每個執行緒都在不斷的等待訊息,處理數據,並將結果傳送給其他的執行緒,同時有可能還要傳送同步訊息給其他執行緒已實現執行緒間的通訊,這裡使用的機制是
SCOM模組。
每個
執行緒都是進行數據
處理的一個單元,有的是處理簡單的,有的處理是相對複雜的過程,簡單的執行緒可以不包括任何的通道,而進行複雜數據處理的執行緒有可能包含多個的通道。
2 通道(Channel):
RF5提供了一種通道結構是為了更方便的封裝算法,這可以理解通道為並行里的串列,因為執行緒的執行就是由通道的串列執行來完成的,一個通道包含一組核(Icell),其主要任務就是依次順序的執行所包含的核,主要執行的流程為:首先需要初始化通道模組,然後建立通道對象,註冊該通道所包含的核對象,接著依次執行每個核,執行完成了後就銷毀對象,最後退出。每個通道可以包含多個核,每個核都要進行初始化後在調用CHAN_regCell註冊。
通道對象的結構如下:
typedef struct CHAN_Obj {
ICELL_Obj *cellSet; /* set of cells in the channel */
Uns cellCnt; /* number of cells in the cellSet */
CHAN_State state; /* state of the channel */
Bool (*chanControlCB)(CHAN_Handle chanHandle); /* optional control function */
} CHAN_Obj;
執行緒一般不定義通道對象,但是在CHAN_open()調用中初始化它們。CHAN_open()的最後一個參數是通道屬性(CHAN_Attrs)結構體的地址。如果最後一個參數是NULL,那么CHAN_open()使用默認的參數。如果要想使用不同的參數,就要聲明一個CHAN_Attrs的結構體,並需初始化為CHAN_ATTRS宏所定義的初值,然後根據需要可以修改其中相應的域的值,通常,其中的通道狀態參數CHAN_State state域默認為CHAN_ACTIVE,以及通道控制回調函式參數域Bool (*chanControlCB)(CHAN_Handle chanHandle)默認為NULL。如果通道控制回調函式不是空,那么在任何的cell調用執行之前都會先調用此回調函式。
一個典型的設定,一個執行緒為每一個通道建立一個CHAN_Obj對象(或者一組類似的對象),並且為每一個cell建立一個ICELL_Obj對象(或者是與每個通道相對應的一組ICCE_Obj對象).線上程初始化ICELL_Obj之後就會調用下面的函式:
備註其中的cell 指向cell 對象的
指針, inputIcc/outputIcc是相應的cell的 ICC 對象,這個調用計算單元需要的空間,並分配給定的ICC對象給單元cell。
CHAN_regCell( cell, inputIcc, 1, outputIcc, 1 );
當所有的cells都已經創建並初始化之後,執行緒調用CHAN_open()函式來為每一個指定的通道(chanNum)傳遞cell對象(cellList)。這個函式創建所有的XDAIS算法,並且如果單元細胞定義了cellOpen函式,則會調用每一個單元細胞的cellOpen函式,.
CHAN_open( chanList[ chanNum ], cellList, numCells, NULL/* default attributes */ );
最後,在運行時,執行緒為每一個通道(chanNum)調用CHAN_execute函式開始執行:
CHAN_execute( chanList[ chanNum ], NULL /* arg to cells */ );
3 核(Icell):
核實際上就是ICELL接口對象,基於RF5的套用常常包含大量的算法和通道,為了便於算法集中到套用中,RF5提出了核的概念,一個核就是包含一種XDAIS算法的容器,一個RF5通道對象可以包含多個核,也即是包含多個算法,通道通過核來調用算法,實際上,真正的數據處理是在XDAIS算法,核只是提供一個調用算法的接口,這大大簡化了工作量,便於移植。
該接口包含一個重要的結構:ICELL_Fxns,該結構包含一組
函式指針。通道通過調用這些函式來調用算法,其中包含一個關鍵的函式cellExecute,這個函式的功能是調用XDAIS算法來執行,上面的通道執行函式CHAN_execute就包含了每個cellExecute的調用。
4 ICC模組
ICC模組是用來管理在核之間以及核與其他執行緒之間的
數據通訊,我們知道執行緒間的數據傳輸是通過
SCOM模組來實現的,每個ICC模組管理一個或者多個ICC對象,每個核都有一組輸入和輸出ICC對象。這些對象是通過CHAN_regCell()來註冊到相應的通道里。
ThrProcess中包含兩個
SCOM對象,RF5使用SCOM對象來實現執行緒的通訊。
SCOM訊息時用戶自定義的一個機構,一個執行緒通過調用SCOM_putMsg()函式將SCOM訊息放置一個SCOM
佇列中,傳送給其他的執行緒,或者通過調用SCOM_getMsg()函式從佇列中獲取訊息,一般情況下,傳送訊息指明接收執行緒所要讀取的
數據緩衝區的地址(以指針形式),接收訊息指明傳送執行緒所要寫入的數據緩衝區的地址,在mape2loopback實例中,thrProcess要從thraVideoInput接收訊息,並傳送訊息給thrVideoOutput輸出圖像。RF5使用
SCOM來實現執行緒間的通訊:thrProcess擁有一些緩衝區,需要thrVideoInput寫或thrVideoOutput讀,所以thrProcess通過SCOM告訴thrVideoIput和thrVideoOutput執行緒
數據緩衝區的地址,同時還要保證兩個執行緒不會同時訪問同一個緩衝區。thrProcess創建了兩種訊息以分別和兩個
執行緒進行通訊,scomMsgRx和scomMsgTx,scomMsgRx指定了被thrVideoInput寫的緩衝區地址,scomMsgTx指定了被thrVideoOutput讀的緩衝區地址。
在實際的操作中,可是將
SCOM看作是種同步標記,她用來區分模組記憶體是否正在被其他
執行緒所使用,這樣就可以放置記憶體訪問的衝突。整個系統中包含很多存儲區,這些記憶體區很有可能在某一時刻正在被某一執行緒訪問,為了保證在任意時刻只有一個執行緒訪問某一塊記憶體,當前正在訪問這一記憶體塊的執行緒通過傳送
SCOM訊息給與這一記憶體塊有關聯的執行緒,告訴他,“我正在訪問呢,你等會再來吧”。當他訪問完後,放棄了這一記憶體塊的占有權,再通過
SCOM訊息告訴相關聯的執行緒,“我用完了,你可以用了。”於是相關聯的
執行緒就可以訪問了。
6 ALGRF模組—算法的實例化Algorithm Instantiation
ALGRF Module用DSP/BIOSMEM
記憶體管理器來創建和刪除XDAIS算法的模組。參考框架服務簡化XDAIS部件的使用。所有符合XDAIS標準的算法都必須使用一個標準的接口——IALG接口。ALGRF使用算法的IALG來實現對XDAIS算法的實例化。任何符合XDAIS標準的算法都可以被ALGRF所使用。
用戶代碼不必直接的調用ALGRF函式,這個工作由CHAN和其他的庫函式來完成。例外的是cell wrappers中的ALGRF_activate/deactivate序列化:如果cell中的XDAIS算法執行IALG_active/deactivate函式,細胞需要調用兩個ALGRF函式來完成。
三個模組來簡化IALG接口創建算法對象,RF5使用ALGRF模組來創建,配置,刪除XDAIS算法實例。ALG模組使用CCStudio作為通用目的使用,並且不用DSP/BIOS MEM模組分配記憶體.ALGMIN是三個中的最小套用。
一般情況下,三個模組是相互包含的,但是只有一個能在應用程式中使用。ALGRF適於RF5的需要和別的RF級別,而不適合緊湊和底端的如RF1級別的系統。
ALGRF與ALG相比,有以下的優勢:
1 更小的代碼腳本(代碼量):
作為一個通用的模組,ALG支持malloc/free
運行時庫和DSP/BIOS MEM_alloc/MEM_free
動態記憶體分配方式,ALGRF只支持DSP/BIOS分配,這為設計者省了代碼空間,另外ALGRF保證沒有無用代碼的存在.只有被調用的函式才被連線到執行程式中。
2 暫存區支持:
下面的API在ALGRF中介紹的實例:
ALGRF_Handle ALGRF_createScratchSupport(IALG_Fxns *fxns, IALG_Handle parent,
IALG_Params *params, Void *scratchBuf, Uns scratchSize)
除了當IALG_SCRATCH記憶體區域(內部
數據緩衝區)被請求,該函式能根據算法請求分配記憶體。作為替代,scratchBuf和scratchSize這兩個參數表明這一緩衝區已經在套用中存在,而且可以被當前的算法重新使用.這就可以受約束的共享資源有限的記憶體區。
3 從DSP/BIOS堆標籤中做提取:
ALGRF使用DSP/BIOS 的MEM模組
動態分配記憶體。一個堆標記或記憶體段名可以傳給
MEM_alloc()來表明分配到哪一個堆.如下:
/* Configure the ALGRF module to use:
* 1st argument - memory for internal heap
* 2nd argument - memory for external heap
*/
ALGRF_setup( INTERNALHEAP, EXTERNALHEAP );
這讓我們可以指定算法的
數據分配位置。例如,如果使用EXTERNALHEAP作為兩個參數,那么算法的數據就被定位在外部
存儲器。
視頻檔案
.rf5檔案,為讀書郎 H6 H8 H10名師課堂檔案,可以用相應機型打開。