ePRC框架分析与应用


eRPC是一个开源的适用于多核嵌入式系统的远程过程调用框架,它专门为紧密耦合的系统设计,使用纯C语言实现远程功能,并且代码量小(<5KB)。本文从ePRC的上手使用开始,然后对其框架原理、开销和性能进行简单分析。

快速开始eRPC由NXP创建,提供了一种简单的通过本地函数调用远程系统上的软件方法的机制。

其特点是:

一种创建client/server应用的简单方法

跨平台的erpcgen工具生成填充代码

简单的传输层设计,它甚至提供了同样是NXP开发的rpmsg-lite的IPC传输层

Server可以是阻塞或非阻塞的

快速使用:

编写IDL文件

生成填充代码

导入eRPC公共文件和接口文件

添加传输层驱动

编写应用程序

IDL文件编写创建的idl文件 idl_example.erpc

12345@output_dir("idl_example_source")@types_header("idl_example_common.h")program idl_exampleimport "idl_test.erpc"

program

可选的program语句用于指定整个输入的名称。该名称用于输出文件名,最终的文件名为program_group_xxx。

import

通过import关键字,包含另一个IDL文件。

注解

注解以”@”字符开头,参数以”()”写入。注解提供了一种方法,用以通知eRPC生成器有关代码部分的特定请求。

@output(string):表示生成文件将输出到string指定的目录

@types_header(string):表示所有的声明(如typedef和struct)将会被移至指定的头文件中。这样可以避免重复定义的错误

创建具体的接口定义文件 idl_test.erpc

1234567const int32 matrix_size = 5type Matrix = int32[maxtrix_size][matrix_size];enum enumPrintType { BUILT_IN_TYPES, STRUCT_TYPE, ARRAY_TYPE,}

内置类型

IDL

C

IDL

C

bool

bool

uint8

uint8_t

int8

int8_t

uint16

uint16_t

int16

int16_t

uint32

uint32_t

int32

int32_t

uint64

uint64_t

int64

int64_t

float

float

string

char*

double

double

数组

IDL

C

int32[10] variable

int32_t variable[10];

int32[10] [6] variable

int32_t variable[10] [6];

别名

type _aliasName = _originalType

常量

使用const关键字定义常量

枚举

IDL的enum定义会生成对应的C枚举类型,区别在于输出的C枚举类型中会增加匹配名称的typedef

12345678910111213141516struct erpc_data_t { int32_t val; byref float b;}struct foo { int32 discriminator; union(discriminator) { case BUILT_IN_TYPES: int32 num case STRUCT_TYPE: erpc_data_t data case ARRAY_TYPE: Matrix m } value}

结构体

IDL文件定义的结构体,输出文件中会额外添加typedef别名。当结构体的成员声明前使用”byref”关键字时,结构的成员将通过引用序列化。

联合体

封装型的联合体:联合体是结构体的一部分,需要结构体的其他成员作为联合体的鉴定符。

非封装的联合体:如果把联合体定义在全局空间,则需要使用@discriminator(string)指定鉴别符。

鉴定符,也就是说要指定union具体是那种类型

1234struct A { int32 discriminator; unionType data @discriminator(discriminator);}

123456789@group("test")@include("idl_example_common.h")@idl(2)interface PrintService { oneway erpc_print(in int32 index); test_binary_allDirectionLength(binary a @length(p1), in binary b, inout binary d, in uint32 p1) -> void; test_list_allDirectionLength(list a @length(p1), inout list d @length(p2), uint32 p1, uint32 p2) -> void; send_my_foo(foo f @retain) -> foo;}

@group(string)

接口可以通过group注解来进行组织,该名字会体现在输出文件中

@include(string)

string是将要包含的头文件名

@id(number)

设置interface/方法的ID号,该ID号必须唯一

Interface

接口包含一个或多个函数,这个函数在客户端使用,在服务端实现

oneway

表明该函数是单向函数

in/out/inout

指定参数的方向

@length

指定变量的长度

@retain

阻止server释放变量的空间

eRPC框架类图

程序流程图

资源消耗eRPC基础框架的代码空间约为3~4KB

FileName

Code

RO Data

RW Data

erpc_basic_codec.o

624

192

0

erpc_client_manager.o

414

40

0

erpc_crc16.o

8

0

0

erpc_message_buffer.o

158

0

0

erpc_server.o

122

0

0

erpc_simple_server.o

514

44

0

erpc_port_freertos.o

30

0

0

erpc_client_setup.o

242

24

24

erpc_server_setup.o

162

0

24

erpc_setup_mbf_dynamic.o

76

32

8

需要指出的是,eRPC的框架代码虽然体积不大,但是生成的shim code体积还是比较大的。

序列化字节流分析

Client->Serverd0 00 5e 79 00 01 01 01 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00d0 00 5e 79:h.m_messageSize = 0x00d0, h.m_crc = 0x795e00 01 01 01:header = 0x01010100,其中kBasicCodecVersion = 0x01, service = 0x01, request = 0x01, messageType = kInvocationMessage01 00 00 00:sequence = 0x00000001后续的200个字节是2个554(row*col*element_size)的matrix实参。

【湾】字简体/繁体/康熙字典【笔画】【五行】【释义】对照表
运行1286天后,熊猫直播正式关站:告别,是为了下次更好的相见