Saturday, May 26, 2012

Learning Lua


Over the last couple of weeks I've been learning Lua. Lua is a programming language which is designed specifically for embedding in other programs and scripting them. It's one of a number of embeddable scripting languages - and is more embeddable (possibly because it's not as comprehensive) then other scripting languages such as Python, Perl and Ruby.

It's been a pretty painless process so far.

Lua vs. Others


I posted a last October about Lua vs. Squirrel ... so why Lua over Squirrel?
  • It's known by someone else I work with (and there is a possibility of collaboration),
  • It seems like there is more information on Lua,
  • I have to write two applications, one is server-side program and the other is for an embedded device with an ARM7 chip in it. There is an embedded version of Lua called eLua that is based the Lua sources, runs on 'bare-metal' (i.e. no operating system) and has an ARM7tdmi port. Hence someone has proven it's possible. This hasn't happened - to my knowledge - yet with Squirrel, AngelScript, GameMonkey or any of the other 'very-embeddable' scripting languages and is very complex for a larger scripting language such as Python (except when the platform supports Linux).
Those, especially the last point, convince me Lua is the correct choice to try first.

The decision for games might be different - dependant on who is doing the scripting (C-syntax might be bettter for C/C++/Obj-C/Java programmers, whereas Lua syntax might be better for beginners or separate script authors - who know, say, a little BASIC - without all those braces). Other factors might come into account as well (see Note 1 below).

It should also be noted that you need enough Flash and RAM on your embedded device target. This is not a problem for my project.


Embedded Device Version Plans

The embedded device I'm using does have a small RTOS (real time operating system) on it (although it's not critical that it does, it helps in some respects like reading/writing to the flash in the existing format). Additionally we have C and C++ drivers for most of the hardware. Hence the flash and hardware drivers of eLua are not as critical.

A second point is that a couple of changes done to eLua are have similar changes incorporated into the latest Lua (5.2). Hence, at least for the moment, I've decided to go for the standard Lua build and see how it goes.

I do intend - once everything is up and running - to change the embedded device Lua to use integers for it's number type rather than doubles. Generally I agree with Lua's approach to use doubles as the single type of number. On modern desktop/laptop microprocessors, double are very fast - sometimes faster than integers. It also offers a simple model for programming.

However, ARM7TDMI chips have no floating point hardware. This means they use software routines to do floating point arithmetic - which is very slow in comparison to integers.

Sometimes floating point numbers are useful on embedded devices (e.g. working with voltage, current and resistance readings) but traditionally this has been avoided except in non-speed critical functions where absolutely necessary (or alternatively emulated with fixed-point numbers).

Because this capability is useful and newer chips are higher-density, more modern micro-controllers [2] have a floating point unit - such as most Cortex-M4 micro-controllers.

Anyhow, because I plan to do a reasonable amount of processing in Lua - and can probably avoid floating-point numbers (or at least use C-functions to perform these operations) - so using integers seems sensible as a later step. Lua is built with the ability to change it's number type, and eLua has the changes in the source to switch between the two models and hence shouldn't take much work.

The Learning So Far

I decided to write a specific part of the server-side program in Lua. This task was outstanding (other pieces are in Python and C++).

The primary reason is to get experience of Lua. Since the specific piece is likely to be only a prototype, the language doesn't actually matter; it's highly likely to get replaced with something more 'industrial' and heavyweight long term.

This piece, because it runs on standard desktop operating systems, also is a bit closer to Lua's usual target, it probably easier to learn with because it can be used immediately without worrying about the embedding on a device problem before writing a single line of code.

The main server control program provides a timer service to the Lua piece (I didn't want to have Lua call C functions for this specific case) and the Lua piece communicates via a text interface (stdin/stdout - standard-in and standard-out) with an easy to create/parse format. The input format looks like a UNIX command line (which allows easy human testing) and basic 'YAML-style' return data.

So far this has worked extremely well. Lua's tables are well suited to general purpose tasks - the only complexity was a link-list type (because usually we are inserting) that has a parallel table used to find a specific id entry for deleting or changing.

Conclusion


I'd have no problem generally recommending Lua based on what I've seen so far.

Only time will tell whether it works out on an embedded device platform - it's certainly the not dependant on Lua itself but also whether my premise is correct about development speed on scripting languages.

I've previously noted that I think programming in Python is faster than C or C++. For languages like this I believe this relates to a bunch of things:
  • partially because of the powerful but easy-to-use container types, 
  • partially because of the library, 
  • partially because it doesn't require a long compile-link cycle, 
  • partially because some investigation work can be done interactively (on fragments of the program) via a command line, 
  • partially because of ease of unit testing specific pieces 
  • ... and other factors :-)
Forth's interactivity and interactive testing, for instance, I've found useful on the Light box / LED display project.

The library leverage applies less to a language like Lua which has a much smaller library, but that wasn't a problem with the Light box project.

Time will tell whether this is correct for these two applications ...


--Rob


NOTE 1: Also Squirrel might have less garbage collector impact (according to the Squirrel author) although there is some conjecture that might not be the case with incremental gc in Lua 5. (See the Squirrel comparison page and gamedev.net discussion). My advice for this is to make proper empirical timings (i.e. profile) if this might be a problem - although perhaps there are better things to consider...

NOTE 2: A micro-controller is a microprocessor with integrated I/O suitable for easy use in an embedded device.





3 Comments:

Blogger LifeChanger said...

Saw this post today. I am attempting to get Lua to build within a TI ARM9 nonLinux environment. I really like the idea of Lua but I can't seem to figure out how to get it pulled into my environment because it is neither Windows nor Linux. What resources did you use to help you get it running? Did you use it as a C API or some other way? Thanks. Tim

2:19 pm  
Blogger RobZed said...

I put the Lua folder into my project, and did pretty much no changes except the following. I'm compling with gcc. On this board the operating system has a POSIX interface and a file system (it's not Windows or Linux, but an embedded operating system) - so that might have helped - although I thought it was meant to work with just a C library. I modified the file lua.c (which has the stand-alone command line) to redirect lua_readline since the OS doesn't read from the serial port properly. Also, I'm not building luac.c (obviously!). I call the modified main() in lua.c from the (effectively) main in the original code. After setting up the Lua state, I add my C functions via the Lua C API and off it goes. Let me know some more details of your setup (e.g. OS or no OS) and I'll try to help more.

6:47 pm  
Anonymous Anonymous said...

Rob, I am trying to build LUA with an RTOS which has the POSIX wrapper. My understanding was that it should build out of the box. Well, it went the same except that I am getting a linker error. This seems like a conflict with libc. Did you run into anything like this?

9:27 pm  

Post a Comment

<< Home

Newer›  ‹Older