RPC Tutorial
Tutorial for working with the RPC modules.
Introduction to RPC
What is RPC
Remote Procedure Call (RPC) allows a computer program to execute subroutines on another computer. It’s generally used in networks of computing devices. In the case of mbed, you can manipulate variables and execute subroutines on the mbed by simply calling the name of the variable or function on the host computer through a terminal or a browser.
The RPC paradigm also allows for programs written in other languages to communicate with the mbed. For instance, you can use the libraries in languages such as Python, Java, Matlab, etc. which enables a GUI based way of executing commands on the mbed.
How to Interface RPC
RPC interfaces the mbed with a computer. To interface with the mbed using a terminal, follow the terminal application setup here: https://developer.mbed.org/handbook/Terminals.
Information
Set your terminal to: transmit CR+LF, 9600 baud, 8 bit data, no parity, 1 bit stop. Also set your terminal to Local Echo.
RPC is also able to interface with popular languages based of libraries created by the mbed team. These libraries allow direct communication to the mbed through RPC without transport setup or formatting of RPC commands. Libraries are available for MATLAB, LabVIEW, Python, Java, and .NET.
RPC Command Format
Interfacing using RPC follows the following command formats: Assuming the commands are inputed to:
RPC::call(buf, outbuf);
Command | Result | Example Output |
Enter | Lists all available RPC objects | |
"/<object> RPC" | Lists all available methods that can be used on the object | |
"<Object name>/<Method name> <Arguments separated by spaces>" | Executes the method with the inputted arguments |
Troubleshooting!
Commands are only accepted with null arguments if a space is entered after the method.
"RPCobject/read " works. "RPCobject/read" does not.
Troubleshooting!
Commands that are edited in TeraTerm using backspace before completion do not work.
Here is an example of the RPC commands to turn LED4 on the mbed on. Given the mbed is running code with the line:
RpcDigitalOut myled(LED4,"mbedled");
The RPC command to turn the led on:
/mbedled/write 1
What is in the RPC Library
RPC Wrapper Classes (included in RpcClasses.h of mbed-rpc library)
Wrapper Class | Constructor | Available Functions |
---|---|---|
Digital Out | * RpcDigitalOut(PinName a0, const char *name=NULL) | #void write(int a0) #int read(void) |
Digital In | * RpcDigitalIn(PinName a0, const char *name=NULL) | #int read(void) |
Digital In Out | * RpcDigitalInOut(PinName a0, const char *name=NULL) | #int read(void) #void write(int a0) #void input(void) #void output(void) |
Analog In | * RpcAnalogIn(PinName a0, const char *name=NULL) | #float read(void) #unsigned short read_u16(void) |
Analog Out | * RpcAnalogOut(PinName a0, const char *name=NULL) | #float read(void) #void write(float a0) #void write_u16(unsigned short a0) |
PWM Out | * RpcPwmOut(PinName a0, const char *name=NULL) | #float read(void) #void write(float a0) #void period(float a0) #void period_ms(int a0) #void pulsewidth(float a0) #void pulsewidth_ms(int a0) |
SPI | * RpcSPI(PinName a0, PinName a1, PinName a2, const char *name=NULL) | #void format(int a0, int a1) #void frequency(int a0) #int write(int a0) |
Serial | * RpcSerial(PinName a0, PinName a1, const char *name=NULL) | #void baud(int a0) #int readable(void) #int writeable(void) #int putc(int a0) #int getc(void) #int puts(const char * a0) |
Timer | * RpcTimer(const char *name=NULL) : RPC(name) | #void start(void) #void stop(void) #void reset(void) #float read(void) #int read_ms(void) #int read_us(void) |
This is an example program implementing the RPC wrapper classes for Digital In, Digital Out, and PWM Out. The program runs over the mini-usb serial interface of the mbed for RPC commands from terminal. Here is the example pinout for the program. http://imgur.com/e0enKfz
Import programRPC_DigitalInDigitalOutPWMOutoverSerial
A RPC example usage program.
Here are some RPC commands for use with this example program:
RPC Command | Function |
Enter | Lists "pwmled switch mbedled RPC" |
/pwmled RPC/ | Lists "read write period period_ms pulsewidth pulsewidth_ms delete" |
/mbedled/write 1 | Turn on mbed LED4 |
/mbedled/write 0 | Turn off mbed LED4 |
/switch/read | Read in the value of p8 switch |
/pwmled/write 1 | Turns on the LED plugged into PWM port 21 |
/pwmled/read | Reads in the current value of PWM port 21 |
RPC Function
RPC Functions are objects that wrap functions that can be executed on the mbed through RPC.
RPC Variable
RPC Variables are objects that wrap basic type variables. These variables can be set and read through RPC.
RPCFunction
Overview
RPCFunction objects behave as containers for the compiler to know which commands can be executed from the Terminal. RPCFunctions take in two parameters, a function address and a string. The function passed into the object is the function that gets called and should have input and output char pointers as parameters. The string that is assigned to the object is how the function is called and represented when you use RPC. In order to decode the data inputted through RPC, specify the template type for the Arguments object. To return an output, set the Reply.putData() parameter to a string. The below example shows a simple example of how to setup a RPCFunction object. In order to run the function over RPC, call the run method on the object.
Example
void moveTo(Arguments *in, Reply *out); RPCFunction rpcMove(&moveTo, "moveTo"); void moveTo (Arguments *in, Reply *out) { bool success = true; xLoc = in->getArg<double>(); yLoc = in->getArg<double>(); // Move robot to location (xLoc, yLoc) char buffer[200]; sprintf(buffer, "Successfully moved to location (%f, %f)", xLoc, yLoc); if (success) { out->putData(buffer); } else { out->putData("Failed to move to location."); } }
Import programRPC_Function_Example
Tutorial Code for working with RPC Functions
RPC Command | Function |
Enter | Lists "moveTo RPC" |
/moveTo RPC/ | Lists "run delete" |
/moveTo/run 1 1 | Moves the robot to 1,1 and returns a success message |
RPCVariable
Overview
Similar to RPCFunction objects, RPCVariables objects allow basic datatype variables to be accessed through RPC. The two parameters to pass into the object are an address to the variable and a string that will be printed on the device interfaced to the MBED over RPC.
Example
int wheelsOn; char lcdBannerMessage; float speed; RPCVariable<int> rpcLights(&wheelsOn, "wheels"); RPCVariable<char> rpcBanner(&lcdBannerMessage, "banner"); RPCVariable<float> rpcSpeed(&speed, "speed");
Import programRPC_Variables_Example
Working with RPC Variables
RPC Command | Function |
Enter | Lists "speed banner wheels RPC" |
/speed RPC/ | Lists "read write delete" |
/speed/write 15 | Sets the variable "speed" to a value of 15 |
/speed/write 1 | Reads in the current value of "speed" to be 15 |
Object Creation over RPC
Overview
RPC allows for the creation of objects over the RPC interface. By adding the following line of code, RPC is able to create objects of the RpcDigitalOut wrapper class.
RPC::add_rpc_class<RpcDigitalOut>();
This creation of objects over RPC only works for RPC wrapper classes.
To instatiate the object over RPC:
/<RPCObjectWrapperClass>/new <mbed pin number> <object name>
Example
Import programRPC_ObjectInstantiation
A demonstration of RPC object instantiation.
Here are some RPC commands for use with this example program:
RPC Command | Function |
/DigitalOut/new LED2 myled | Creates the myled object and returns the name of the object "myled" |
/myled/write 1 | Turns on mbed LED2 |
Troubleshooting!
As with other RPC commands, the "/DigitalOut/new LED2 myled " command requires a space at the end. "/DigitalOut/new LED2 myled" does not work
Bug!
As of 2016.03.15, the mbed_rpc library only adds objects created over RPC to the RPC list (the list printed by pressing enter) after the substantiation of a second object.
RPC Serial
Overview
The Serial RPC Interface library is an addition to the mbed-RPC library that allows for serial RPC communication to occur while programs are running on the mbed. Given RPC functions, wrapper classes, or variables, a program can run on the mbed while any RPC command given through the serial port causes an interrupt. The additional library sets up RPC by registering all base classes and the serial port whenever an RPC command is sent.
Example
Simply add the following constructor to your program (along with any RPC functions, variables, or wrapper classes):
SerialRPCInterface SerialInterface(USBTX, USBRX);
Also import the larger SerialRPCInterface library:
Import library
Public Member Functions |
|
SerialRPCInterface (PinName tx, PinName rx, int baud=9600) | |
Constructor.
|
|
void | Disable (void) |
Disable the RPC.
|
|
void | Enable (void) |
Enable the RPC.
|
Information
The SerialRPCInterface library includes the new mbed_RPC library but may require an update. Update the library by importing, selecting RPCInterface > mbed-rpc then selecting update.
RPC HTTP
Overview
This HTTP Server has an RPC handler. By using the HTTP server example program on your mbed you will be able to use RPC over HTTP. The RPC commands are sent by adding them to the URL of the mbed in a browser.
Information
RPC commands over HTTP follow format: http://<url of mbed>/rpc/<Object name>/<Method name> <Arguments seperate by spaces>
The mbed will pass the URL it is assigned over the USB serial. You will need to wait to see what IP address is assigned to your mbed to properly connect with it in the client. You can view the address by starting the program and viewing print information in a serial terminal set to 9600 baud. The terminal will also allow you to view the information being recieved/sent over HTTP.
The important line of code for RPC is to add the RPC handler.
svr.addHandler<HTTPRpcRequestHandler>("/rpc");
It is also important to add the RPC classes you are using. For instance, the following line of code is important if you intend to use RPC on a DigitalOut object.
RPC::add_rpc_class<RpcDigitalOut>();
Example
Import programRPC_HTTP
RPC over HTTP example.
Software Libraries
You now have a program running on mbed which handles the RPC commands. To make a complete application your software needs to set up the transport mechanism on its end and format the commands into strings. To make this easier we've created libraries that not only give you simple access to the RPC from several programming languages but also include classes for much of the mbed API. The software libraries also include classes for the RPC Interface Library to help extend RPC into your own code.
They all use a consistent interface which is a close as possible to the interface for programming on mbed. They've been designed so that is easy to switch between transport mechanisms and so that an application can control multiple mbeds. MATLAB LabVIEW Python Java .NET
References
Please log in to post comments.