eRPC是一个开源的适用于多核嵌入式系统的远程过程调用框架,它专门为紧密耦合的系统设计,使用纯C语言实现远程功能,并且代码量小(<5KB)。本文从ePRC的上手使用开始,然后对其框架原理、开销和性能进行简单分析。
快速开始
eRPC由NXP创建,提供了一种简单的通过本地函数调用远程系统上的软件方法的机制。
其特点是:
- 一种创建client/server应用的简单方法
- 跨平台的erpcgen工具生成填充代码
- 简单的传输层设计,它甚至提供了同样是NXP开发的rpmsg-lite的IPC传输层
- Server可以是阻塞或非阻塞的
快速使用:
编写IDL文件
生成填充代码
导入eRPC公共文件和接口文件
添加传输层驱动
编写应用程序
IDL文件编写
创建的idl文件 idl_example.erpc
1 | @output_dir("idl_example_source") |
program
可选的program语句用于指定整个输入的名称。该名称用于输出文件名,最终的文件名为program_group_xxx。
import
通过import关键字,包含另一个IDL文件。
注解
注解以”@”字符开头,参数以”()”写入。注解提供了一种方法,用以通知eRPC生成器有关代码部分的特定请求。
- @output(string):表示生成文件将输出到string指定的目录
- @types_header(string):表示所有的声明(如typedef和struct)将会被移至指定的头文件中。这样可以避免重复定义的错误
创建具体的接口定义文件 idl_test.erpc
1 | const int32 matrix_size = 5 |
- 内置类型
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
1 | struct erpc_data_t { |
结构体
IDL文件定义的结构体,输出文件中会额外添加typedef别名。当结构体的成员声明前使用”byref”关键字时,结构的成员将通过引用序列化。
联合体
封装型的联合体:联合体是结构体的一部分,需要结构体的其他成员作为联合体的鉴定符。
非封装的联合体:如果把联合体定义在全局空间,则需要使用@discriminator(string)指定鉴别符。
鉴定符,也就是说要指定union具体是那种类型
1 | struct A { |
1 | @group("test") |
@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->Server
d0 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 00
d0 00 5e 79:h.m_messageSize = 0x00d0, h.m_crc = 0x795e
00 01 01 01:header = 0x01010100,其中kBasicCodecVersion = 0x01, service = 0x01, request = 0x01, messageType = kInvocationMessage
01 00 00 00:sequence = 0x00000001
后续的200个字节是2个554(row*col*element_size)的matrix实参。