Dual serial transport
概述
eRPC 的預設的設計模型是簡單的主從模式,也就是裝置A上運作服務,另一個裝置B主動發起請求調用A的服務,但在實際的應用中,我們需要雙向的請求,也就是說裝置A,裝置B互為主從,兩台裝置上都會運作服務供對方調用。在這種模式下,原有的串行通訊傳輸(SerialTransport)實作就不能滿足要求,因為裝置接收到的資料無法知道是給server的請求(Requst),還是給client的響應(Response)。
如果要實作上述的雙向請求并不複雜,隻要修改串行通訊傳輸(SerialTransport)的實作,在發送資料時,多發送一個資料類型的标志,這樣接收方收到資料時先判斷這個标志,如果是給server端的Request,後續的資料就讓server接收,如果是給client端的Response,就讓client接收。
由此就可以實作一個支援雙向請求的串行資料傳輸(dual serial transport).通過隻修改傳輸層,就可以讓eRPC架構實作client/server混合運作。
實作邏輯
如下圖是Dual serial transport的實作模型。
因為client/server混合運作時,client和server都會發送資料也都會接收資料,是以關鍵的問題就是通過資料類型标志(segType),讓接收到的資料被正确的接收端(client或server)接收。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICMyYTMvw1dvwlMvwlM3VWaWV2Zh1Wa-cmbw5CN2onY4Fnd3QTYvwFO0YDO0ETMtUGall3LcVmdhNXLwRHdo9CXt92YucWbpRWdvx2Yx5yazF2Lc9CX6MHc0RHaiojIsJye.png)
資料發送
為了防止client/server的資料發送能同時正常執行,設計了一個發送資料互斥鎖(send_lock),使用互斥鎖将client和server發送資料的操作嚴格區分開。
在發送正式資料之前先發送一個資料類型标志(segType)标志
資料接收
為了確定client/server能正确收到自己應該接收的資料,設計了三個資料接收信号量:
變量名 | 說明 | 備注 |
---|---|---|
server_semaphore | server 端資料接收信号量 | 初始狀态下server端接收請求資料時被此信号量阻塞,等待被開關線程收喚醒 |
client_semaphore | client 端資料接收信号量 | 初始狀态下cliennt端接收響應資料時被此信号量阻塞,等待被開關線程收喚醒 |
switch_semaphore | 資料開關線程 資料接收信号量 | 開關線程負責讀取資料類型标志(segType),并根據标志喚醒server或client接收資料 |
當資料開關線程喚醒server或client接收資料後,自己就進入阻塞狀态,等待server或client端的喚醒
當server或client被被開關線程收喚醒接收完資料後,會設定switch_semaphore信号量喚醒開關線程準備接收下一個資料類型标志(segType)
上述三個資料接收信号量和發送資料互斥鎖定義在
erpc_setup_dual_serial.cpp
資料開關線程的實作在:
DualSerialTransport::serverThread
在原有的SerialTransport的資料發送函數基礎上,DualSerialTransport 做了簡單修改,增加了信号量等待和發送資料類型标志(segType)動作,參見:
DualSerialTransport::underlyingSend
在原有的SerialTransport的資料接收函數基礎上,DualSerialTransport 增加了信号量等待動作,參見:
DualSerialTransport::underlyingReceive
測試驗證
關于雙向資料傳輸完整的測試代碼參見
https://gitee.com/l0km/facelog/blob/dev3/facelog-client-cpp/dependencies/erpc/test/erpc_dual_test.cpp