eRPC (Embedded RPC) is an open source Remote Procedure Call (RPC) system for multichip embedded systems and heterogeneous multicore SoCs.
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.
eRPC does not force upon you any particular API style. It allows you to export existing C functions, without having to change their prototypes. (There are limits, of course.) And although the internal infrastructure is written in C++, most users will be able to use only the simple C setup APIs shown in the examples below.
A code generator tool called erpcgen
is included. It accepts input IDL files, having an .erpc
extension, that have definitions of your data types and remote interfaces, and generates the shim code that handles serialization and invocation. erpcgen
can generate either C/C++ or Python code.
Example .erpc
file:
// Define a data type.
enum LEDName { kRed, kGreen, kBlue }
// An interface is a logical grouping of functions.
interface IO {
// Simple function declaration with an empty reply.
set_led(LEDName whichLed, bool onOrOff) -> void
}
Client side usage:
void example_client(void) {
erpc_transport_t transport;
erpc_mbf_t message_buffer_factory;
erpc_client_t client_manager;
/* Init eRPC client infrastructure */
transport = erpc_transport_cmsis_uart_init(Driver_USART0);
message_buffer_factory = erpc_mbf_dynamic_init();
client_manager = erpc_client_init(transport, message_buffer_factory);
/* init eRPC client IO service */
initIO_client(client_manager);
// Now we can call the remote function to turn on the green LED.
set_led(kGreen, true);
/* deinit objects */
deinitIO_client();
erpc_client_deinit(client_manager);
erpc_mbf_dynamic_deinit(message_buffer_factory);
erpc_transport_tcp_deinit(transport);
}
void example_client(void) {
erpc_transport_t transport;
erpc_mbf_t message_buffer_factory;
erpc_client_t client_manager;
/* Init eRPC client infrastructure */
transport = erpc_transport_cmsis_uart_init(Driver_USART0);
message_buffer_factory = erpc_mbf_dynamic_init();
client_manager = erpc_client_init(transport, message_buffer_factory);
/* scope for client service */
{
/* init eRPC client IO service */
IO_client client(client_manager);
// Now we can call the remote function to turn on the green LED.
client.set_led(kGreen, true);
}
/* deinit objects */
erpc_client_deinit(client_manager);
erpc_mbf_dynamic_deinit(message_buffer_factory);
erpc_transport_tcp_deinit(transport);
}
Server side usage:
// Implement the remote function.
void set_led(LEDName whichLed, bool onOrOff) {
// implementation goes here
}
void example_server(void) {
erpc_transport_t transport;
erpc_mbf_t message_buffer_factory;
erpc_server_t server;
erpc_service_t service = create_IO_service();
/* Init eRPC server infrastructure */
transport = erpc_transport_cmsis_uart_init(Driver_USART0);
message_buffer_factory = erpc_mbf_dynamic_init();
server = erpc_server_init(transport, message_buffer_factory);
/* add custom service implementation to the server */
erpc_add_service_to_server(server, service);
// Run the server.
erpc_server_run();
/* deinit objects */
destroy_IO_service(service);
erpc_server_deinit(server);
erpc_mbf_dynamic_deinit(message_buffer_factory);
erpc_transport_tcp_deinit(transport);
}
// Implement the remote function.
class IO : public IO_interface
{
/* eRPC call definition */
void set_led(LEDName whichLed, bool onOrOff) override {
// implementation goes here
}
}
void example_server(void) {
erpc_transport_t transport;
erpc_mbf_t message_buffer_factory;
erpc_server_t server;
IO IOImpl;
IO_service io(&IOImpl);
/* Init eRPC server infrastructure */
transport = erpc_transport_cmsis_uart_init(Driver_USART0);
message_buffer_factory = erpc_mbf_dynamic_init();
server = erpc_server_init(transport, message_buffer_factory);
/* add custom service implementation to the server */
erpc_add_service_to_server(server, &io);
/* poll for requests */
erpc_status_t err = server.run();
/* deinit objects */
erpc_server_deinit(server);
erpc_mbf_dynamic_deinit(message_buffer_factory);
erpc_transport_tcp_deinit(transport);
}
A number of transports are supported, and new transport classes are easy to write.
Supported transports can be found in erpc/erpc_c/transport folder. E.g:
eRPC is available with an unrestrictive BSD 3-clause license. See the LICENSE file for the full license text.
Edge releases can by found on eRPC CircleCI webpage. Choose build of interest, then platform target and choose ARTIFACTS tab. Here you can find binary application from chosen build.
Documentation is in the wiki
section.
eRPC Infrastructure documentation
Example IDL is available in the examples/ folder.
Plenty of eRPC multicore and multiprocessor examples can be also found in NXP MCUXpressoSDK packages. Visit https://mcuxpresso.nxp.com to configure, build and download these packages.
To get the board list with multicore support (eRPC included) use filtering based on Middleware and search for 'multicore' string. Once the selected package with the multicore middleware is downloaded, see