概述
- RPC(Remote Procedure call)遠程過程調用。其分為兩部分:遠程過程和過程調用。遠程過程是指每臺機器上提供的服務,過程調用就是對遠程過程調用以及數據傳輸。
- RPC用通俗的語言描述:客戶端在不知道調用細節的情況下,調用存在于遠程設備上的某個對象,就像調用本地應用程序中的對象一樣。RPC比較正式的描述:一種通過傳輸介質從遠程設備程序上請求服務,而不需要了解底層傳輸介質的協議。
- 按照我對RPC的理解,我將RPC分為三層:接口層,協議層,傳輸層。
- 接口層:客戶端實現了服務端的接口代理,而服務端的接口為具體實現。
- 協議層:客戶端根據規則實現接口參數的打包,序列化等動作。服務端根據規則將參數反序列化,并將其傳輸到服務接口。
- 傳輸層:傳輸介質:TCP/UDP,HTTP,藍牙,串口,USB等。

RPC的特點:
- RPC是協議:它是一套協議規范,需要遵循這套規范來實現。目前典型的RPC實現包括:Dubbo,eRPC,GRPC等。目前技術的發展趨勢來看,實現了RPC協議的應用工具往往都會附加其他重要功能。
- 傳輸層對其透明:RPC的客戶端調用就像調用本地應用程序中的對象,所以傳輸層使用TPC/UDB、UART、USB等協議,它本省是不需要關心的。
- 協議格式對其透明:RPC客戶端調用遠程對象需要傳遞一些參數,并且返回一個調用結果,至于被調用的對象內部是如何使用這些參數,并計算出結果的。調用方是不需要關系的。也就傳輸的協議格式的構成,調用方是不需要關心的。
- 跨語言能力:調用方實際是不需要關心被調用方是什么設備,使用什么語言。它可以是一個云服務器,也可以是一個小的單片機。至于這些設備使用的語言無需關心,被調用方只需要能夠解析調用方的數據及能返回正確的結果即可。
RPC的優缺點:
-
優點:實現模塊的分布式部署,可以實現更好的維護性,擴展性以及協同式開發。
-
缺點:①通信延遲;②地址空間隔離;③局部故障;④并發問題。
eRPC (Embedded RPC)
eRPC是什么
eRPC (Embedded RPC) is an open source Remote Procedure Call (RPC) system for multichip embedded systems and heterogeneous multicore SoCs.
eRPC(嵌入式RPC)是一種用于多芯片嵌入式系統和異構多核SoC的開源遠程過程調用(RPC)系統。
Unlike other modern RPC systems, such as the excellent Apache Thrift, eRPC distinguishes itself by being designed for tightly coupled systems, using plain C for remote functions, and having a small code size (<5kB). It is not intended for high performance distributed systems over a network.
與其他現代RPC系統(如出色的Apache Thrift)不同,eRPC的與眾不同之處在于它是為緊密耦合的系統設計的,使用純C實現遠程功能,并且代碼大小較?。?5kB)。它不適用于網絡上的高性能分布式系統。
eRPC源碼
eRPC源碼路徑
「https://github.com/EmbeddedRPC/erpc」
eRPC源碼目錄
我們關注兩個目錄erpc_c和erpcgen。其中:erpc_c是eRPC的C/C++實現。erpcgen是將IDL文件轉為C或Python源文件。
.
├──doxygen
├──erpc_c
│├──config
│├──infra
│├──port
│├──setup
│└──transports
├──erpcgen
├──erpc_python
├──erpcsniffer
├──examples
├──mk
├──README.md
├──test
└──utilities
目錄 | 說明 |
---|---|
erpc_c/config | eRPC的配置文件 |
erpc_c/infra | eRPC的核心代碼 |
erpc_c/port | eRPC的移植層,適配不同的開發環境 |
erpc_c/setup | eRPC的C接口 |
erpc_c/transports | eRPC的傳輸層,包含不同介質的驅動 |
eRPC編譯
我們需要編譯兩個東西,其中:①需要將編譯erpc_c編譯成庫,②編譯erpcgen編譯成可執行文件,用于.erpc的IDL語法生成service和client的代碼。
編譯eRPC庫
為了方便我們編譯,我們將eRPC編程庫,然后我們的應用通過鏈接方式生成可執行文件。步驟:
- 進入erpc_c目錄。
- 執行 make build=release,編譯生成release版本的eRPC庫。
- 執行 make build=release install,安裝release版本的eRPC庫。其中:默認安裝路徑是:/usr/local/lib,頭文件安裝路徑是:/usr/local/include。
編譯erpcgen
eRPC為了能過夠更加方便供開發者使用,提供了IDL的解析器erpcgen及生成規則,減少了我們編碼。erpcgen在eRPC中非常重要。步驟:
- 進入erpcgen目錄。
- 執行 make build=release,編譯生成可執行程序。
- 執行 make build=release install,安裝,其中:默認安裝路徑是:/usr/local/bin。
eRPC例子
我們寫一個簡單的例子,傳輸層采用TCP,Client發一個字符串,Server端回復一個字符串。步驟:
- 新建一個目錄:youyeetoo,并新建一個eRPC的IDL文件:youyeetoo.erpc
programyouyeetoo//指定生成的文件名
interfaceyouyeetoo{//接口定義,包好一個或者多個函數
helloYouyeetoo(binarytxInput)->binary,//函數:helloYouyeetoo,入參類型:binary,返回值類型:binary
}
- 將youyeetoo.erpc作為參數,使用剛剛編譯的erpcgen可執行文件,生成客戶端和服務端的代碼:
youyeetoo@youyeetoo:~/youyeetoo$erpcgen./youyeetoo.erpc
-
上述執行完會在當前目錄下生成4個文件:"youyeetoo_client.cpp","youyeetoo_server.cpp","youyeetoo_server.h","youyeetoo.h"。其中:
- 根據.erpc文件會生成一個接口:binary_t * helloYouyeetoo(const binary_t * txInput);。
- 客戶端無需實現這個接口的定義,它的實現已經自動生成放在youyeetoo_client.cpp。上層應用直接使用即可。
- 服務端需要沒有實現這個接口,所以需要在上層應用實現函數體的內容。
-
創建一個客戶端的上層應用文件:client_app.cpp。其中:
- 創建一個TCP傳輸層通道。
- 初始化eRPC客戶端對象。
- 通過helloYouyeetoo函數進行遠程調用,發送一條消息:"hello youyeetoo!"。
- 將遠程調用的返回值打印出來。
- 編譯命令:「g++ -Wall -I. -I/usr/local/include/erpc -L/usr/local/lib youyeetoo_client.cpp client_app.cpp -lerpc -lpthread -o client_app」
- 生成client_app可執行文件。
#include
#include
#include
#include
#include
#include"youyeetoo.h"
staticvoidfree_binary_t_struct(binary_t*data)
{
if(data->data){
erpc_free(data->data);
}
}
intmain(intargc,char*argv[])
{
erpc_transport_ttransport=erpc_transport_tcp_init("127.0.0.1",5555,false);
erpc_mbf_tmessage_buffer_factory=erpc_mbf_dynamic_init();
erpc_client_init(transport,message_buffer_factory);
char*msg="hello,youyeetoo!";
binary_tb={(uint8_t*)msg,(uint32_t)strlen(msg)};
printf("Request:%sn",msg);
binary_t*resp=helloYouyeetoo(&b);
if(resp!=NULL){
char*buf=(char*)malloc(resp->dataLength+1);
strncpy(buf,(constchar*)resp->data,resp->dataLength);
buf[resp->dataLength]='';
printf("Respond:%sn",buf);
free_binary_t_struct(resp);
free(buf);
}
erpc_transport_tcp_close();
return0;
}
- 創建一個服務端的上層應用文件:server_app.cpp。其中:
- 創建一個TCP傳輸層通道。
- 初始化eRPC服務端對象。
- 注冊服務到服務端對象中。
- 運行服務端線程。
- 當客戶端進行遠程調用時,將會進入helloYouyeetoo函數,并返回。
- 編譯命令:「g++ -Wall -I. -I/usr/local/include/erpc -L/usr/local/lib youyeetoo_server.cpp server_app.cpp -lerpc -lpthread -o server_app」
- 生成client_app可執行文件。
#include
#include
#include
#include
#include
#include
#include"youyeetoo_server.h"
binary_t*helloYouyeetoo(constbinary_t*input)
{
size_tlen=0;
char*buf;
printf("recv:%srn",input->data);
buf=(char*)malloc(strlen("hi,good!"));
memset(buf,0,strlen("hi,good!"));
strncpy(buf,"hi,good!",strlen("hi,good!"));
printf("send:hi,good!n");
len=strlen("hi,good!");
returnnewbinary_t{(uint8_t*)buf,(uint32_t)len};
}
intmain(intargc,char*argv[])
{
erpc_transport_ttransport=erpc_transport_tcp_init("127.0.0.1",5555,true);
erpc_mbf_tmessage_buffer_factory=erpc_mbf_dynamic_init();
erpc_server_tserver=erpc_server_init(transport,message_buffer_factory);
erpc_add_service_to_server(server,create_youyeetoo_service());
while(1){
erpc_server_run(server);
}
erpc_transport_tcp_close();
return0;
}
- 執行結果:

總結
- eRPC確實是一個不錯的組件,它對底層傳輸層做了抽象,使其RPC組件不局限傳統的僅在TPC/UDP條件下運行。
- eRPC的傳輸層缺少可行認證,它的傳輸時明文的,對于數據來說是不安全的,應該提供安全認證的能力。
- eRPC提供IDL(接口定義語言),是我們使用起來更加方便,我們不在需要知道eRPC的具體實現,便可以完成客戶端與服務端的調用。
歡迎關注微信公眾號『Rice嵌入式開發技術分享』
-
嵌入式
+關注
關注
5106文章
19294瀏覽量
310246
發布評論請先 登錄
相關推薦
如何手搓一個自定義的RPC 遠程過程調用框架

嵌入式組件的設計原則是什么?
如何將eRPC移植到rt-thread系統上
在eRPC上怎么添加RT-Thread系統接口
基于嵌入式TCP/IP的遠程GPRS控制終端的設計與實現
嵌入式RPC的設計與實現
嵌入式視頻監控組件的設計與實現
如何實現嵌入式系統遠程調試

嵌入式系統如何進行遠程調試
什么是遠程過程調用

評論