• 沒有找到結果。

模組間資料串流

第三章 傳輸模組 IOD

3.3 模組間資料串流

q_vreceive (gpSpOsalQueues[queueHandle].psosQueue, queueFlags, timeout, pBuffer, INT_MAX, pPacketSize) //呼叫 psos 的系統函式來取得

emptyQueue 上的 packet OSAL Layer

Connection_SourceReceive( ) //處理IOD傳送端接收packet的函式

{ ……

tmosalQueueReceive (iod->emptyQueue, msgBuf, &msgSize, timeout, 0U) //將 IOD 中 emptyQueue 的指標傳入 OSAL 層接收 Queue 的函式,來取得

emptyQuene 上的 packet Default Layer

switch (flags)

{ ……

case tsaDataoutGetEmpty:

……

tmviConnection_SourceReceive (oc, &msg, &data, timeout);

//進入到 flag=tsaDataoutGetEmpty 的 case

//藉由 Macro 連結到 Connection 函式

33

tmosalQueueReceive( ),來取得空的packet。而在OSAL層接收Queue的函式中,則會將此 IOD的emptyQueue指標傳給psos的系統函式q_vreceive( ),讓系統函式辨認出目前所要取 得的是哪一個序列中的packet。

當系統函式取得packet後,便可將此packet的位址回傳給傳送端模組,而傳送端模組 則會將處理完畢的影像資料寫入此packet中。接下來,就要將這些寫有資料的packet放入 IOD的序列中傳送出去,傳送packet的途徑與取得packet的方法類似,傳送端模組同樣呼 叫了Default層的tsaDefaultDataoutFunction( )函式,但這部分傳入的旗標為“tsaDataout- PutFull",是要將存有資料的packet放入序列中,因此在寫入packet的case中,會連結至 處理傳送端輸出packet的函式Connection_SourceSend( )來執行。而在這個函式裡,則會 將傳送端模組寫好的packet傳入OSAL層上傳送Queue的函式tmosalQueueSend( ),再由 OSAL層來呼叫psos的系統函式q_vsend( ),藉由系統函式將packet傳送到fullQueue的序列 上。

接下來,位於此IOD接收端的模組會來接收傳送端模組寫入的影像資料。而接收端 模組在這部分會藉由Default層中處理輸入資料的函式tsaDefaultDatainFunction( )來取得 packet,因此接收端模組會傳入拿取full packet的旗標“tsaDatainGetFull"給Default層,

讓tsaDefaultDatainFunction( )函式執行取得full packet的case。而執行的程序與前一段敘述 在傳送端上取得空packet的流程類似,但由於這部分是要拿取攜帶資料的packet,因此必 須將IOD上的fullQueue指標傳入到OSAL層接收Queue的函式tmosalQueueReceive( )裡,

讓接下來所要執行的psos系統函式q_vreceive( )能夠從正確的fullQueue序列上取得的 packet。

而在接收端模組讀取完packet的資料後,會將packet裡的影像資料清空並放回到IOD 的序列中,因此這部分會將“tsaDatainPutEmpty"旗標傳入到Default層的tsaDefault- DatainFunction( )函式裡,讓該函式執行把空的packet放回序列的case。執行的程序與傳 送端模組將full packet傳入IOD的序列類似,但這部分在將packet傳入OSAL層傳送Queue 的函式tmosalQueueSend( )之前,會先透過一個清除packet資料的函式tmPacket_Release( ) 來清空packet上所儲存的影像資料,函式流程如圖 3.11所示。在tmPacket_Release( )函式 中,會執行packet結構上的清除packet的函式releaseFunc,由於在設定packet資料結構時 已將tsaConnection_ReleasePacket()函式設定給releaseFunc,因此在這部分會直接連結到

34

tsaConnection_ReleasePacket()函式。而接下來則會透過tmPacket_Empty( )函式來清除 packet上資料,將packet上所使用到的buffer設定為Null;再將這個清空的packet透過OSAL 層傳送Queue的函式tmosalQueueSend( ),傳入到IOD的emptyQueue序列上。

在上述操作 packet 的四個程序中:Get full、Put full、Get empty、Put empty,前三 個操作程序 Get full、Put full、Get empty 主要是根據模組傳入的 IOD 資料結構上所記錄 的 fullQueue 與 emptyQueue 序列編號,到系統儲存序列的陣列裡尋找該編號所代表的序 列,進而在該序列上做 packet 的存取動作。但是在 Put empty 這個部分,則不是根據模 組傳入的 IOD 結構所儲存的 emptyQueue 編號來選取序列,而是依據目前所要傳送的 packet 上所記錄的 emptyQueue 編號來選取。由於在 packet 的建立過程中,會將 packet 所屬的 IOD 指標設定到 packet 的結構成員 cookie 中,因此在每個 packet 上都會記錄著 自己是屬於哪一個 IOD 的 packet。而在 Put empty 的程序上,就會依據 packet 所屬的 IOD 上記錄的序列編號,來選取 packet 所要存放的 emptyQueue。

而在接收端模組將 packet 放回 emptyQueue 序列上之後,當傳送端模組需要空的 packet 來寫入資料時,會再重複前面所描述的步驟,到 emptyQueue 上拿取 packet,取 得一個空的記憶體區塊來寫入資料。而在 IOD 上的每個 packet 也都會透過上述的程序,

不斷的重複使用,以一個循環的 packet 傳輸方式,來提供給傳送端與輸出端模組。

tmPacket_Release( )

{ ……

packet->header-> releaseFunc (packet);

//將 packet 傳入到函式 tsaConnection_ReleasePacket()裡

tsaConnection_ReleasePacket ( )

{ …… //傳入 IOD 以及 packet 指標,由該函式來清空以及送出 packet sendDataPacketToEmpty (iod, packet);

sendDataPacketToEmptyt ( )

{ ……

tmPacket_Empty (packet);//清除 packet 上的資訊以及相關設定 //將 empty packet 放回 emtpyQueue 上

tmosalQueueSend (iod->emptyQueue, msgBuf, sizeof msgBuf, &noWait,0U)

圖 3.11 Release packet 的函式流程

35