mbed RPC

2015. 10. 8. 14:402018년 이전 관심사/mbed

반응형

mbed RPC

What is the RPC(Remote Procedure Call)?

별도의 원격제어를 위한 코딩 없이 다른 주소공간에서 함수나 프로시저를 실행할 수 있게하는 프로세스 간 통신 기술이다. 다시말해, 원격 프로시저 호출을 이용하면 프로그래머는 함수가 실행프로그램에 로컬 위치에 있든 원격 위치에 있든 동일한 코드를 이용할 수 있다.

참고자료:wikipedia

더 간단히 말하면 아래 그림과 같이 Client에서 Server의 특정 함수를 실행하거나 특정 변수 값을 알고 싶을 때 RPC를 사용할 수 있으며, RPC Library를 통해 Client와 Server 간의 통신을 할 수 있다.

rpc

그림 출처: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를 참고 하기 바란다.

//Create a function of the required format
void foo(Arguments * input, Reply * output);
//Attach it to an RPC object
RPCFunction rpc_foo(&foo, "foo");

void foo(Arguments * input, Reply * output){
   int x,y;
   char arg[100];
   sscanf(input, "%i, %i", &x, &y);

   //Do something here......
   sprintf(arg, "%i, %i", x, y);
   output->putData(arg);
}
/**
* Copyright (c)2010 ARM Ltd.
* Released under the MIT License: http://mbed.org/license/mit
*/
#include "mbed.h"
#include "SerialRPCInterface.h"
#include "SRF08.h"

using namespace mbed;

//Create the interface on the USB Serial Port
SerialRPCInterface RPC(USBTX, USBRX);
void ReadRange(Arguments * input, Reply * output);
RPCFunction RangeFinder(&ReadRange, "RangeFinder");
SRF08 srf08(p9, p10, 0xE0);      // Define SDA, SCL pin and I2C address 
DigitalOut myled(LED1);

int main() {

    while(1) {


        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }
}

//As neither I2C nor the SRF08 library is avalible directly over RPC we create a Custom Function which we make RPCable by attaching to an RPCFunction
void ReadRange(Arguments * input, Reply * output){
   char arg[100];

    //Format the output of the srf08 into the output string
   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하기 위해 사용된다.

//First create the variables you wish to use
float f;
int i;
char c;
//Then attach them to an RPCVariable Object
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
/**
* Copyright (c)2010 ARM Ltd.
* Released under the MIT License: http://mbed.org/license/mit
*/

#include "mbed.h"
#include "QEI.h"
#include "Motor.h"
#include "SerialRPCInterface.h"

//Create the interface on the USB Serial Port
SerialRPCInterface SerialInterface(USBTX, USBRX);

QEI Encoder(p29 ,p30, NC, 48);
Motor Wheel(p23, p21, p22);

//Create float variables
float MotorOutput = 50;
float Percentage = 0;

//Make these variables accessible over RPC by attaching them to an RPCVariable
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);
        //RPC will be used to set the value of MotorOutput.
        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
반응형