Quantcast LuaRPC in eLua - eLua Wiki
Locked History Attachments

LuaRPC in eLua

Controlling eLua with LuaRPC

Remote procedure calls (RPC) allow one program to communicate with another and call functions or subroutines within the second program. For example one might want to programmatically control an array of LEDs connected to an eLua embedded device from a desktop Lua state. A simple implementation might be a protocol that would allow one to send commands numeric or text-based commands that would cause code to be executed in eLua that would change the state of the LEDs. As one needs new commands to change these LEDs, one would need to upload a new Lua program to handle changing functionality. In contrast to this ad-hoc method for remote calls, LuaRPC provides a more general way to manipulate the state and execution of a remote Lua environment.

When a client is connected to a LuaRPC server, it can interact with it in the following ways:

  • assign values to new or existing variables in the server state
  • get values from variables in the server state
  • call functions to be executed on the server side using parameters of serializable types, with return values being sent back to the client
  • create local userdata helpers (aliases) which provide short-hand access to remote state

Building the Desktop Client/Server

  • first, make sure that your PC has already a build system installed (gcc, binutils, libc, headers...). You'll also need scons. The good news is that you should have it already installed, since otherwise you won't be able to build even regular eLua (see building for more in-depth instructions).

  • from the eLua base directory, issue this command:

$ scons -f rpc-lua.py

You should get a file called luarpc in the same directory which, when started, should give you a normal Lua interpreter with a built-in rpc module.

Building eLua with RPC Boot

See building for details and requirements for the building process. In order to boot into RPC mode, the RPC component will need to be enabled, and appropriate static configuration data need to be set. To build eLua to boot into RPC mode, include boot=luarpc in the build options.

LuaRPC Basics

In terms of the LED example from the beginning of this section, one could directly call pio module functions from the desktop side, experimenting with responses. If the experimentation developed into a program this could be tested both on the desktop side and on the microcontroller by making aliases to eLua modules in local Lua state. Such aliasing can be done as follows:

   1 -- open connection from Linux host serial port to eLua
   2 slave,err = rpc.connect("/dev/ttyUSB0")
   3 
   4 -- make a local helper pointing to pio module in eLua
   5 pio = slave.pio 
   6 
   7 -- define function to set direction and value of port B
   8 function set_port_val(val)
   9   pio.port.setdir( pio.OUTPUT, pio.PB )
  10   pio.port.setval( val, pio.PB )
  11 end
  12 
  13 set_port_val(23)
  14 

When we run this locally, calling and indexing helpers are translated into appropriate actions on the server. If we were done with modifications to the above function and wanted it to execute in eLua rather than using local aliases, which will result in a great deal of RPC traffic every time the function is called, we can send the function to the remote side:

   1 -- cross-compile local chunk for function and send to server
   2 slave.set_port_val = set_port_val 
   3 
   4 -- call function on server device
   5 slave.set_port_val(23)
   6 

In addition to functions, we can also copy most other Lua types from client to server using simple assignment. Due to Lua's internal workings the opposite operation of copying Lua types from server to client requires an additional metamethod:

   1 -- make table on remote server
   2 slave.remote_table = {}
   3 
   4 -- put data in table
   5 slave.remote_table.rval = 42
   6 
   7 -- get data back from server, print
   8 local_table = slave.remote_table:get()
   9 print(local_table.rval)
  10 

While these examples are trivial, they serve to illustrate a compelling development paradigm that gives one a great deal of flexibility for development and testing with an embedded target.

Serializable Lua Types

Most Lua types can be transferred between the client and server states. The following list indicates which ones can be transferred, and where there are known exceptions:

  • Serializable Types

    Exceptions and Notes

    numbers

     

    strings

     

    booleans

     

    tables

    no circular references

    functions

    no upvalues

    nil