EmbeddedRPC / erpc

Embedded RPC
https://github.com/EmbeddedRPC/erpc/wiki
BSD 3-Clause "New" or "Revised" License
683 stars 198 forks source link

[FEATURE] Implement the "null transport" #300

Open rdpoor opened 1 year ago

rdpoor commented 1 year ago

Is your feature request related to a problem? Please describe.

As a hardware developer, I can see that eRPC is ideal for testing (where eRPC calls are routed to an external automated testing harness,) as well as for classic client/server architectures (where the user interface is physically separated from the control hardware).

But there's a third use case as well: for production units, where the user interface and control hardware run on the same microcontroller (and same address space), I'd like eRPC to use the same .erpc IDL file to generate local calls, without going through the transport mechanism at all.

Describe the solution you'd like I'd like a "null transport" which short-circuits as much of the marshalling / un-marshalling and transport communication as possible, Ideally, in this scenario, a "client-side" call to set_led(kGreen, true); would directly invoke the "server-side" implementation of set_led(LEDName whichLed, bool onOrOff).

Describe alternatives you've considered Our hardware will use a serial port for its transport layer. I've considered directly tying the TX line to the RX line, and running a local eRPC server on the target hardware, but that seems needlessly heavyweight.

Steps you didn't forgot to do I'm sure I've missed something! As a newcomer to the eRPC library, I'm not sure what terminology would be used to describe this "null transport", so it may already be requested (or even implemented!) using a different. name.

github-actions[bot] commented 1 year ago

Hi eRPC user. Thank you for your interest and welcome. We hope you will enjoy this framework well.

Hadatko commented 1 year ago

Hi @rdpoor, in current situation i would say that rpmsg,tcp or interprocessbuffer transport would be better then serial, but i don't know on which OS are you working on (LINUX?, FREERTOS?,...). From what you described, i would say that you don't want NULL Transport, but NULL serializiation of data. Transport is for exchanging data between client and server. And what about programming language C/Python?

Just summarize if i understand it correctly: You have two tasks/processes in same address space and you want exchange data between them. Advantage of current solution (serializing data) is that there will be copy of data so caller may free or reused memory after calling eRPC function. We are considering to simplify serializing data on server side to do not copy data from buffer but forward data from buffer(but this is not yet our priority). So what you can do now is choose correct transport layer.

I would say that use of RPMSG layer could be good solution for you (still depends on OS/Programing Language). You will reserve some part of memory and this memory will be used for exchanging data.

rdpoor commented 1 year ago

i would say that you don't want NULL Transport, but NULL serializiation of data

You're correct that I don't want a NULL Transport. I'd go even further, though, and say that I don't even want serialization of data -- just a straight function call from client to server. Since they're running in the same address space, I don't see a need to serialize the data: the client-side function would directly invoke the de-serialized server-side function.

I haven't seen the code that eRPC generates, so I'm not sure how to give a concrete example. The best I can say is to repeat bit from the original post: a "client-side" call to set_led(kGreen, true); would directly invoke the "server-side" implementation of set_led(LEDName whichLed, bool onOrOff). (That's probably not quite accurate:. It might be more accurate to say that the client side call to set_let(kGreen, true); triggers the server side call in its command loop. But you get the idea...)

[At this point, you might ask: why use eRPC at all? The motivation is twofold. First, there will be use cases where the server runs on a different machine (for factory testing and setup). Second, the .erpc file would guarantee that client side functions are matched with corresponding server-side functions.]

Hadatko commented 1 year ago

Hi, i still don't know programing languague, OS, one or more tasks/processes....

To me it sounds like you don't need/want client/server application for second case. In case of C you can take only generated header files (generic not client/server related) for that case and link with your implementation. So there will be no client, no server, no serialized code, no transport..... Then you can have server thread with server side generated code which will handle requests from remote system....

rdpoor commented 1 year ago

i still don't know programing languague, OS, one or more tasks/processes....

I guess that would help! Our environment is pure C with FreeRTOS. Since both sides of the RPC can initiate calls, I'm envisioning two "listener" (i.e. server) threads.

But you're correct: if the .erpc file generates client and server stubs, I can make the client functions be direct FreeRTOS messages, while the server thread simply listens for the messages. I'm imagine that eRPC can provide useful runtime functionality for this approach, but since I've not yet seen what code it generates, that's just a guess.

amgross commented 1 year ago

Hi @rdpoor

just a straight function call from client to server. Since they're running in the same address space

Do your server and client use same stack and same registers values? Compilers sometimes passing parameters to functions on stack and sometime on registers (most of the time the few first parameters on stack and the other on registers)