GithubHelp home page GithubHelp logo

embeddedrpc / erpc Goto Github PK

View Code? Open in Web Editor NEW
667.0 53.0 192.0 8.8 MB

Embedded RPC

Home Page: https://github.com/EmbeddedRPC/erpc/wiki

License: BSD 3-Clause "New" or "Revised" License

Makefile 2.66% CSS 0.04% HTML 0.02% C++ 81.84% C 2.91% Python 6.00% Shell 0.04% Lex 0.39% Yacc 1.37% PowerShell 0.08% Java 4.59% CMake 0.06%
rpc rpc-framework embedded multicore multiprocessor amp erpc

erpc's Introduction

eRPC

GitHub all releases GitHub License Version GitHub language count GitHub top language GitHub repo size GitHub code size in bytes GitHub forks GitHub Repo stars GitHub watchers GitHub commit activity (branch) GitHub commits difference between two branches/tags/commits Contributors Issues PRs Welcome

About

Open enhancement issues Closed enhancement issues Open enhancement PRs Closed enhancement PRs

Open bug issues Closed bug issues Open bug PRs Closed bug PRs

Open question issues Closed question issues

Open help-wanted issues Closed help-wanted issues

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:

  • CMSIS UART
  • NXP Kinetis SPI and DSPI
  • POSIX and Windows serial port
  • TCP/IP (mostly for testing)
  • NXP RPMsg-Lite / RPMsg TTY
  • SPIdev Linux
  • USB CDC
  • NXP Messaging Unit

eRPC is available with an unrestrictive BSD 3-clause license. See the LICENSE file for the full license text.

Releases

eRPC releases

Edge releases

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

Documentation is in the wiki section.

eRPC Infrastructure documentation

Examples

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

<MCUXpressoSDK_install_dir>/boards/<board_name>/multicore_examples for eRPC multicore examples (RPMsg_Lite or Messaging Unit transports used) or

<MCUXpressoSDK_install_dir>/boards/<board_name>/multiprocessor_examples for eRPC multiprocessor examples (UART or SPI transports used).

eRPC examples use the 'erpc_' name prefix.

Another way of getting NXP MCUXpressoSDK eRPC multicore and multiprocessor examples is using the mcux-sdk Github repo. Follow the description how to use the West tool to clone and update the mcuxsdk repo in readme Overview section. Once done the armgcc eRPC examples can be found in

mcuxsdk/examples/<board_name>/multicore_examples or in

mcuxsdk/examples/<board_name>/multiprocessor_examples folders.

You can use the evkmimxrt1170 as the board_name for instance. Similar to MCUXpressoSDK packages the eRPC examples use the 'erpc_' name prefix.

References

This section provides links to interesting erpc-based projects, articles, blogs or guides:

Directories

doc - Documentation.

doxygen - Configuration and support files for running Doxygen over the eRPC C++ infrastructure and erpcgen code.

erpc_c - Holds C/C++ infrastructure for eRPC. This is the code you will include in your application.

erpc_python - Holds Python version of the eRPC infrastructure.

erpcgen - Holds source code for erpcgen and makefiles or project files to build erpcgen on Windows, Linux, and OS X.

erpcsniffer - Holds source code for erpcsniffer application.

examples - Several example IDL files.

mk - Contains common makefiles for building eRPC components.

test - Client/server tests. These tests verify the entire communications path from client to server and back.

utilities - Holds utilities which bring additional benefit to eRPC apps developers.

Building and installing

These build instructions apply to host PCs and embedded Linux. For bare metal or RTOS embedded environments, you should copy the erpc_c directory into your application sources.

The primary build system is makefile based. It builds a static library of the eRPC C/C++ infrastructure, the erpcgen executable, and optionally the unit tests.

The makefiles are compatible with gcc or clang on Linux, OS X, and Cygwin. A Windows build of erpcgen using Visual Studio is also available in the erpcgen/VisualStudio_v14 directory. There is also an Xcode project file in the erpcgen directory, which can be used to build erpcgen for OS X.

Requirements

Windows

Linux

./install_dependencies.sh

Mandatory for case, when build for different architecture is needed

  • gcc-multilib, g++-multilib

Mac OS X

./install_dependencies.sh

Building

To build the library and erpcgen, run from the repo root directory:

make

To install the library, erpcgen, and include files, run:

make install

You may need to sudo the make install.

By default this will install into /usr/local. If you want to install elsewhere, set the PREFIX environment variable. Example for installing into /opt:

make install PREFIX=/opt

List of top level Makefile targets:

  • erpc: build the liberpc.a static library
  • erpcgen: build the erpcgen tool
  • erpcsniffer: build the sniffer tool
  • test: build the unit tests under the test directory
  • all: build all of the above
  • install: install liberpc.a, erpcgen, and include files

eRPC code is validated with respect to the C++ 11 standard.

Installing for Python

To install the Python infrastructure for eRPC see instructions in the erpc python readme.

Known issues and limitations

  • Static allocations controlled by the ERPC_ALLOCATION_POLICY config macro are not fully supported yet, i.e. not all erpc objects can be allocated statically now. It deals with the ongoing process and the full static allocations support will be added in the future.

Code providing

Repository on Github contains two main branches: main and develop. Code is developed on develop branch. Release version is created via merging develop branch into main branch.


Copyright 2014-2016 Freescale Semiconductor, Inc.

Copyright 2016-2024 NXP

erpc's People

Contributors

adithyabaglody avatar aelray avatar aglass0fmilk avatar amgross avatar burgerkingorama avatar dpfrey avatar dusancervenkanxp avatar gabbla avatar hadatko avatar hakehuang avatar hp-peti avatar jankomareknxp avatar jcdr avatar kacper-ka avatar mareknovaknxp avatar michalprincnxp avatar peterhinson avatar petrlukasnxp avatar pgu-swir avatar ramlco avatar ramseyti avatar rene-becker-setec avatar snalvc avatar thewon86 avatar thom747 avatar werner-dk avatar wesley-wu avatar willmann9527 avatar yanyang517 avatar zuzy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

erpc's Issues

HDLC for framed transport

The transfer of the frame is done primitively, for the serial device will not do !!! We need to introduce something like HDLC.

Passing struct by value

Hi,
I see on the wiki that the structure function params can be only pointers for all tyeps (in, out, inout).
Is there a way to handle passing structure by value?

eRPC server Multiple IO service

Hi Marek and Dusan

we are trying to add multiple service at the server side like below

erpc_server_init(transport, message_buffer_factory);

// Add the IO service.1
erpc_add_service_to_server( create_IO_service1() );
printf("CAD service added\r\n");
// Add the IO service. 2
erpc_add_service_to_server(create_IO_service2());

Is it possible to add ??we are getting error 9, if try to add second service..

Is 2nd service create one more channel ? or use existing one ?

Thank you very much in advance
Chandini

Failure when installing Python library

Summary

Installation of Python library in clean environment fails.

Steps to reproduce

  1. Clone repository (path: /home/user/projects/erpc)
  2. Create clean virtual environment (python -m venv /home/user/python-env)
  3. Activate virtual environment (source /home/user/python-env/bin/activate)
  4. Install Python library from path (python -m pip install /home/user/projects/erpc/erpc_python)

Current buggy behaviour

Step 3. fails with error code 1 (Python ModuleNotFoundError exception).

Expected correct behaviour

Step 3. completes successfully, module gets installed in virtual environment.

Relevant logs

Step 3. output:

Processing /home/kacper/projects/erpc/erpc_python
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-req-build-ym2kz4cl/setup.py", line 36, in <module>
        from erpc import erpc_version
      File "/tmp/pip-req-build-ym2kz4cl/erpc/__init__.py", line 39, in <module>
        from . import arbitrator
      File "/tmp/pip-req-build-ym2kz4cl/erpc/arbitrator.py", line 37, in <module>
        from .transport import Transport
      File "/tmp/pip-req-build-ym2kz4cl/erpc/transport.py", line 36, in <module>
        import serial
    ModuleNotFoundError: No module named 'serial'
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-req-build-ym2kz4cl/

Possible fixes

The issue is caused by line 36 in file setup.py:

from erpc import erpc_version

Importing any file from erpc package causes __init__.py script to execute, in consequence some other modules are pulled as well (as seen in the log above). To overcome the issue it is proposed to remove the offending line and read the version constant with a following snippet:

with open(path.join(here, 'erpc', 'erpc_version.py')) as f:
    exec(f.read())

Then in the setup invocation instead of referencing the constant via erpc_version.ERPC_VERSION (line 52) use ERPC_VERSION directly.

Annotation for a language

Hi,
I try to use @external for C only, but get an exception "Unexpected :"

the format I'm using is:
@c:external

ERPC1.5

Is that the correct usage?

Server notification message

How can I define a method, which is called from the server? I guess the "kNotificationMessage" is allocated for that reason... Maybe on the code generator side the "TOK_ASYNC" is the token?

I couldn't find any documentation?
I found about the "kInvocationMessage" with "kReplyMessage"; and about the "kOnewayMessage", but not the notification...

Simple hello-world server/client

I have looked at the erpc_transport_setup.h and wonder if there are a call (maybe in other file) where you can set an IP-addr and Port for a server that a client from another machine can use to communicate to server, similar to gRPC?

C examples

So I read: Designed to work well with C, but flexible enough to support object-oriented languages like C++.
Are there any C examples available.
I would like to use erpc to talk between to STM32 devices. Do you think this is the right lib to use for that.
I think so but I am wonder why I do not found any example for that in the WEB.

Many thanks
cheers
mathias

Bug in StaticMessageBufferFactory?

Hi,
I think there is a bug in erpc_setup_mbf_static.cpp

StaticMessageBufferFactory(void)
#if !ERPC_THREADS_IS(ERPC_THREADS_NONE)
    : m_semaphore(0)
#endif
...

The semaphore count is initialized with 0.
Now, if i make a request on the client side, the ClientManager will try to create a new Messagebuffer.

virtual MessageBuffer create()
{
    uint8_t idx = 0;
#if !ERPC_THREADS_IS(ERPC_THREADS_NONE)
    m_semaphore.get();
#endif
...

As you see, it will directly try to get the semaphore. But how is it supposed to get the semaphore, when it's initialized to 0?

bool Semaphore::get(uint32_t timeout)
{
    Mutex::Guard guard(m_mutex);
    int err;
    while (m_count == 0)
    {
        if (timeout == kWaitForever)
        {
            err = pthread_cond_wait(&m_cond, m_mutex.getPtr());
            if (err)
            {
                return false;
            }
        }
...

The code will simply wait indefinitely, because there is no other task setting a signal on the condition.
We have one task, which initializes erpc (like in the examples) and then makes the request to the server.

I think there is a bug, where StaticMessageBufferFactory() initializes m_semaphore with 0 instead of 1.

Best regards,
Lukas

Implementing threading support for CMSIS-RTOS2

I would like to implement threading support for CMSIS-RTOS2 and have ported most of the methods needed. I am a little unsure of the intended use of Thread::threadEntryPoint, and Thread::threadEntryPointStub. It looks like threadEntryPointStub is used to call the actual threadEntryPoint on the casted class passed by arg. One particularly confusion point in the freertos port is the Thread* linked list and its purpose. It appears that the pthread example doesn't have this linked list and neither does the zepher implementation. My best guess for the purpose behind the linked list is for the getCurrentThread function. Is this correct?

.template file editor

What tools you use to edit/generate the .template files (in "erpc/erpcgen/src/templates/")?

How to convert C header to eRPC IDL file

Hi All,

I would like to use eRPC for one of my project. I am looking for option, is there any way to convert C language header file to eRPC IDL file. I have a large chunk of C header file so I am finding it difficult to write the eRPC IDL file manually. Appreciate your help in this regard. Thank you for your help.

Regards,
Sudhakar

Forwarding eRPC failures to application

Hi all,
We're using eRPC for communication between 2 applications hosted on 2 different systems for a life safety critical medical product.
So, we've to handle all the potential error cases at the product level. Being said that, I performed an exercise to capture the error codes from eRPC to the application level.
I've set a custom error handler to eRPC client to forward the errors to the application.
On course of this exercise, I found a few observations below, which would need update in a few eRPC files and autogenerated (CPP) files. I request you to kindly have a look and let me know your thoughts.

  1. In autogenerated client file, error from g_client-> performRequest is not handled, rather the error from codec status (err = codec->getStatus();) is returned by error handler.
    I think the codec status has to be checked prior to even performing the request and if codec status is not successful, then the request shall not be performed.
    Also, the error from performRequest has to be handled.

  2. In erpc/infra/src/erpc_transport_arbitrator.cpp, TransportArbitrator::receive(), if there is error from codec status, it says to continue, It should rather return the error.

  3. In TransportArbitrator::prepareClientReceive(), if the PendingClientInfo is NULL, it returns kErpcStatus_Fail which is not complying the method prototype and skips the error from its caller too.

  4. In erpc/transport/src/erpc_tcp_transport.cpp, the TCP_DEBUG_ERR causes the application to exit, by ePRC itself, rather than forwarding it to application.

Request your inputs on the above observations.

Problems while building - undefined reference to

This is probably my fault and I'm sorry for asking. I'm trying to build my simple example and I can't figure out how to do this.

My code is very simple at the moment. It looks like this, arm0.cpp:

#include "myerpc_test.h"
#include "erpc_client_setup.h"

int main() {
  int32_t f_in = 3;

  /* init eRPC client environment */
  erpc_transport_t transport = erpc_transport_rpmsg_linux_init(-1,0,-1);

  /* MessageBufferFactory initialization */
  erpc_mbf_t message_buffer_factory = erpc_mbf_dynamic_init();

  /* eRPC client side initialization */
  erpc_client_init(transport, message_buffer_factory);

  /* call eRPC functions */
  my_func(f_in):
  return 0;
}

For building I'm using this two commands:
clang++ -std=c++11 -I../erpc_c/config -I../erpc_c/infra -I../erpc_c/port -I../erpc_c/setup -I../erpc_c/transports -c -o arm0.o arm0.cpp
clang++ -std=c++11 -I../erpc_c/config -I../erpc_c/infra -I../erpc_c/port -I../erpc_c/setup -I../erpc_c/transports -L../Debug/Linux/erpc/lib -lerpc -static arm0.o -o armZero

The second command issues an error. Here it is:

arm0.o: In function `main':
arm0.cpp:(.text+0x22): undefined reference to `erpc_transport_rpmsg_linux_init'
arm0.cpp:(.text+0x2b): undefined reference to `erpc_mbf_dynamic_init'
arm0.cpp:(.text+0x3c): undefined reference to `erpc_client_init'
arm0.cpp:(.text+0x44): undefined reference to `my_func'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Could you please help me?

'@group()' annotation

Hi,
When using '@group()' for an interface it produces the correct files, except the data types are duplicated in all the headers (for all groups).
The interface related functions are OK in the source files as well as in the headers. The interface IDs and function IDs are fine (per group). All other C types are duplicated in the header files for each group.
Looking at the templates it doesn't seem to handle types separation per group...

Where is erpc_transport_uart_init ?

unit_test_server.cpp has the following:
#if defined(UART)
transport = erpc_transport_uart_init(ERPC_BOARD_UART_BASEADDR, ERPC_BOARD_UART_BAUDRATE,
CLOCK_GetFreq(ERPC_BOARD_UART_CLKSRC);

In addition to this on the project page:
https://github.com/EmbeddedRPC/erpc
We have the server example using the same call as well:
void example_server(void) {
// Initialize server running over UART.
erpc_server_init(
erpc_transport_uart_init(UART0_NonBlocking_Driver);

// Add the IO service.
erpc_add_service_to_server(create_IO_service());

// Run the server.
erpc_server_run();

}

We tried to use the uart_cmsis but this still needs some work, related to timeout of the read operation and the detection of the new messages, since hasMessage(void) { return true; }
Are we missing any sources ? Was this intentional ?

erpc_rpmsg_lite_transport.cpp

please check rpmsg_lite_master_init() and rpmsg_lite_remote_init() functions in
erpc_rpmsg_lite_transport.cpp. The bare metal compilation works without last parameters in these functions.

Binary data size is lost on Python if connection breaks

With basic_codec.py the length parameter is lost if for some reason the connection breaks and the full response isn't in the buffer. The code in question is:

    def read_binary(self):
        length = self.read_uint32()
        data = self._buffer[self._cursor:self._cursor+length]
        self._cursor += length
        return data

If self._buffer doesn't have length bytes after self._cursor, data will be happily shorter. The corresponding code in basic_codec.cpp returns an error, so an analogous thing might be to raise an exception in Python.

In my case though, I want to keep whatever I can from the response as I'm down linking data from a satellite and it's a waste to throw away bytes that did come through fine. What I would want is to get back the intended length and a data array whose length I could check and then request byte ranges manually from there with another procedure call. Maybe these fields could be even carried in an exception.

I'd be happy to write the code if I get indication on what would be an acceptable solution.

Multithreading of servers when built with an RTOS

The documentation in the home/introduction makes reference of "Multithreading of servers when built with an RTOS" but I am unable to see how any of the threading support works for servers. I take the statement to mean that rpc calls may be handled by separate threads. I only see the TCPTransport having any mention of threads and it only creates one thread to run the server, and doesn't seem to spawn threads to call the rpc endpoints.

Have I misinterpreted the intended threading support?

using the application as bidirectional

I want to use function calls from M4 and A9 simultaneosly.
I am using arbitrator sources for it.
The function call from A9 works fine and M4 returns data.
But function call from M4 seems doesn't work. The error appears in A9 "Waiting MU transmit buffer empty timeout!
ugh, imx_mu_rpmsg_send() failed: -5".

After this error data function call doesn't work in another side too: "rpmsg_multiept rpmsg0: virtqueue_add_outbuf failed: -5"

M4 code

.
.

erpc_transport_t transport = erpc_transport_rpmsg_lite_rtos_remote_init(30, 1024, BOARD_SHARED_MEMORY_BASE, 0, NULL, cp);
erpc_mbf_t message_buffer_factory = erpc_mbf_rpmsg_init(transport);
erpc_transport_t arbitrator = erpc_arbitrated_client_init(transport, message_buffer_factory);
erpc_server_init(arbitrator, message_buffer_factory);
erpc_add_service_to_server(create_XXX_service());

while (true)
{
erpc_server_poll();
function1(....);
}

A9 code

.
.

erpc_transport_t transport = erpc_transport_rpmsg_linux_init(1024, 0, 30);
erpc_mbf_t message_buffer_factory = erpc_mbf_dynamic_init();
erpc_transport_t arbitrator = erpc_arbitrated_client_init(transport, message_buffer_factory);
erpc_server_init(arbitrator, message_buffer_factory);
erpc_add_service_to_server(create_XXX_service());

while (true)
{
erpc_server_poll();
function2(....);
}
Could anybody suggest anything?

Serial test fail

When I run any serial test in Linux the following error appears:

Starting ERPC server...
test_lists_server_serial_test: /erpc-master/erpc_c/infra/erpc_framed_transport.cpp:67: virtual erpc_status_t erpc::FramedTransport::receive(erpc::MessageBuffer*): Assertion `m_crcImpl && "Uninitialized Crc16 object."' failed.
Aborted

Server with TCP Transport handling multiple connections

Hi, I see that in tcp_transport.cpp, if the connection is closed by the client, TCPTransport::close() brings down the server thread by setting m_runServer = false;
Please correct me if I'm wrong but it seems to me that this means that for a subsequent client connection, the server and transport need to be reinitialized again. This also looks like it would incur the overhead of having to create a new thread. I was just wondering if you could comment on why this approach was taken?

Issue with comments

Hi,
I'm facing an issue with the comments within an enum

  1. C-style doxygen comments within an enum are not present in the generated code. No error message.
    In the .erpc file:
enum test_enum
 {
	/* 0 */
    TEST_0 = 0,
	/*! 1 */	
    TEST_1 = 1,
	/*! 2 */
    TEST_2 = 2,
	/*! 3 */
    TEST_3 = 3
	/* Bottom comment */
}

Generates:

typedef enum test_enum
{
    TEST_0 = 0,
    /*! 1 */
    TEST_1 = 1,
    /*! 2 */
    TEST_2 = 2,
    /*! 3 */
    TEST_3 = 3
} test_enum;

(First and last comments are missing)

  1. A doxygen comment following the enum members declarations causes an error:
    In the .erpc file:
enum test_enum
 {
	/* 0 */
    TEST_0 = 0,
	/*! 1 */	
    TEST_1 = 1,
	/*! 2 */
    TEST_2 = 2,
	/*! 3 */
    TEST_3 = 3
	/*! Bottom comment */
}

causes:
"error: file test_comments.erpc:14:1: syntax error, unexpected '}', expecting identifier"

Multiple transports

Hello,

I have 2 UART interfaces on-board and would like to use eRPC for each. So, I need to have 2 UART transports, 2 clients and (or) 2 servers in a single project. Is it possible to implement? From analysing the eRPC code, seems, not. But maybe there is an workaround?

Best regards,
Eugene.

[BUG] SimpleServer destructor deletes static object

Hello,

Service objects are statically allocated. But SimpleServer destructor deletes it:

SimpleServer::~SimpleServer(void)
{
    while (m_firstService != NULL)
    {
        Service *firstService = m_firstService;
        m_firstService = m_firstService->getNext();
        delete firstService;
    }
}

self.length error

Hi all,
I have small problem, when I run code generated by the command below I get error about invalid object attribute:

erpcgen/erpcgen -gpy dir/example1.erpc

Iterface file:

program example1

interface Example1
{
    func1(list<uint32> data) -> uint32
}

Generated file (client.py):


# Generated by erpcgen 1.7.1 on Wed Nov 21 17:40:42 2018.
#
# AUTOGENERATED - DO NOT EDIT
#

import erpc
from . import common, interface

# Client for Example1
class Example1Client(interface.IExample1):
    def __init__(self, manager):
        super(Example1Client, self).__init__()
        self._clientManager = manager

    def func1(self, data):
        # Build remote function invocation message.
        request = self._clientManager.create_request()
        codec = request.codec
        codec.start_write_message(erpc.codec.MessageInfo(
                type=erpc.codec.MessageType.kInvocationMessage,
                service=self.SERVICE_ID,
                request=self.FUNC1_ID,
                sequence=request.sequence))
        if data is None:
            raise ValueError("data is None")
        codec.start_write_list(self.length)
        for _i0 in data:
            codec.write_uint32(_i0)


        # Send request and process reply.
        self._clientManager.perform_request(request)
        _result = codec.read_uint32()
        return _result

Problematic line is
codec.start_write_list(self.length), Example1Client does not contain length attribute.
It seems it should be
codec.start_write_list(len(data))
instead.

Am I using IDL incorrectly or this is a a bug?
Regards

What's the best way to transfer a file, or any non fixed size of binary data, with eRPC?

Hi,

We use eRPC between an ARM/QNX and a Kinetis/FreeRTOS (connected with SPI) for some remote functions calls.
Now we would like to transfer a new FW image to the Kinetis MCU, if possible using the eRPC server running on the Kinetis. What's the best way to do that? Which type should we use in the IDL?
Notice that we may also need to transfer other files (e.g. XML config file).

Thank you for your help,
Greg

Python inout fn parameters

What's the right way of using inout params in Python.
What I do is create Reference class, but it doesn't seem to work.
The issue is:

  1. At the top of a function there is an assert checking for Reference class:
    {% for p in fn.outParameters if not p.serializedViaMember %} assert type({$p.name}) is erpc.Reference, "{$p.direction} parameter must be a Reference object" {% endfor -- outParams %}
  2. Few lines below, the parameters are serialized
    {% for p in fn.inParameters if not p.serializedViaMember %}
    which in
    {% def encodeValue(info, name, codec, indent, depth) %}
    resolves to:
    {$name}._write({$codec}){%>%}

,but the {$name} has no member _write as it is of class Reference.
It probably should be something like:
{$name}.value._write({$codec}){%>%}
in this case, but not in the case for in function parameter, only for inout.

Data transfer More than buffer size

Hi
I am setting buffer size for 1k and transferring 1k array data between A7 and M4 without any issue .
But now i am trying to transfer 2k array blob between A7 and M4 without changing rpmsg buffer size.

Is it possible by using oneway function ?

Thank you
Chandini

Problems with bidirectional communication

Hello,

I’m trying to setup a bidirectional communication between a M4 core (running FreeRTOS) and a A7 core (running Linux).

When the A7 tries to do a remote call, nothing happens. But when the remote calls are performed from the M4, it gives the error below :

Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib/python2.7/site-packages/erpc/simple_server.py", line 23, in run
    self._receive_request()
  File "/usr/lib/python2.7/site-packages/erpc/simple_server.py", line 31, in _receive_request
    msg = self.transport.receive()
  File "/usr/lib/python2.7/site-packages/erpc/arbitrator.py", line 57, in receive
    info = self._codec.start_read_message()
TypeError: unbound method start_read_message() must be called with BasicCodec instance as first argument (got nothing instead)

Could you please help me ?

Here is the M4 code in C:

void functionsM4_eRPC(...){
	...
} 

void poll_server(void *param){
    PRINTF("Polling task started\n\r");
    while(1) erpc_server_poll();
}

void app_task(void *param){
	erpc_mbf_t message_buffer_factory;
	transport = erpc_transport_rpmsg_lite_tty_rtos_remote_init(101, 1024, (void*) RPMSG_LITE_SHMEM_BASE, ERPC_TRANSPORT_RPMSG_LITE_LINK_ID, NULL, RPMSG_LITE_NS_ANNOUNCE_STRING);
	message_buffer_factory = erpc_mbf_rpmsg_tty_init(transport);
	erpc_transport_t arbitrator = erpc_arbitrated_client_init(transport, message_buffer_factory);
	erpc_server_init(arbitrator, message_buffer_factory);
	erpc_add_service_to_server(create_linux2rtos_service());

	if(xTaskCreate(poll_server, "APP_POLL", APP_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &app_task_handle) != pdPASS) {
		PRINTF("\r\nFailed to create polling task.\r\n");
		return;
	}

	while(1){
		functionsA7_eRPC(...);
	}
}

Here is the A7 code in Python :

class rtos2linuxServiceHandler(erpc_message.interface.Irtos2linux):
    def functionsA7_eRPC(self, ...):
        ...

def runServer(transport):
    server = erpc.simple_server.ServerThread(transport, erpc.basic_codec.BasicCodec)
    msgHandler = rtos2linuxServiceHandler()
    msgService = erpc_message.server.rtos2linuxService(msgHandler)
    server.add_service(msgService)
    server.start()
    print('\r\neRPC server started\r\n')


def runClient(transport):
    clientManager = erpc.client.ClientManager(transport, erpc.basic_codec.BasicCodec)
    client = erpc_message_M4server.client.linux2rtosClient(clientManager)
    while True:
        client.funcitonsM4_eRPC():

if __name__ == "__main__":
    transport = erpc.transport.SerialTransport("/dev/ttyRPMSG101", 115200)
    arbitrator = erpc.arbitrator.TransportArbitrator(transport, erpc.basic_codec.BasicCodec)
    print('Selected ttyRPMSG Transport')
    runServer(arbitrator)
    runClient(arbitrator)

Multirole device

Hi,

I'd like to use eRPC for my current project, since I have a good experience of using it in past.
I have an embedded system (Cortex M4 MCU) and use C API.
2 devices can be daisy chained and eRPC used to communicate between them. In this case one device configured as master and another one - as slave. So, depending on configuration I need to switch device between client and server roles.

This is good example of what I need (I can run it as server or as client):
https://github.com/EmbeddedRPC/erpc/blob/master/examples/matrix_multiply_tcp_python/matrix_multiply.py

But when using C API, there is an issue. Let's say we have erpcMatrixMultiply function to call on a client side. When I code server I have to define erpcMatrixMultiply in my code. But function with this name is already defined in erpc_matrix_multiply_client.cpp

Thanks,
Eugene

problem in communication using windows as a client and linux as server

Hi,

We are using erpc server on linux and erpc Client on Windows.
(Erpc client on windows is compiled using migw)

We observed that the custom functions called from the client are not executed from server.
We have added the function details on .erpc also
If there are no custom functions and try to run the test_arbitrator sample code , it works fine.
The addition of the custom code is making the system to stop at the call of function. (There is no segmentation fault)
Reported).
Attached is the .erpc and custom function in client.
this is test_arbitrator code

test_arbitrator.erpc

/*!
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright 2016 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

@crc
@output_dir("erpc_outputs/")
program test;

import "../common/unit_test_common.erpc"

@group("firstInterface")
interface FirstInterface
{
    whenReady() -> void
    oneway firstSendInt(int32 a)
    firstReceiveInt() -> int32 
    ####################################
    ourCustomFun(some datatype) -> returnvalue
    ####################################
    stopSecondSide() -> void
    getResultFromSecondSide() -> int32
    oneway quitFirstInterfaceServer()
    nestedCallTest() -> int32
    @nested
    callSecondSide() -> int32
}

@group("secondInterface")
interface SecondInterface
{
    oneway secondSendInt(int32 a)
    secondReceiveInt() -> int32
    oneway quitSecondInterfaceServer()
    oneway enableFirstSide()
    @nested
    callFirstSide() -> int32
}

Allocate struct on stack

When using structs with eRPC, they are always allocated with erpc_malloc. erpcgen generates the following code for the server:
data = (someStruct *) erpc_malloc(sizeof(someStruct));

Why is the struct allocated with malloc, instead of allocating it on the function's stack? When using arrays or primitive types, they are allocated on the stack, as expected:
uint8_t someArray[10];

Is there a way to allocate the struct on the stack, is it is done with arrays?

Background of this question is that I want to avoid malloc completely.

C++ version of erpc_c files

What version of c++ should the files in the erpc_c directory use? Some of the code requires c++11 for building erpcgen, is this also a reasonable requirement for the actual implementation?

Static allocated classes

Why are many of the internal elements of erpc statically allocated with ManuallyConstructed?

I am trying to extract the CRC functionality so that it can be provided to the clients/servers during the erpc_client/server_init() and notice that the MessageBufferFactory, ClientManager, BasicCodeFactory, and Crc16 are all statically allocated and constructed/destroyed with ManuallyConstructed.

If I were to have multiple threads doing RPC to different end points I would think it would be necessary to allow dynamic allocation of these so different threads weren't sharing the resource, especially for something like the CRC.

Inter-"version" compatability

I am interested in having inter-"version" compatibility.

It would be nice if mismatched clients and servers could talk. As it stands on the dev branch a version CRC is embedded prevents any interoperability between builds of IDL files that may have only added functionality but not removed it.

Linux RPMsg master

Hi Dusan and Marek

Hope you guys are doing good.

I have quick question regarding transport layer. In the rpmsg_lite we have 2 transport layers

  1. erpc_transport_rpmsg_lite_rtos_master_init - which uses rpmsg_lite_master_init

  2. erpc_transport_rpmsg_lite_rtos_remote_init - which uses rpmsg_lite_remote_init

Could you please tell me the difference ?

Currently As you guys know I am using freertos on M4 and linux on A7 . I call erpc_transport_rpmsg_lite_rtos_remote_init as my M4 transport which really signal the A7 that it is ready and waits for link up.

Can I use erpc_transport_rpmsg_lite_rtos_master_init so that I do not have to wait for A7 for signal ?

Could you please is there any relation between RL_BUFFER_SIZE / ERPC_DEFAULT_BUFFER_SIZE and SH_MEM_TOTAL_SIZE ?

#define SH_MEM_TOTAL_SIZE (6144)

erpc_transport_t erpc_transport_rpmsg_lite_rtos_master_init(unsigned long src_addr,
                                                            unsigned long dst_addr,
                                                            int rpmsg_link_id)
{
    s_transport.construct();
    if (s_transport->init(src_addr, dst_addr, BOARD_SHARED_MEMORY_BASE, SH_MEM_TOTAL_SIZE, rpmsg_link_id) != kErpcStatus_Success)
    {
        return NULL;
    }
    return reinterpret_cast<erpc_transport_t>(s_transport.get());
}

Build Error using make.

Any suggestion if i have missed some steps before running 'make'?

System:
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 2
Core(s) per socket: 2
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 69
Model name: Intel(R) Core(TM) i7-4510U CPU @ 2.00GHz
Stepping: 1
CPU MHz: 944.734
CPU max MHz: 3100,0000
CPU min MHz: 800,0000
BogoMIPS: 5187.74
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 4096K
NUMA node0 CPU(s): 0-3
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm epb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts

OS:
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.3 LTS
Release: 16.04
Codename: xenial

Steps:
$git clone https://github.com/DusanCervenkaNXP/erpc.git
$cd erpc/
$make

result:
~/myrepo/erpc/erpc$ make
Generating erpcgen/src/erpcgen_parser.y
make[1]: /usr/bin/bison: Command not found
Makefile:138: recipe for target '/home/myhome/myrepo/erpc/erpc/Debug/Linux/erpcgen/obj/erpcgen_parser.tab.hpp' failed
make[1]: *** [/home/myhome/myrepo/erpc/erpc/Debug/Linux/erpcgen/obj/erpcgen_parser.tab.hpp] Error 127
/home/myhome/myrepo/erpc/erpc/mk/subdirs.mk:41: recipe for target 'erpcgen' failed
make: *** [erpcgen] Error 2

TCP Example client / server code

Hi All,

I am new to eRPC. Is there any example of client & server initialization code in C language, with erpc using TCP as transport mechanism ?

Can you please point me to the code, if it is readily available. I thank you for your support.

Regards,
Sudhakar

Multiple calls between A7 and M4 using eRPC

Hi

I am trying to understand more about rpmsg here. I would like to run 2 process at the same time between M4 and A7 using eRPC

  1. Lets say Process 'A' is running between M4 and A7 using rpmsg 'A' channel . now I would like call Process 'B' from A7 and that should redirect to proper function in M4 without effecting Process 'A' communication.

  2. Can I achieve this by just creating one more endpoint in A7/M4 or should I need to create one more rpmsg channel as well ?

Thank you so much in advance
Chandini

Code generator crash

The code generator crashes when an enum member is initialized with negative value. Simple .erpc file:
`program enumtest
enum error_e
{
ERROR_NONE = 0,
ERROR_UNKNOWN = -1
}

interface etest
{
enum_test(error_e e) -> int32
}`

The 'assert(member->hasValue());' asserts...

Same function name in different interfaces

Hello,

when using same function names in different interfaces the C generated files will have duplicate function definitions.

Sample:

interface House
{
	open() -> void
	close() -> void
}

interface Car
{
	open() -> void
	close() -> void
}

Is there a way of automatically adding a prefix to the generated functions like:

void House_open(void);
void Car_open(void);

Timeout for eRPC call

Hi

Is there any way we can set timeout from client[A7] so that if M4 die's by any case A7 get notification so that we can reset the connection .

Thank you
Chandini

Callback on client side

Hello eRPC-Team,
thanks for your project, great work! I’ve a question regarding the callback feature.
Is it possible to register a callback function reside on the client to the server? Is it possible to call the callback function on the client from the server? Could you provide an IDL example for this?
Best regards, MH.

CRC annotation

What's the right use of @Crc annotation?
From what I read it should create s constant crc16 based on the idl file and use it instead the crc16 over the message content. Is that correct?
I don't see methods on the transport layer (both C and Py) to allow this.

Increasing transfer speed between cores

I am use some methodes for measuring application time and interaction time between several devices in the network. I found out that A9 core interactes quite fast for my task, but sending data to and from M4 core makes too much delay for me (2-4 ms and even more). My task is just send some 0/1 flags from A9 to M4 and back. I use functions with only 1 IN binary arrays for it. Using oneway functions makes even more delay between cores(200ms!)
I am triyng to improve my appl and increase my intercore speed.
Which functions/data types etc. should I use optimally?
Any config adjustments in rpmsg protocol or eRPC configs?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.