• 沒有找到結果。

模組的函式功能

第二章 TSSA 模組架構

2.3 模組的函式功能

在 TSSA 架構中為每個模組定義了八個在運作上的相關函式,分別負責處理模組中 不同的程序設定,而這八個函式列舉如下:

‐ tm <Layer> <Component> GetCapbilities( )

‐ tm <Layer> <Component> Open( )

‐ tm <Layer> <Component> GetInstanceSetup( )

‐ tm <Layer> <Component> InstanceSetup( )

‐ tm <Layer> <Component> Start( )

‐ tm <Layer> <Component> Stop( )

‐ tm <Layer> <Component> Close( )

‐ tm <Layer> <Component> InstanceConfig( )

13

在每個模組中的 OL 層以及 AL 層上都會具備這些函式,因此在函式名稱上,<Layer>

代表函式所在的層面,< Component >則代表模組的名稱。而由於 Default 層是負責模組 OL 層與 AL 層的連結,因此在 Default 層中也具備了這八個函式,並以< tsaDefault >做 為函式名稱的開頭,例如 tsaDefaultGetCapabilities( )、tsaDefaultOpen( )……等。接下來 就針對這八個函式的執行內容來進行討論。

1. GetCapbilities( )

由於 Capabilities 資料結構中儲存了模組的結構特性以及標示模組的代號,因此在模 組的執行程序上,首先必須取得 Capabilities 的資料設定。而 Capabilities 結構參數的 值設定於模組的 AL 層中,因此應用層會透過 OL 層以及 Default 層的連結來向 AL 層取得 Capabilities 的設定。函式的流程如圖 2.6 所示,首先在應用層上會呼叫模組 OL 層的 GetCapabilities( )函式,並傳入應用層中存放 Capabilities 結構的指標;接下 來在 OL 層中,會呼叫 Default 層的 GetCapabilities( )函式,將該模組 AL 層的函式指 標位址與存放 Capabilities 的指標一併傳入到 Default 層中,讓 Default 層取得 AL 層 運作的函式位址;最後,就由 Default 層連結到該模組 AL 層的 GetCapabilties( )函式,

並在該函式中,將存放 Capabilities 資料結構的位址設定到由上層傳入用來取得 Capabilities 設定的變數中,完成 Capabilities 的設定。

圖 2.6 設定 Capabilities 的函式流程

tmalComponentGetCapabilities(ptmalComponentCapabilities_t * cap)

{ //在 AL 層這部分則會將存放 Capabilities 結構的位址設定給傳入的指標。

*cap = &lcap;

……

AL Layer

tsaviAl_GetCapabilities (tmalFunc, &cap)

//在 Default 層中則會藉由巨集連結到模組 AL 層的 GetCapabilities 函式。

Default Layer

//在 OL 層中會呼叫 Default 層的 GetCapabilities 函式,並將模組 AL 層的 函式位址以及存放 Capabilities 結構的指標一併傳入到 Default 層中。

tsaDefaultGetCapabilities(&add_done, &Component_TmalFunc, (UInt32*) ppCap,);

OL Layer

//在應用層呼叫模組 OL 層 GetCapabilities 的介面函式,並傳入存放 Capabilities 的指標。

tmolComponentGetCapabilities(&ivp->ComponentCap);

Application Layer

//模組 AL 層的函式指標位址

14

2. Open( )

Open( )函式主要的功能是分配記憶體空間給 Instance 資料結構。由於接下來所要設 定的部分為模組的 Instance 結構,因此在各層的 Open( )函式裡會先分配記憶體空間 給 Instance 以及 Instance 的 Setup 資料結構,提供給模組一個新的設定環境,並且讓 模組在資料結構的設定上能夠避免被其它的模組修改到,也是對模組在設定上多一 層的保護。

圖 2.7 為 AL 層 Open( )函式的執行內容,由於各層 Open( )函式執行的內容類似,這 部分便以 AL 層為例。在 Open( )函式中,主要是藉由 TSSA 中所定義分配記憶體的 函式 tmDefault_Calloc( ),依據 Instance 以及 InstanceSetup 資料結構的大小來分配記 憶給模組的變數。其中在 Default 層的 Open( )函式裡,在做好記憶體區塊分配後,

還會針對 Instance 結構中部分的結構成員做初始值的設定。

3. GetInstanceSetup( )

GetInstanceSetup( )函式是去取得模組的 Instance Setup 結構,提供給應用層來設定。

而在取得模組 Instance Setup 結構的流程上,與前面所描述 GetCapabilities( )函式在 取得 Capabilities 結構的方法類似,都是先藉由 OL 層的函式將待設定的結構指標以 及 AL 層的函式位址傳入 Default 層中,再由 Default 層連結到 AL 層的函式上,取 得資料結構的位址。而應用層在獲得模組的 Instance Setup 結構時,便可針對模組在 運作上的需求來設定結構參數,而除了模組本身所具備特定的參數須要設定外,在 每個模組中都會設定到的結構成員包括了 errorFunc、progressFunc、completeFunc 等模組在運作上用來標示以及回報狀態的函式,模組的執行緒在作業系統上的優先 順訊 priority,模組輸入端所連接的傳輸模組 inputDescriptors,模組輸出端所連接的 傳輸模組 outputDescriptors……等。

圖 2.7 Open()函式的執行內容

tmalComponentOpen()

{ //依照 Instanc 結構的 Size,分配記憶體空間給 Instance 變數 ivp = tmDefault_Calloc (sizeof (ComponentInstance_t);

//依照 InstancSetup 結構的 Size,分配記憶體空間給 Instance Setup 變數 ivp->pSetup = tmDefault_Calloc (sizeof (ComponentInstanceSetup_t));

……

15

4. InstanceSetup( )

而當應用層設定完上述的 Instance Setup 結構後,便透過 InstanceSetup( )函式將設定 好的 Setup 結構傳入下層,而在 Default 層以及 AL 層中則會將這些 Setup 結構的參 模組的指令後,首先 Default 層會呼叫 OSAL 層執行緒的建立函式 tmosalTaskCreate( ),

判斷該模組是否具備建立好的執行緒,若模組的執行緒尚未建立,則會藉由 psos 的

tsaviAl_Start (divp);

//將模組的輸入輸出端設定為“停止"的狀態 stopPins (divp);

…… } tmosalTaskCreate()

{ //由 OSAL 層呼叫 psos 的系統函式 t_start,並將 Default 層的 task 執行函 數傳入,交由 psos 系統來呼叫。

t_start (psosTask, T_PREEMPT | T_TSLICE , pStartFunction ,tArgs);

……

tsaDefaultStart( )

{ //呼叫 OSAL 層的 task 建立函式,並傳入 Default 層中管理模組 task 運作 的函式 defaultTask,以及模組上與 task 相關的設定參數。

tmosalTaskCreate ( defaultTask, divp, divp->priority, divp->stackSize, &tid, divp->taskName, divp->taskFlags | tmosalTaskStarted);

……

16

而在 OSAL 層呼叫 psos 系統函式 t_start( )執行的同時,會傳入一個 Default 層上所 定義的 root function 稱為 defaultTask( ),在這個函式裡將模組運作上所會執行的內 容寫在一個迴圈裡,包含了一開始要先將模組的輸入端與輸出端 pin 腳設定為啟動 的狀態,接著再呼叫該模組 AL 層上的執行運作函式,進入到模組影像處理的程式 部分。而在啟動模組之後,必須讓模組的函式保持在運作的狀態,才能不斷處裡輸 入的串流資料。因此在每個模組 AL 層 Start 函式的執行程序上,會定義一個無限迴 圈,將模組從拿取影像資料、運算處理、到儲存處理好的影像資料的流程,都寫在 這個迴圈裡,若模組一直保持在啟動的執行狀態,就會不斷的在這個迴圈裡執行運 算,直到收到停止的指令才會停止運算並跳出迴圈,圖 2.9 為 ProcessInPlace 模組 AL 層 Start( )函式的執行內容。當應用程式啟動所有的模組之後,系統上會取得每 一個模組的執行緒,以及執行緒上所要運作的函式,而每個執行緒這時候都會保持 在啟動的狀態,由系統依照執行緒的優先權來分配運作的先後順序。

6. InstanceConfig( )

當所有模組皆開始運作後,某些應用程式或許會提供一些變更影像畫面的功能給使 用者來選擇,例如暫停影像畫面、取消影像 deinterlaced 的功能、或停止程式的運 作……等選項,而在使用者下達指令後,應用層就會透過 OL 層的 InstanceConfig( ) 函式將變更的部分傳入下層,並於 Default 層以及 AL 層的 InstanceConfig( )函式中去 更改 Instance 資料結構的設定。

7. Stop( )

暫停模組中所有處理的程序,並變更標明模組狀態的旗標設定,將原本為“Running"

或者“Requesting"的狀態更改為“Stop"以及“Stop_Requesting"。而模組會在暫 停的狀態上停留,直到模組的 Start( )函式再度被呼叫時,才會恢復模組運作。

tmalProcessInPlaceStart(Int instance)

{…… //進入模組的運算迴圈,讓模組能夠不斷的執行運算

while (ivp->componentState == tsaCompStateRunning) { //呼叫 datain function 讀取輸入影像資料

tsaviStreaming_DataIn ( );

//呼叫模組的影像處理函式來運算資料 modifyPacket (ivp->handle, ivp->packet);

//呼叫 dataout function 輸出模組處理完的影像資料 tsaviStreaming_DataOut ( );

…… }

圖 2.9 模組 AL 層上 Start 函式的內容

17

8. Close( )

結束整個模組的運作,並藉由 TSSA 中所定義釋放記憶體的函式 tmDefault_Free( ),

將前面在 Open( )以及 Start( )函式中所分配的記憶體空間釋放掉。

一個標準的 TSSA 軟體模組架構,就是藉由 Capabilities 以及 Instance 這兩大資料結 構在上述的這些函式中,搭配模組的分層機制來設定以及運作而構成的。

struct exSvipInstance // Global Structure { ……

/*--- tmVdecAna ---*/ //A/D 晶片的操作模組

Int hVdecAna;

tmbslVdecAnaVideoInSources_t VISources;

……

/*--- tmVcapSvip ---*/ //影像擷取模組

Int hVcapSvipUnit;

Int hVcapSvipStream[MAX_NUMBER_STREAMS];

ptmolVcapSvipUnit_Capabilities_t pVcapSvipUnitCap;

ptmolVcapSvipUnit_InstanceSetup_t pVcapSvipUnitSetup;

ptmolVcapSvipStream_Capabilities_t pVcapSvipStreamCap[MAX_NUMBER_STREAMS];

ptmolVcapSvipStream_InstanceSetup_t pVcapSvipStreamSetup[MAX_NUMBER_STREAMS];

/*--- tmVideoProc ---*/ //影像處理模組

Int videoProc;

ptmolProcessInPlaceCapabilities_t videoProcCap;

ptmolProcessInPlaceInstanceSetup_t videoProcSetup;

…… ptsaInOutDescriptor_t vcapSvipOd;

ptsaInOutDescriptor_t videoProcOd;

……