A test of creating custom classes for control over RPC. Creates an LED class with member functions callable over serial.

Dependencies:   mbed

Committer:
JimmyTheHack
Date:
Wed Sep 29 01:20:59 2010 +0000
Revision:
1:ddf1739fcbb8
Parent:
0:b0ab03e03fdc
Child:
2:fe4c1d5a97fa
experimenting with adding auto-documentation.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JimmyTheHack 0:b0ab03e03fdc 1 /* Test of custom RPC classes. An introduction to the RPC environment.
JimmyTheHack 0:b0ab03e03fdc 2
JimmyTheHack 0:b0ab03e03fdc 3 Based heavily off of code from iva2k
JimmyTheHack 0:b0ab03e03fdc 4 http://mbed.org/users/iva2k/programs/pub_iva2k_ethrpc/gpdz3x
JimmyTheHack 0:b0ab03e03fdc 5 in turn based off of servo library
JimmyTheHack 0:b0ab03e03fdc 6 http://mbed.org/projects/cookbook/svn/Servo/trunk/Servo.h
JimmyTheHack 0:b0ab03e03fdc 7 http://mbed.org/projects/cookbook/svn/Servo/trunk/Servo.cpp
JimmyTheHack 0:b0ab03e03fdc 8
JimmyTheHack 0:b0ab03e03fdc 9 This code features heavy copy-pasting, so I take little credit for the content. My goal was not to create original code, but to put together a basic introduction
JimmyTheHack 0:b0ab03e03fdc 10 to help myself and others understand how to implement custom classes in RPC.
JimmyTheHack 0:b0ab03e03fdc 11
JimmyTheHack 0:b0ab03e03fdc 12 This code creates a custom RPC class called LED. The LED class contains two member functions, toggle and blink.
JimmyTheHack 0:b0ab03e03fdc 13 Normally when compiling a program the original names of the objects are lost. In order to be able to call these functions by name after compiling, we must save the name in a string.
JimmyTheHack 0:b0ab03e03fdc 14 The name of our object and necessary arguments for the initialization function are saved using the get_rpc_class() function. The name of each member function and their arguments must also be
JimmyTheHack 0:b0ab03e03fdc 15 registered using get_rpc_methods().
JimmyTheHack 0:b0ab03e03fdc 16
JimmyTheHack 0:b0ab03e03fdc 17
JimmyTheHack 0:b0ab03e03fdc 18
JimmyTheHack 0:b0ab03e03fdc 19
JimmyTheHack 0:b0ab03e03fdc 20 From: http://mbed.org/cookbook/Interfacing-Using-RPC
JimmyTheHack 0:b0ab03e03fdc 21
JimmyTheHack 0:b0ab03e03fdc 22 RPC Commands are in the format: "/<Object name>/<Method name> <Arguments separated by spaces>
JimmyTheHack 0:b0ab03e03fdc 23 If you send just "/" mbed will return a list of objects that can be used
JimmyTheHack 0:b0ab03e03fdc 24 If you send "/<object name>/" then mbed will return the methods which can be used on this object.
JimmyTheHack 0:b0ab03e03fdc 25
JimmyTheHack 0:b0ab03e03fdc 26 I haven't finished digging through this yet, but I think most of the documentation for the RPC functions is in the files:
JimmyTheHack 0:b0ab03e03fdc 27 http://mbed.org/projects/libraries/svn/mbed/trunk/Base.h
JimmyTheHack 0:b0ab03e03fdc 28 http://mbed.org/projects/libraries/svn/mbed/trunk/rpc.h
JimmyTheHack 0:b0ab03e03fdc 29
JimmyTheHack 0:b0ab03e03fdc 30
JimmyTheHack 0:b0ab03e03fdc 31 */
JimmyTheHack 0:b0ab03e03fdc 32
JimmyTheHack 0:b0ab03e03fdc 33 #include "mbed.h"
JimmyTheHack 0:b0ab03e03fdc 34 #include "rpc.h"
JimmyTheHack 0:b0ab03e03fdc 35
JimmyTheHack 0:b0ab03e03fdc 36
JimmyTheHack 0:b0ab03e03fdc 37 /*LED class definition*/
JimmyTheHack 0:b0ab03e03fdc 38
JimmyTheHack 0:b0ab03e03fdc 39 class LED :public Base { //make sure to define the class with inheritance from the Base RPC class.
JimmyTheHack 0:b0ab03e03fdc 40 public:
JimmyTheHack 0:b0ab03e03fdc 41 //constructor//
JimmyTheHack 0:b0ab03e03fdc 42 LED(PinName mypin, const char *name=NULL);
JimmyTheHack 0:b0ab03e03fdc 43 //LED class functions//
JimmyTheHack 0:b0ab03e03fdc 44 void blink(int n);
JimmyTheHack 0:b0ab03e03fdc 45 int toggle();
JimmyTheHack 0:b0ab03e03fdc 46 DigitalOut LEDpin;
JimmyTheHack 0:b0ab03e03fdc 47 int state;
JimmyTheHack 0:b0ab03e03fdc 48
JimmyTheHack 0:b0ab03e03fdc 49 #ifdef MBED_RPC //this code will not compile unless we have included the rpc.h file. So this class can also be used without RPC.
JimmyTheHack 0:b0ab03e03fdc 50 virtual const struct rpc_method *get_rpc_methods();
JimmyTheHack 0:b0ab03e03fdc 51 static struct rpc_class *get_rpc_class();
JimmyTheHack 0:b0ab03e03fdc 52 #endif // MBED_RPC
JimmyTheHack 0:b0ab03e03fdc 53 };
JimmyTheHack 0:b0ab03e03fdc 54
JimmyTheHack 0:b0ab03e03fdc 55
JimmyTheHack 1:ddf1739fcbb8 56 /**Initialization Function**/
JimmyTheHack 1:ddf1739fcbb8 57 LED::LED(PinName mypin, const char *name) : Base(name), LEDpin(mypin) { //initialize pin
JimmyTheHack 0:b0ab03e03fdc 58 LEDpin.write(0);
JimmyTheHack 0:b0ab03e03fdc 59 state=false; //set LED to off
JimmyTheHack 0:b0ab03e03fdc 60 }
JimmyTheHack 1:ddf1739fcbb8 61 /**switch the state of the LED**/
JimmyTheHack 1:ddf1739fcbb8 62 int LED::toggle() {
JimmyTheHack 0:b0ab03e03fdc 63 if (state==0) {
JimmyTheHack 0:b0ab03e03fdc 64 state=1;
JimmyTheHack 0:b0ab03e03fdc 65 } else {
JimmyTheHack 0:b0ab03e03fdc 66 state=0;
JimmyTheHack 0:b0ab03e03fdc 67 }
JimmyTheHack 0:b0ab03e03fdc 68 LEDpin=state;
JimmyTheHack 0:b0ab03e03fdc 69 return state; //print the current state of the LED
JimmyTheHack 0:b0ab03e03fdc 70 }
JimmyTheHack 0:b0ab03e03fdc 71
JimmyTheHack 1:ddf1739fcbb8 72 /**blink the LED n times**/
JimmyTheHack 1:ddf1739fcbb8 73 void LED::blink(int n=1) {
JimmyTheHack 0:b0ab03e03fdc 74 do { //blink at least once
JimmyTheHack 0:b0ab03e03fdc 75 toggle(); //toggle LED state
JimmyTheHack 0:b0ab03e03fdc 76 wait(.2);
JimmyTheHack 0:b0ab03e03fdc 77 toggle(); //return LED to original state
JimmyTheHack 0:b0ab03e03fdc 78 wait(.2);
JimmyTheHack 0:b0ab03e03fdc 79 n--;
JimmyTheHack 0:b0ab03e03fdc 80 } while (n>=1);
JimmyTheHack 0:b0ab03e03fdc 81 }
JimmyTheHack 0:b0ab03e03fdc 82
JimmyTheHack 0:b0ab03e03fdc 83
JimmyTheHack 0:b0ab03e03fdc 84 #ifdef MBED_RPC
JimmyTheHack 1:ddf1739fcbb8 85 /**Create a list of the available methods which can be called for this class**/
JimmyTheHack 1:ddf1739fcbb8 86 const rpc_method *LED::get_rpc_methods() {
JimmyTheHack 0:b0ab03e03fdc 87 static const rpc_method rpc_methods[] = {
JimmyTheHack 0:b0ab03e03fdc 88 { "toggle", rpc_method_caller<int, LED, &LED::toggle> }, //first specify the name string. The arguments to rpc_method_caller appear to be <outputs, RPC class, inputs, reference to function>.
JimmyTheHack 0:b0ab03e03fdc 89 //In this case, we have one output and no inputs so they are skipped. We must only specify the class of the object the method belongs to and the address of the method.
JimmyTheHack 0:b0ab03e03fdc 90
JimmyTheHack 0:b0ab03e03fdc 91 { "blink", rpc_method_caller<LED, int, &LED::blink> }, //this method has no outputs so they are skipped, but we must specify the input to be of type int.
JimmyTheHack 0:b0ab03e03fdc 92 RPC_METHOD_SUPER(Base),
JimmyTheHack 0:b0ab03e03fdc 93 };
JimmyTheHack 0:b0ab03e03fdc 94 return rpc_methods;
JimmyTheHack 0:b0ab03e03fdc 95 }
JimmyTheHack 1:ddf1739fcbb8 96 /**Register the class itself as an RPC-callable class**/
JimmyTheHack 1:ddf1739fcbb8 97 rpc_class *LED::get_rpc_class() {
JimmyTheHack 0:b0ab03e03fdc 98 static const rpc_function funcs[] = {
JimmyTheHack 0:b0ab03e03fdc 99 { "new", rpc_function_caller<const char*, PinName, const char*, &Base::construct<LED,PinName,const char*> > }, //still don't fully understand the arguments in this line. I suppose the first argument may just be an output echo of the name.
JimmyTheHack 0:b0ab03e03fdc 100 RPC_METHOD_END
JimmyTheHack 0:b0ab03e03fdc 101 };
JimmyTheHack 0:b0ab03e03fdc 102 static rpc_class c = { "LED", funcs, NULL };
JimmyTheHack 0:b0ab03e03fdc 103 return &c;
JimmyTheHack 0:b0ab03e03fdc 104 }
JimmyTheHack 0:b0ab03e03fdc 105 #endif // MBED_RPC
JimmyTheHack 0:b0ab03e03fdc 106
JimmyTheHack 0:b0ab03e03fdc 107
JimmyTheHack 0:b0ab03e03fdc 108 /* end LED class definition */
JimmyTheHack 0:b0ab03e03fdc 109
JimmyTheHack 0:b0ab03e03fdc 110
JimmyTheHack 0:b0ab03e03fdc 111
JimmyTheHack 0:b0ab03e03fdc 112
JimmyTheHack 0:b0ab03e03fdc 113
JimmyTheHack 0:b0ab03e03fdc 114 Serial pc(USBTX, USBRX); //set up serial communication
JimmyTheHack 1:ddf1739fcbb8 115 /**Wait for RPC commands and then call the interpreter**/
JimmyTheHack 1:ddf1739fcbb8 116 int main() {
JimmyTheHack 0:b0ab03e03fdc 117
JimmyTheHack 0:b0ab03e03fdc 118 // specify which classes we would like to be able to call over LED
JimmyTheHack 0:b0ab03e03fdc 119 Base::add_rpc_class<Timer>(); //a class included in the core mbed RPC library
JimmyTheHack 0:b0ab03e03fdc 120 Base::add_rpc_class<LED>(); //my own custom LED class
JimmyTheHack 0:b0ab03e03fdc 121
JimmyTheHack 0:b0ab03e03fdc 122 // receive commands, and send back the responses
JimmyTheHack 0:b0ab03e03fdc 123 char buf[256], outbuf[256];
JimmyTheHack 0:b0ab03e03fdc 124 while (1) {
JimmyTheHack 0:b0ab03e03fdc 125 pc.gets(buf, 256); //grab serial commands
JimmyTheHack 0:b0ab03e03fdc 126 rpc(buf, outbuf); //interpret the RPC commands
JimmyTheHack 0:b0ab03e03fdc 127 //this function only requires an input string and output string, so we can obtain RPC commands via a different interface than serial if desired.
JimmyTheHack 0:b0ab03e03fdc 128 pc.printf("%s\n", outbuf); //print back over serial
JimmyTheHack 0:b0ab03e03fdc 129 }
JimmyTheHack 0:b0ab03e03fdc 130 }
JimmyTheHack 0:b0ab03e03fdc 131
JimmyTheHack 0:b0ab03e03fdc 132
JimmyTheHack 0:b0ab03e03fdc 133