mbed RPC
What is the RPC(Remote Procedure Call)?
별도의 원격제어를 위한 코딩 없이 다른 주소공간에서 함수나 프로시저를 실행할 수 있게하는 프로세스 간 통신 기술이다. 다시말해, 원격 프로시저 호출을 이용하면 프로그래머는 함수가 실행프로그램에 로컬 위치에 있든 원격 위치에 있든 동일한 코드를 이용할 수 있다.
참고자료:wikipedia
더 간단히 말하면 아래 그림과 같이 Client에서 Server의 특정 함수를 실행하거나 특정 변수 값을 알고 싶을 때 RPC를 사용할 수 있으며, RPC Library를 통해 Client와 Server 간의 통신을 할 수 있다.
그림 출처:http://blog.facilelogin.com/2011/02/rpc-with-java.html
mbed RPC Interface Library
mbed Repository에는 RPC Interface를 위한 라이브러리가 이미 존재하며, 크게 아래와 같은 기능을 지원한다.
- RPCFunction : RPC를 통해 User가 정의한 함수를 호출 하기 위한 클래스
- RPCVariable : RPC를 통해 mbed platform 안의 변수를 read/write 하기 위한 클래스
- SerialRPCInterface : Serial을 통해 RPC를 Set up 하기 위한 클래스
RPCFunction
RPC Function object는 RPC를 통해 User가 정의한 Custom 함수를 호출 하기 위해 사용된다. 이 때 사용되는 함수는 void foo(char input, char output)과 같은 포맷으로 인자값을 받아야 한다. ( 최근 라이브러리에서는 void foo(Arguments input, Reply output) 과 같이 char 형 대신 Arguments , Reply형으로 인자값을 받아야, 컴파일 에러 없이 사용 할 수 있다. )
Arguments, Reply에 대한 Class 정의는 mbed-rpc/Arguments.h를 참고 하기 바란다.
void foo(Arguments * input, Reply * output);
RPCFunction rpc_foo(&foo, "foo");
void foo(Arguments * input, Reply * output){
int x,y;
char arg[100];
sscanf(input, "%i, %i", &x, &y);
sprintf(arg, "%i, %i", x, y);
output->putData(arg);
}
#include "mbed.h"
#include "SerialRPCInterface.h"
#include "SRF08.h"
using namespace mbed;
SerialRPCInterface RPC(USBTX, USBRX);
void ReadRange(Arguments * input, Reply * output);
RPCFunction RangeFinder(&ReadRange, "RangeFinder");
SRF08 srf08(p9, p10, 0xE0);
DigitalOut myled(LED1);
int main() {
while(1) {
myled = 1;
wait(0.2);
myled = 0;
wait(0.2);
}
}
void ReadRange(Arguments * input, Reply * output){
char arg[100];
sprintf(arg, "%f",srf08.read());
output->putData(arg);
}
- 14 : Custom 함수 등록
- 31 ~ 34 : Custom 함수 구현 부
RPC command to read the range:/RangeFinder/run
RPCVariable
RPCVariable 클래스는 mbed platform 내에 구현되어 있는 변수를 read/write하기 위해 사용된다.
float f;
int i;
char c;
RPCVariable<float> rpc_f(&f, "f");
RPCVariable<int> rpc_i(&i, "i");
RPCVariable<char> rpc_c(&c, "c");
The RPC commands to read and write the float f would be:
/f/write 0.123
/f/read
#include "mbed.h"
#include "QEI.h"
#include "Motor.h"
#include "SerialRPCInterface.h"
SerialRPCInterface SerialInterface(USBTX, USBRX);
QEI Encoder(p29 ,p30, NC, 48);
Motor Wheel(p23, p21, p22);
float MotorOutput = 50;
float Percentage = 0;
RPCVariable<float> RPCMotorOut(&MotorOutput, "MotorOutput");
RPCVariable<float> RPCPercentage(&Percentage, "Percentage");
int main(){
Encoder.reset();
float NoPulses;
while(1){
NoPulses = Encoder.getPulses();
Percentage = ((NoPulses / 48) * 100);
Wheel.speed((MotorOutput - 50) * 2 / 100);
wait(0.005);
}
}
Client 측에서 아래와 같은 포맷으로 데이터를 송신하면, MotorOutput변수와 Percetage변수를 read/write 할 수 있다.
rpc command to get the position: /percentage/read
rpc command to set the motor speed: /MotorOutput/write 0.8